c627827fe0bb024eab1071f0fbbce57223828f17
[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                         Fuel f = (Fuel)o;\r
41                         URI uri = FuelResolver.getURI(f);\r
42                         ctx.convertAnother(uri);\r
43                 }\r
44 \r
45                 @Override\r
46                 public Object unmarshal(HierarchicalStreamReader r,\r
47                                 UnmarshallingContext ctx) {\r
48                         Object o = ctx.currentObject();\r
49                         Object uri = null;\r
50                         Class<?> c = ctx.getRequiredType();\r
51                         try { \r
52                                 uri = ctx.convertAnother(o, URI.class);\r
53                         } catch ( ConversionException e ){\r
54                                 e.printStackTrace();\r
55                         }\r
56                         if ( uri != null && uri instanceof URI ){\r
57                                 try {\r
58                                         return FuelResolver.getFuel((URI)uri);\r
59                                 } catch (FuelNotFound e) {\r
60                                         // TODO Auto-generated catch block\r
61                                         e.printStackTrace();\r
62                                 }\r
63                         }\r
64 \r
65                         try {\r
66                                 return FuelResolver.getFuel(new URI("motorsim:" + c.getSimpleName()));\r
67                         } catch (FuelNotFound e) {\r
68                                 // TODO Auto-generated catch block\r
69                                 e.printStackTrace();\r
70                         } catch (URISyntaxException e) {\r
71                                 // TODO Auto-generated catch block\r
72                                 e.printStackTrace();\r
73                         }\r
74                         return null;\r
75                 }\r
76                 \r
77         }\r
78         \r
79         static class AmountConverter implements Converter{\r
80                 \r
81                 @SuppressWarnings("unchecked")\r
82                 public void marshal(Object o, HierarchicalStreamWriter w, MarshallingContext c) {\r
83                         Amount a = (Amount)o;\r
84                         String text;\r
85                         //Leave off the fractional part if it is not relevant so we get exact values back\r
86                         if (a.isExact())\r
87                                 text = a.getExactValue() + " " + a.getUnit();\r
88                         else\r
89                                 text = a.doubleValue(a.getUnit()) + " " + a.getUnit();\r
90                         w.setValue(fix(text));\r
91                 }\r
92 \r
93                 public Object unmarshal(HierarchicalStreamReader r, UnmarshallingContext c) {\r
94                         String text = r.getValue();\r
95                         return Amount.valueOf(unfix(text));\r
96                 }\r
97                 \r
98                 private String fix(String s){\r
99                         return s.replace("\u00B3", "^3");\r
100                 }\r
101                 \r
102                 private String unfix(String s){\r
103                         return s.replace("^3", "\u00B3");\r
104                 }\r
105 \r
106                 public boolean canConvert(Class c) {\r
107                         return c.equals(Amount.class);\r
108                 }\r
109                 \r
110         \r
111         }\r
112         \r
113         @SuppressWarnings("deprecation")\r
114         private static XStream getXStream(){\r
115                 XStream xstream = new XStream();\r
116                 xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);\r
117                 xstream.registerConverter(new AmountConverter());\r
118                 xstream.registerConverter(new FuelConverter());\r
119                 xstream.registerConverter(new JavaBeanConverter(xstream.getClassMapper(), "class"), -20); \r
120                 return xstream;\r
121         }\r
122         \r
123         @SuppressWarnings("deprecation")\r
124         private static XStream getFuelXStream(){\r
125                 XStream xstream = new XStream();\r
126                 xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);\r
127                 xstream.registerConverter(new AmountConverter());\r
128                 xstream.registerConverter(new JavaBeanConverter(xstream.getClassMapper(), "class"), -20); \r
129                 return xstream;\r
130         }\r
131         \r
132         public static void writeFuel(Fuel f, OutputStream os) throws IOException{\r
133                 ObjectOutputStream out = getFuelXStream().createObjectOutputStream(os);\r
134                 out.writeObject(f);\r
135                 out.close();\r
136                 os.flush();\r
137         }\r
138         \r
139         public static Fuel readFuel(InputStream is) throws IOException{\r
140                 ObjectInputStream in = getFuelXStream().createObjectInputStream(is);\r
141                 Fuel f;\r
142                 try {\r
143                         f = (Fuel)in.readObject();\r
144                 } catch (ClassNotFoundException e) {\r
145                         throw new IOException("Class not found", e);\r
146                 }\r
147                 return f;\r
148         }\r
149         \r
150         public static void writeMotor(Motor m, OutputStream os) throws IOException{\r
151                 ObjectOutputStream out = getXStream().createObjectOutputStream(os);\r
152                 out.writeObject(m);\r
153                 out.close();\r
154                 os.flush();\r
155         }\r
156         \r
157         public static Motor readMotor(InputStream is) throws IOException{\r
158                 ObjectInputStream in = getXStream().createObjectInputStream(is);\r
159                 Motor m;\r
160                 try {\r
161                         m = (Motor)in.readObject();\r
162                 } catch (ClassNotFoundException e) {\r
163                         throw new IOException("Class not found", e);\r
164                 }\r
165                 return m;\r
166         }\r
167         \r
168 }\r