1 | /* |
2 | * Copyright (c) 2005 The PseudoQ Project. |
3 | * |
4 | * This file is part of PseudoQ. |
5 | * |
6 | * PseudoQ is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU Lesser General Public License as published by |
8 | * the Free Software Foundation; either version 2.1 of the License, or |
9 | * (at your option) any later version. |
10 | * |
11 | * PseudoQ is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU Lesser General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU Lesser General Public License |
17 | * along with PseudoQ; if not, write to the Free Software |
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
19 | */ |
20 | |
21 | package net.sourceforge.pseudoq.model.io; |
22 | |
23 | import java.util.Set; |
24 | |
25 | import net.sourceforge.pseudoq.model.Coordinate; |
26 | import net.sourceforge.pseudoq.model.Grid; |
27 | import net.sourceforge.pseudoq.model.Puzzle; |
28 | import net.sourceforge.pseudoq.model.PuzzleFactory; |
29 | import net.sourceforge.pseudoq.model.PuzzleTypeEnum; |
30 | import net.sourceforge.pseudoq.solver.Solution; |
31 | |
32 | /** |
33 | * Scans a DOM tree and constructs the puzzle represented. |
34 | * |
35 | * Example: |
36 | * <pre> |
37 | * javax.xml.parsers.DocumentBuilderFactory builderFactory = javax.xml.parsers.DocumentBuilderFactory.newInstance(); |
38 | * javax.xml.parsers.DocumentBuilder builder = builderFactory.newDocumentBuilder(); |
39 | * org.w3c.dom.Document document = builder.parse(new org.xml.sax.InputSource (???)); |
40 | * <font color="blue">PuzzleScanner scanner = new PuzzleScanner(document);</font> |
41 | * <font color="blue">Puzzle puzzle = scanner.visitDocument();</font> |
42 | * </pre> |
43 | * @author <a href="http://sourceforge.net/users/stevensa">Andrew Stevens</a> |
44 | * @author generated from pseudoq-puzzle-1.0.dtd by NetBeans XML module |
45 | * @see org.w3c.dom.Document |
46 | * @see org.w3c.dom.Element |
47 | * @see org.w3c.dom.NamedNodeMap |
48 | */ |
49 | public class PuzzleScanner { |
50 | /** Log4J logger */ |
51 | private static final org.apache.log4j.Logger log = |
52 | org.apache.log4j.LogManager.getLogger(PuzzleScanner.class); |
53 | |
54 | /** |
55 | * org.w3c.dom.Document document |
56 | */ |
57 | private org.w3c.dom.Document document = null; |
58 | |
59 | private Puzzle puzzle = null; |
60 | private Grid grid = null; |
61 | private Coordinate coordinate = null; |
62 | private Integer value = null; |
63 | private Solution solution = null; |
64 | private String explanation = null; |
65 | |
66 | /** |
67 | * Create new PuzzleScanner with org.w3c.dom.Document. |
68 | */ |
69 | public PuzzleScanner(org.w3c.dom.Document document) { |
70 | this.document = document; |
71 | } |
72 | |
73 | /** |
74 | * Scan through org.w3c.dom.Document document. |
75 | */ |
76 | public Puzzle visitDocument() { |
77 | reset(); |
78 | org.w3c.dom.Element element = document.getDocumentElement(); |
79 | if ((element != null) && element.getTagName().equals("puzzle")) { |
80 | visitElement_puzzle(element); |
81 | } |
82 | // if ((element != null) && element.getTagName().equals("givens")) { |
83 | // visitElement_givens(element); |
84 | // } |
85 | // if ((element != null) && element.getTagName().equals("grid")) { |
86 | // visitElement_grid(element); |
87 | // } |
88 | // if ((element != null) && element.getTagName().equals("cell")) { |
89 | // visitElement_cell(element); |
90 | // } |
91 | // if ((element != null) && element.getTagName().equals("coordinate")) { |
92 | // visitElement_coordinate(element); |
93 | // } |
94 | // if ((element != null) && element.getTagName().equals("value")) { |
95 | // visitElement_value(element); |
96 | // } |
97 | return puzzle; |
98 | } |
99 | |
100 | /** |
101 | * Scan through org.w3c.dom.Element named puzzle. |
102 | */ |
103 | void visitElement_puzzle(org.w3c.dom.Element element) { // <puzzle> |
104 | // element.getValue(); |
105 | org.w3c.dom.NamedNodeMap attrs = element.getAttributes(); |
106 | for (int i = 0; i < attrs.getLength(); i++) { |
107 | org.w3c.dom.Attr attr = (org.w3c.dom.Attr)attrs.item(i); |
108 | if (attr.getName().equals("type")) { // <puzzle type="???"> |
109 | String type = attr.getValue(); |
110 | PuzzleTypeEnum puzzleType = PuzzleTypeEnum.valueOf(type); |
111 | puzzle = PuzzleFactory.newInstance(puzzleType); |
112 | } |
113 | } |
114 | org.w3c.dom.NodeList nodes = element.getChildNodes(); |
115 | for (int i = 0; i < nodes.getLength(); i++) { |
116 | org.w3c.dom.Node node = nodes.item(i); |
117 | switch (node.getNodeType()) { |
118 | case org.w3c.dom.Node.CDATA_SECTION_NODE: |
119 | // ((org.w3c.dom.CDATASection)node).getData(); |
120 | break; |
121 | case org.w3c.dom.Node.ELEMENT_NODE: |
122 | org.w3c.dom.Element nodeElement = (org.w3c.dom.Element)node; |
123 | if (nodeElement.getTagName().equals("givens")) { |
124 | visitElement_givens(nodeElement); |
125 | } |
126 | if (nodeElement.getTagName().equals("grid")) { |
127 | grid = puzzle.getGrid(); |
128 | visitElement_grid(nodeElement); |
129 | grid = null; |
130 | } |
131 | if (nodeElement.getTagName().equals("solution")) { |
132 | visitElement_solution(nodeElement); |
133 | } |
134 | break; |
135 | case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE: |
136 | // ((org.w3c.dom.ProcessingInstruction)node).getTarget(); |
137 | // ((org.w3c.dom.ProcessingInstruction)node).getData(); |
138 | break; |
139 | default: |
140 | // do nothing |
141 | break; |
142 | } |
143 | } |
144 | } |
145 | |
146 | /** |
147 | * Scan through org.w3c.dom.Element named givens. |
148 | */ |
149 | void visitElement_givens(org.w3c.dom.Element element) { // <givens> |
150 | Set<Coordinate> givens = puzzle.getGivens(); |
151 | // element.getValue(); |
152 | org.w3c.dom.NodeList nodes = element.getChildNodes(); |
153 | for (int i = 0; i < nodes.getLength(); i++) { |
154 | org.w3c.dom.Node node = nodes.item(i); |
155 | switch (node.getNodeType()) { |
156 | case org.w3c.dom.Node.CDATA_SECTION_NODE: |
157 | // ((org.w3c.dom.CDATASection)node).getData(); |
158 | break; |
159 | case org.w3c.dom.Node.ELEMENT_NODE: |
160 | org.w3c.dom.Element nodeElement = (org.w3c.dom.Element)node; |
161 | if (nodeElement.getTagName().equals("coordinate")) { |
162 | coordinate = null; |
163 | visitElement_coordinate(nodeElement); |
164 | givens.add(coordinate); |
165 | } |
166 | break; |
167 | case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE: |
168 | // ((org.w3c.dom.ProcessingInstruction)node).getTarget(); |
169 | // ((org.w3c.dom.ProcessingInstruction)node).getData(); |
170 | break; |
171 | default: |
172 | // do nothing |
173 | break; |
174 | } |
175 | } |
176 | } |
177 | |
178 | /** |
179 | * Scan through org.w3c.dom.Element named grid. |
180 | */ |
181 | void visitElement_grid(org.w3c.dom.Element element) { // <grid> |
182 | // element.getValue(); |
183 | org.w3c.dom.NodeList nodes = element.getChildNodes(); |
184 | for (int i = 0; i < nodes.getLength(); i++) { |
185 | org.w3c.dom.Node node = nodes.item(i); |
186 | switch (node.getNodeType()) { |
187 | case org.w3c.dom.Node.CDATA_SECTION_NODE: |
188 | // ((org.w3c.dom.CDATASection)node).getData(); |
189 | break; |
190 | case org.w3c.dom.Node.ELEMENT_NODE: |
191 | org.w3c.dom.Element nodeElement = (org.w3c.dom.Element)node; |
192 | if (nodeElement.getTagName().equals("cell")) { |
193 | coordinate = null; |
194 | value = null; |
195 | visitElement_cell(nodeElement); |
196 | grid.put(coordinate, value); |
197 | } |
198 | break; |
199 | case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE: |
200 | // ((org.w3c.dom.ProcessingInstruction)node).getTarget(); |
201 | // ((org.w3c.dom.ProcessingInstruction)node).getData(); |
202 | break; |
203 | default: |
204 | // do nothing |
205 | break; |
206 | } |
207 | } |
208 | } |
209 | |
210 | /** |
211 | * Scan through org.w3c.dom.Element named cell. |
212 | */ |
213 | void visitElement_cell(org.w3c.dom.Element element) { // <cell> |
214 | // element.getValue(); |
215 | org.w3c.dom.NodeList nodes = element.getChildNodes(); |
216 | for (int i = 0; i < nodes.getLength(); i++) { |
217 | org.w3c.dom.Node node = nodes.item(i); |
218 | switch (node.getNodeType()) { |
219 | case org.w3c.dom.Node.CDATA_SECTION_NODE: |
220 | // ((org.w3c.dom.CDATASection)node).getData(); |
221 | break; |
222 | case org.w3c.dom.Node.ELEMENT_NODE: |
223 | org.w3c.dom.Element nodeElement = (org.w3c.dom.Element)node; |
224 | if (nodeElement.getTagName().equals("coordinate")) { |
225 | visitElement_coordinate(nodeElement); |
226 | } |
227 | if (nodeElement.getTagName().equals("value")) { |
228 | visitElement_value(nodeElement); |
229 | } |
230 | break; |
231 | case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE: |
232 | // ((org.w3c.dom.ProcessingInstruction)node).getTarget(); |
233 | // ((org.w3c.dom.ProcessingInstruction)node).getData(); |
234 | break; |
235 | default: |
236 | // do nothing |
237 | break; |
238 | } |
239 | } |
240 | } |
241 | |
242 | /** |
243 | * Scan through org.w3c.dom.Element named coordinate. |
244 | */ |
245 | void visitElement_coordinate(org.w3c.dom.Element element) { // <coordinate> |
246 | // element.getValue(); |
247 | int row = 0; |
248 | int column = 0; |
249 | org.w3c.dom.NamedNodeMap attrs = element.getAttributes(); |
250 | for (int i = 0; i < attrs.getLength(); i++) { |
251 | org.w3c.dom.Attr attr = (org.w3c.dom.Attr)attrs.item(i); |
252 | if (attr.getName().equals("row")) { // <coordinate row="???"> |
253 | row = Integer.parseInt(attr.getValue()); |
254 | } |
255 | if (attr.getName().equals("column")) { // <coordinate column="???"> |
256 | column = Integer.parseInt(attr.getValue()); |
257 | } |
258 | } |
259 | coordinate = new Coordinate(row, column); |
260 | |
261 | org.w3c.dom.NodeList nodes = element.getChildNodes(); |
262 | for (int i = 0; i < nodes.getLength(); i++) { |
263 | org.w3c.dom.Node node = nodes.item(i); |
264 | switch (node.getNodeType()) { |
265 | case org.w3c.dom.Node.CDATA_SECTION_NODE: |
266 | // ((org.w3c.dom.CDATASection)node).getData(); |
267 | break; |
268 | case org.w3c.dom.Node.ELEMENT_NODE: |
269 | org.w3c.dom.Element nodeElement = (org.w3c.dom.Element)node; |
270 | break; |
271 | case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE: |
272 | // ((org.w3c.dom.ProcessingInstruction)node).getTarget(); |
273 | // ((org.w3c.dom.ProcessingInstruction)node).getData(); |
274 | break; |
275 | default: |
276 | // do nothing |
277 | break; |
278 | } |
279 | } |
280 | } |
281 | |
282 | /** |
283 | * Scan through org.w3c.dom.Element named value. |
284 | */ |
285 | void visitElement_value(org.w3c.dom.Element element) { // <value> |
286 | // element.getValue(); |
287 | org.w3c.dom.NodeList nodes = element.getChildNodes(); |
288 | for (int i = 0; i < nodes.getLength(); i++) { |
289 | org.w3c.dom.Node node = nodes.item(i); |
290 | switch (node.getNodeType()) { |
291 | case org.w3c.dom.Node.CDATA_SECTION_NODE: |
292 | value = Integer.valueOf(((org.w3c.dom.CDATASection)node).getData()); |
293 | break; |
294 | case org.w3c.dom.Node.ELEMENT_NODE: |
295 | org.w3c.dom.Element nodeElement = (org.w3c.dom.Element)node; |
296 | break; |
297 | case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE: |
298 | // ((org.w3c.dom.ProcessingInstruction)node).getTarget(); |
299 | // ((org.w3c.dom.ProcessingInstruction)node).getData(); |
300 | break; |
301 | case org.w3c.dom.Node.TEXT_NODE: |
302 | value = Integer.valueOf(((org.w3c.dom.Text)node).getData()); |
303 | break; |
304 | default: |
305 | // do nothing |
306 | break; |
307 | } |
308 | } |
309 | } |
310 | |
311 | /** |
312 | * Scan through org.w3c.dom.Element named solution. |
313 | */ |
314 | void visitElement_solution(org.w3c.dom.Element element) { // <puzzle> |
315 | solution = new Solution(); |
316 | // element.getValue(); |
317 | org.w3c.dom.NodeList nodes = element.getChildNodes(); |
318 | for (int i = 0; i < nodes.getLength(); i++) { |
319 | org.w3c.dom.Node node = nodes.item(i); |
320 | switch (node.getNodeType()) { |
321 | case org.w3c.dom.Node.CDATA_SECTION_NODE: |
322 | // ((org.w3c.dom.CDATASection)node).getData(); |
323 | break; |
324 | case org.w3c.dom.Node.ELEMENT_NODE: |
325 | org.w3c.dom.Element nodeElement = (org.w3c.dom.Element)node; |
326 | if (nodeElement.getTagName().equals("grid")) { |
327 | grid = new Grid(puzzle.getSize()); |
328 | visitElement_grid(nodeElement); |
329 | solution.setGrid(grid); |
330 | grid = null; |
331 | } |
332 | if (nodeElement.getTagName().equals("step")) { |
333 | coordinate = null; |
334 | explanation = null; |
335 | visitElement_step(nodeElement); |
336 | // solution.addStep(coordinate, explanation); |
337 | } |
338 | break; |
339 | case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE: |
340 | // ((org.w3c.dom.ProcessingInstruction)node).getTarget(); |
341 | // ((org.w3c.dom.ProcessingInstruction)node).getData(); |
342 | break; |
343 | default: |
344 | // do nothing |
345 | break; |
346 | } |
347 | } |
348 | puzzle.setSolution(solution); |
349 | solution = null; |
350 | } |
351 | |
352 | /** |
353 | * Scan through org.w3c.dom.Element named step. |
354 | */ |
355 | void visitElement_step(org.w3c.dom.Element element) { // <cell> |
356 | // element.getValue(); |
357 | org.w3c.dom.NodeList nodes = element.getChildNodes(); |
358 | for (int i = 0; i < nodes.getLength(); i++) { |
359 | org.w3c.dom.Node node = nodes.item(i); |
360 | switch (node.getNodeType()) { |
361 | case org.w3c.dom.Node.CDATA_SECTION_NODE: |
362 | // ((org.w3c.dom.CDATASection)node).getData(); |
363 | break; |
364 | case org.w3c.dom.Node.ELEMENT_NODE: |
365 | org.w3c.dom.Element nodeElement = (org.w3c.dom.Element)node; |
366 | if (nodeElement.getTagName().equals("coordinate")) { |
367 | visitElement_coordinate(nodeElement); |
368 | } |
369 | if (nodeElement.getTagName().equals("explanation")) { |
370 | visitElement_explanation(nodeElement); |
371 | } |
372 | break; |
373 | case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE: |
374 | // ((org.w3c.dom.ProcessingInstruction)node).getTarget(); |
375 | // ((org.w3c.dom.ProcessingInstruction)node).getData(); |
376 | break; |
377 | default: |
378 | // do nothing |
379 | break; |
380 | } |
381 | } |
382 | } |
383 | |
384 | /** |
385 | * Scan through org.w3c.dom.Element named explanation. |
386 | */ |
387 | void visitElement_explanation(org.w3c.dom.Element element) { // <value> |
388 | // element.getValue(); |
389 | org.w3c.dom.NodeList nodes = element.getChildNodes(); |
390 | for (int i = 0; i < nodes.getLength(); i++) { |
391 | org.w3c.dom.Node node = nodes.item(i); |
392 | switch (node.getNodeType()) { |
393 | case org.w3c.dom.Node.CDATA_SECTION_NODE: |
394 | explanation = ((org.w3c.dom.CDATASection)node).getData(); |
395 | break; |
396 | case org.w3c.dom.Node.ELEMENT_NODE: |
397 | org.w3c.dom.Element nodeElement = (org.w3c.dom.Element)node; |
398 | break; |
399 | case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE: |
400 | // ((org.w3c.dom.ProcessingInstruction)node).getTarget(); |
401 | // ((org.w3c.dom.ProcessingInstruction)node).getData(); |
402 | break; |
403 | case org.w3c.dom.Node.TEXT_NODE: |
404 | value = Integer.valueOf(((org.w3c.dom.Text)node).getData()); |
405 | break; |
406 | default: |
407 | // do nothing |
408 | break; |
409 | } |
410 | } |
411 | } |
412 | |
413 | private void reset() { |
414 | puzzle = null; |
415 | grid = null; |
416 | coordinate = null; |
417 | value = null; |
418 | solution = null; |
419 | explanation = null; |
420 | } |
421 | |
422 | } |