1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package pl.edu.agh.cast.model.mapper.internal;
19
20 import java.lang.reflect.Constructor;
21 import java.lang.reflect.Method;
22 import java.util.Date;
23 import java.util.HashMap;
24 import java.util.Map;
25
26 import org.xml.sax.Attributes;
27 import org.xml.sax.SAXException;
28 import org.xml.sax.helpers.DefaultHandler;
29
30 import pl.edu.agh.cast.model.base.IDataSet;
31 import pl.edu.agh.cast.model.base.IEntity;
32 import pl.edu.agh.cast.model.base.IModel;
33 import pl.edu.agh.cast.model.base.IRelation;
34 import pl.edu.agh.cast.model.mapper.Mappable;
35
36
37
38
39
40
41 class ModelParser extends DefaultHandler {
42 private static final String NULL = "null";
43
44 private static final String INT_TYPE = "int";
45
46 private static final String DOUBLE_TYPE = "double";
47
48 private static final String BOOLEAN_TYPE = "boolean";
49
50 private static final String LONG_TYPE = "long";
51
52 private static final String SETTER_PREFIX = "set";
53
54
55
56
57 private Map<Long, Mappable> cache = new HashMap<Long, Mappable>();
58
59 private IDataSet dataSet;
60
61 private Mappable mappable;
62
63 private String mappableQName;
64
65 private Method setterMethod;
66
67 private Class returnType;
68
69 private IModel model;
70
71 private Map<String, Class> typeMap;
72
73 private StringBuilder contentBuffer = new StringBuilder();
74
75 public ModelParser(IModel newModel, Map<String, Class> newTypeMap) {
76 model = newModel;
77 typeMap = newTypeMap;
78 }
79
80
81
82
83
84
85
86
87
88
89
90
91
92 @Override
93 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
94
95 if (qName.equals(XMLSaver.ROOT)) {
96 if (model.getId() == null) {
97 model.setId(attributes.getValue(XMLSaver.ID));
98 }
99 return;
100 }
101 try {
102 if (mappableQName == null) {
103
104 Class<Mappable> klass = Helper.mappedClass(qName, typeMap);
105 Constructor<Mappable> constructor = Helper.getConstructor(klass);
106 mappable = constructor.newInstance((Object[])null);
107 if (mappable instanceof IRelation) {
108 IRelation relation = (IRelation)mappable;
109 IEntity source = (IEntity)cache.get(Long.parseLong(attributes.getValue(XMLSaver.SOURCE)));
110 if (source == null) {
111 throw new SAXException("Relation references entity which was not yet " +
112 "parsed. Data set: " + dataSet);
113 }
114 relation.setSource(source);
115 source.addRelation(relation);
116 IEntity target = (IEntity)cache.get(Long.parseLong(attributes.getValue(XMLSaver.TARGET)));
117 if (target == null) {
118 throw new SAXException("Relation references entity which was not yet " +
119 "parsed. Data set: " + dataSet);
120 }
121 relation.setTarget(target);
122 target.addRelation(relation);
123 } else if (mappable instanceof IDataSet) {
124 dataSet = (IDataSet)mappable;
125 model.addDataSet(dataSet);
126 dataSet.setModel(model);
127 }
128 mappableQName = qName;
129 mappable.setMid(Long.parseLong(attributes.getValue(XMLSaver.ID)));
130 cache.put(mappable.getMid(), mappable);
131 } else {
132
133 String setterName = SETTER_PREFIX + qName.substring(3);
134 String typeName = attributes.getValue(XMLSaver.TYPE);
135 if (typeName.equals(LONG_TYPE)) {
136 returnType = long.class;
137 } else if (typeName.equals(BOOLEAN_TYPE)) {
138 returnType = boolean.class;
139 } else if (typeName.equals(DOUBLE_TYPE)) {
140 returnType = double.class;
141 } else if (typeName.equals(INT_TYPE)) {
142 returnType = int.class;
143 } else {
144 returnType = Class.forName(typeName);
145 }
146
147 setterMethod = mappable.getClass().getMethod(setterName, returnType);
148
149 }
150 } catch (Exception e) {
151 e.printStackTrace();
152 throw new SAXException(e);
153 }
154 }
155
156
157
158
159
160
161
162
163
164
165
166 @Override
167 public void characters(char[] ch, int start, int length) {
168 if (setterMethod != null) {
169
170 contentBuffer.append(ch, start, length);
171 }
172 }
173
174
175
176
177
178
179 @Override
180 public void endElement(String uri, String localName, String qName) throws SAXException {
181 if (setterMethod != null) {
182
183 Object value = null;
184 String valueString = contentBuffer.toString();
185 contentBuffer.setLength(0);
186 try {
187 if (valueString.equals(NULL)) {
188 value = null;
189 } else if (String.class.equals(returnType)) {
190 value = valueString;
191 } else if (Long.class.equals(returnType) || long.class.equals(returnType)) {
192 value = Long.parseLong(valueString);
193 } else if (Integer.class.equals(returnType) || int.class.equals(returnType)) {
194 value = Integer.parseInt(valueString);
195 } else if (Double.class.equals(returnType) || double.class.equals(returnType)) {
196 value = Double.parseDouble(valueString);
197 } else if (Date.class.equals(returnType)) {
198 value = XMLSaver.DATE_FORMAT.parse(valueString);
199 } else if (Boolean.class.equals(returnType) || boolean.class.equals(returnType)) {
200 if (valueString.equals("true")) {
201 value = new Boolean(true);
202 } else {
203 value = new Boolean(false);
204 }
205 }
206 setterMethod.invoke(mappable, new Object[] { value });
207 setterMethod = null;
208 } catch (Exception e) {
209 throw new SAXException(e);
210 }
211 } else if (mappableQName != null) {
212
213 if (mappableQName.equals(qName)) {
214 if (mappable instanceof IRelation) {
215
216
217 dataSet.addRelation((IRelation)mappable);
218 }
219 mappableQName = null;
220 mappable = null;
221 }
222 }
223 }
224 }