make PLF fuel savable
[sw/motorsim] / src / com / billkuker / rocketry / motorsim / io / MotorIO.java
1 package com.billkuker.rocketry.motorsim.io;\r
2 \r
3 import java.io.IOException;\r
4 import java.io.InputStream;\r
5 import java.io.ObjectInputStream;\r
6 import java.io.ObjectOutputStream;\r
7 import java.io.OutputStream;\r
8 import java.net.URI;\r
9 import java.net.URISyntaxException;\r
10 \r
11 import org.jscience.physics.amount.Amount;\r
12 \r
13 import com.billkuker.rocketry.motorsim.Fuel;\r
14 import com.billkuker.rocketry.motorsim.Motor;\r
15 import com.billkuker.rocketry.motorsim.fuel.FuelResolver;\r
16 import com.billkuker.rocketry.motorsim.fuel.FuelResolver.FuelNotFound;\r
17 import com.thoughtworks.xstream.XStream;\r
18 import com.thoughtworks.xstream.converters.ConversionException;\r
19 import com.thoughtworks.xstream.converters.Converter;\r
20 import com.thoughtworks.xstream.converters.MarshallingContext;\r
21 import com.thoughtworks.xstream.converters.UnmarshallingContext;\r
22 import com.thoughtworks.xstream.converters.javabean.JavaBeanConverter;\r
23 import com.thoughtworks.xstream.io.HierarchicalStreamReader;\r
24 import com.thoughtworks.xstream.io.HierarchicalStreamWriter;\r
25 \r
26 public class MotorIO {\r
27         \r
28         static class FuelConverter implements Converter{\r
29 \r
30                 @Override\r
31                 public boolean canConvert(Class c) {\r
32                         return Fuel.class.isAssignableFrom(c);\r
33                 }\r
34 \r
35                 @Override\r
36                 public void marshal(Object o, HierarchicalStreamWriter w,\r
37                                 MarshallingContext ctx) {\r
38                         /*Fuel f = (Fuel)o;\r
39                         w.setValue(f.getURI().toString());*/\r
40                         ctx.convertAnother(((Fuel)o).getURI());\r
41                 }\r
42 \r
43                 @Override\r
44                 public Object unmarshal(HierarchicalStreamReader r,\r
45                                 UnmarshallingContext ctx) {\r
46                         Object o = ctx.currentObject();\r
47                         Object uri = null;\r
48                         Class<?> c = ctx.getRequiredType();\r
49                         try { \r
50                                 uri = ctx.convertAnother(o, URI.class);\r
51                         } catch ( ConversionException e ){\r
52                                 e.printStackTrace();\r
53                         }\r
54                         if ( uri != null && uri instanceof URI ){\r
55                                 try {\r
56                                         return FuelResolver.getFuel((URI)uri);\r
57                                 } catch (FuelNotFound e) {\r
58                                         // TODO Auto-generated catch block\r
59                                         e.printStackTrace();\r
60                                 }\r
61                         }\r
62 \r
63                         try {\r
64                                 return FuelResolver.getFuel(new URI("motorsim:" + c.getSimpleName()));\r
65                         } catch (FuelNotFound e) {\r
66                                 // TODO Auto-generated catch block\r
67                                 e.printStackTrace();\r
68                         } catch (URISyntaxException e) {\r
69                                 // TODO Auto-generated catch block\r
70                                 e.printStackTrace();\r
71                         }\r
72                         return null;\r
73                 }\r
74                 \r
75         }\r
76         \r
77         static class AmountConverter implements Converter{\r
78                 \r
79                 @SuppressWarnings("unchecked")\r
80                 public void marshal(Object o, HierarchicalStreamWriter w, MarshallingContext c) {\r
81                         Amount a = (Amount)o;\r
82                         String text;\r
83                         //Leave off the fractional part if it is not relevant so we get exact values back\r
84                         if (a.isExact())\r
85                                 text = a.getExactValue() + " " + a.getUnit();\r
86                         else\r
87                                 text = a.doubleValue(a.getUnit()) + " " + a.getUnit();\r
88                         w.setValue(fix(text));\r
89                 }\r
90 \r
91                 public Object unmarshal(HierarchicalStreamReader r, UnmarshallingContext c) {\r
92                         String text = r.getValue();\r
93                         return Amount.valueOf(unfix(text));\r
94                 }\r
95                 \r
96                 private String fix(String s){\r
97                         return s.replace("\u00B3", "^3");\r
98                 }\r
99                 \r
100                 private String unfix(String s){\r
101                         return s.replace("^3", "\u00B3");\r
102                 }\r
103 \r
104                 public boolean canConvert(Class c) {\r
105                         return c.equals(Amount.class);\r
106                 }\r
107                 \r
108         \r
109         }\r
110         \r
111         @SuppressWarnings("deprecation")\r
112         private static XStream getXStream(){\r
113                 XStream xstream = new XStream();\r
114                 xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);\r
115                 xstream.registerConverter(new AmountConverter());\r
116                 xstream.registerConverter(new FuelConverter());\r
117                 xstream.registerConverter(new JavaBeanConverter(xstream.getClassMapper(), "class"), -20); \r
118                 return xstream;\r
119         }\r
120         \r
121         @SuppressWarnings("deprecation")\r
122         private static XStream getFuelXStream(){\r
123                 XStream xstream = new XStream();\r
124                 xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);\r
125                 xstream.registerConverter(new AmountConverter());\r
126                 xstream.registerConverter(new JavaBeanConverter(xstream.getClassMapper(), "class"), -20); \r
127                 return xstream;\r
128         }\r
129         \r
130         public static void writeFuel(Fuel f, OutputStream os) throws IOException{\r
131                 ObjectOutputStream out = getFuelXStream().createObjectOutputStream(os);\r
132                 out.writeObject(f);\r
133                 out.close();\r
134                 os.flush();\r
135         }\r
136         \r
137         public static Fuel readFuel(InputStream is) throws IOException{\r
138                 ObjectInputStream in = getFuelXStream().createObjectInputStream(is);\r
139                 Fuel f;\r
140                 try {\r
141                         f = (Fuel)in.readObject();\r
142                 } catch (ClassNotFoundException e) {\r
143                         throw new IOException("Class not found", e);\r
144                 }\r
145                 return f;\r
146         }\r
147         \r
148         public static void writeMotor(Motor m, OutputStream os) throws IOException{\r
149                 ObjectOutputStream out = getXStream().createObjectOutputStream(os);\r
150                 out.writeObject(m);\r
151                 out.close();\r
152                 os.flush();\r
153         }\r
154         \r
155         public static Motor readMotor(InputStream is) throws IOException{\r
156                 ObjectInputStream in = getXStream().createObjectInputStream(is);\r
157                 Motor m;\r
158                 try {\r
159                         m = (Motor)in.readObject();\r
160                 } catch (ClassNotFoundException e) {\r
161                         throw new IOException("Class not found", e);\r
162                 }\r
163                 return m;\r
164         }\r
165         \r
166 }\r