1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 package name.angoca.db2sa.core.syntax.graph;
30
31 import java.io.IOException;
32 import java.util.HashMap;
33 import java.util.Iterator;
34 import java.util.Map;
35
36 import javax.xml.parsers.DocumentBuilder;
37 import javax.xml.parsers.DocumentBuilderFactory;
38 import javax.xml.parsers.ParserConfigurationException;
39
40 import name.angoca.db2sa.Configurator;
41 import name.angoca.db2sa.Constants;
42 import name.angoca.db2sa.core.syntax.graph.exception.DuplicateNodeException;
43 import name.angoca.db2sa.core.syntax.graph.exception.EndingNodeNotDefinedException;
44 import name.angoca.db2sa.core.syntax.graph.exception.GrammarFileException;
45 import name.angoca.db2sa.core.syntax.graph.exception.InvalidGraphException;
46 import name.angoca.db2sa.core.syntax.graph.exception.StartingNodeNotDefinedException;
47 import name.angoca.db2sa.messages.Messages;
48
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51 import org.w3c.dom.Document;
52 import org.w3c.dom.Element;
53 import org.w3c.dom.NodeList;
54 import org.xml.sax.InputSource;
55 import org.xml.sax.SAXException;
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82 public final class GraphConstructor {
83
84
85
86
87 private static final Logger LOGGER = LoggerFactory
88 .getLogger(GraphConstructor.class);
89
90
91
92
93 private final Map<String, GraphToken> m_tokens;
94
95
96
97
98 private GraphConstructor() {
99 this.m_tokens = new HashMap<String, GraphToken>();
100 }
101
102
103
104
105
106
107
108
109
110
111
112
113 public static StartingToken
114 throws InvalidGraphException {
115
116 final GraphConstructor graphCons = new GraphConstructor();
117
118
119 final Document dom = graphCons.parseXmlFile(content);
120
121
122 graphCons.firstPhaseDocument(dom);
123
124
125 graphCons.secondPhaseDocument(dom);
126
127
128 final StartingToken start = graphCons.addExtraTokens();
129
130 if (GraphConstructor.LOGGER.isDebugEnabled()) {
131 graphCons.printData();
132 }
133
134 return start;
135 }
136
137
138
139
140
141
142
143
144
145
146 private Document parseXmlFile(final InputSource
147 throws GrammarFileException {
148
149 final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
150
151
152 DocumentBuilder docBuilder;
153 Document dom = null;
154
155 try {
156 docBuilder = dbf.newDocumentBuilder();
157
158
159 dom = docBuilder.parse(content);
160
161 } catch (ParserConfigurationException e) {
162
163 throw new GrammarFileException(e);
164 } catch (SAXException e) {
165 throw new GrammarFileException(e);
166 } catch (IOException e) {
167
168 throw new GrammarFileException(e);
169 }
170 return dom;
171 }
172
173
174
175
176
177
178
179
180
181
182
183 private void firstPhaseDocument(final Document dom)
184 throws DuplicateNodeException {
185
186 final Element docEle = dom.getDocumentElement();
187
188
189 final NodeList nodelist = docEle.getElementsByTagName("token");
190
191 if (nodelist != null) {
192 final int size = nodelist.getLength();
193 if (size > 0) {
194 for (int i = 0; i < size; i += 1) {
195
196
197 final Element eleToken = (Element) nodelist.item(i);
198
199
200 final GraphToken graphToken = this.getToken(eleToken);
201
202
203 final String tokenId = graphToken.getId();
204 if (this.m_tokens.containsKey(tokenId)) {
205 throw new DuplicateNodeException(tokenId);
206 }
207 this.m_tokens.put(tokenId, graphToken);
208 }
209 }
210 }
211 }
212
213
214
215
216
217
218
219
220
221 private GraphToken
222
223
224 final String tokenId = this.getTextValue(eleToken, "id");
225 final String name = this.getTextValue(eleToken, "name");
226 final NodeList nodelist = eleToken.getElementsByTagName("reserved");
227 boolean reserved = false;
228 if (nodelist != null && nodelist.getLength() > 0) {
229 reserved = true;
230 }
231
232
233 GraphToken token = null;
234
235 if (tokenId == null) {
236
237
238 throw new RuntimeException("id not defined " + name);
239 } else if (name == null) {
240
241
242 throw new RuntimeException("name not defined " + tokenId);
243 } else if (tokenId.compareTo(Constants.STARTING_TOKEN) == 0) {
244
245 token = new StartingToken();
246 } else if (tokenId.compareTo(Constants.ENDING_TOKEN) == 0) {
247
248 token = new EndingToken();
249 } else {
250
251 token = new GraphToken(tokenId, name, reserved);
252 }
253
254 return token;
255 }
256
257
258
259
260
261
262
263
264
265
266
267 private String
268 final String
269 String textValue = null;
270 final NodeList nodelist = element.getElementsByTagName(tagName);
271 if (nodelist != null && nodelist.getLength() > 0) {
272 final Element elem = (Element) nodelist.item(0);
273 textValue = elem.getFirstChild().getNodeValue();
274 }
275
276 return textValue;
277 }
278
279
280
281
282
283
284
285 private void secondPhaseDocument(final Document dom) {
286
287 final Element docEle = dom.getDocumentElement();
288
289
290 final NodeList tokenlist = docEle.getElementsByTagName("token");
291
292 if (tokenlist != null) {
293 final int size = tokenlist.getLength();
294 if (size > 0) {
295 for (int i = 0; i < size; i += 1) {
296
297
298 final Element eleToken = (Element) tokenlist.item(i);
299
300
301 this.getChildren(eleToken);
302 }
303 }
304 }
305 }
306
307
308
309
310
311
312
313 private void getChildren(final Element
314
315 final String tokenId = this.getTextValue(eleToken, "id");
316
317
318 final GraphToken token = this.m_tokens.get(tokenId);
319
320
321 final NodeList childList = eleToken.getElementsByTagName("idNode");
322
323 if (childList != null) {
324 final int size = childList.getLength();
325 if (size > 0) {
326 for (int i = 0; i < size; i += 1) {
327
328
329 final Element childElement = (Element) childList.item(i);
330
331
332 final String childId = childElement.getFirstChild()
333 .getNodeValue();
334
335
336 final GraphToken childToken = this.m_tokens.get(childId);
337 if (childToken == null) {
338
339 throw new RuntimeException("token not defined "
340 + childId);
341 }
342 token.addWay(childToken);
343 }
344 }
345 }
346 if (GraphConstructor.LOGGER.isDebugEnabled()) {
347 GraphConstructor.LOGGER.debug(token.toString());
348 for (int i = 0; i < token.getWays().size(); i += 1) {
349 GraphConstructor.LOGGER.debug("\t{} ", token.toString());
350 GraphConstructor.LOGGER.debug("\t\t\t -> {}",
351 token.getWays().get(i).toString());
352 }
353 }
354 }
355
356
357
358
359
360
361
362
363 private StartingToken
364 StartingToken start = null;
365 try {
366
367 start = (StartingToken) this.m_tokens.get(Constants.STARTING_TOKEN);
368 if (start == null) {
369 throw new StartingNodeNotDefinedException();
370 }
371
372
373 final EndingToken end = (EndingToken) this.m_tokens
374 .get(Constants.ENDING_TOKEN);
375 if (end == null) {
376 throw new EndingNodeNotDefinedException();
377 }
378
379 if (start.getWays().size() == 1
380 && start.getWays().get(0).getId().compareTo(
381 Constants.ENDING_TOKEN) == 0) {
382 GraphConstructor.LOGGER.info("Invalid graph");
383
384
385 throw new InvalidGraphException();
386 }
387
388
389 final String aboutToken = Configurator.getInstance().getProperty(
390 Constants.ABOUT_TOKEN);
391 if (aboutToken == null) {
392
393 throw new RuntimeException(Messages
394 .getString("GraphConstructor"
395 + ".NoAboutTokenDefined"));
396 }
397 final GraphToken licenseCaller = new GraphToken(aboutToken, true);
398 final LicenseToken license = new LicenseToken();
399
400 start.addWay(licenseCaller);
401 licenseCaller.addWay(license);
402 license.addWay(end);
403
404
405 final String helpToken = Configurator.getInstance().getProperty(
406 Constants.HELP_TOKEN);
407 if (helpToken == null) {
408
409 throw new RuntimeException(Messages
410 .getString("GraphConstructor"
411 + ".NoHelpTokenDefined"));
412 }
413 final GraphToken helpCaller = new GraphToken(helpToken, true);
414 final HelpToken help = new HelpToken();
415
416 start.addWay(helpCaller);
417 helpCaller.addWay(help);
418 help.addWay(end);
419
420 } catch (ClassCastException e) {
421
422 throw new InvalidGraphException(e);
423 }
424 return start;
425 }
426
427
428
429
430 @SuppressWarnings("boxing")
431 private void printData() {
432
433 GraphConstructor.LOGGER
434 .debug("No of Tokens '{}'", this.m_tokens.size());
435
436 final Iterator<GraphToken> iterator = this.m_tokens.values().iterator();
437 while (iterator.hasNext()) {
438 GraphConstructor.LOGGER.debug(iterator.next().toString());
439 }
440 }
441 }