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