15 |
private int ignoreAll; |
private int ignoreAll; |
16 |
private Element parentElement; |
private Element parentElement; |
17 |
public Element rootElement; |
public Element rootElement; |
|
private String name; |
|
18 |
private URL url; |
private URL url; |
19 |
private ParserElement currentElement; |
private ParserElement currentElement; |
20 |
|
private String name; |
21 |
|
|
22 |
/* |
/* |
23 |
* ============================================ |
* ============================================ |
25 |
* ============================================ |
* ============================================ |
26 |
*/ |
*/ |
27 |
|
|
28 |
abstract class ParserElement implements Cloneable { |
abstract class ParserElement implements Cloneable |
29 |
|
{ |
30 |
abstract public void start(String qName, Attributes atts) |
abstract public void start(String qName, Attributes atts) |
31 |
throws SAXException; |
throws SAXException; |
32 |
abstract public void end(String qName); |
abstract public void end(String qName) |
33 |
|
throws SAXException; |
34 |
abstract public void characters(char[] ch, int start, int length); |
abstract public void characters(char[] ch, int start, int length); |
35 |
|
|
36 |
public ParserElement previousElement; |
public ParserElement previousElement; |
37 |
} |
} |
38 |
|
|
39 |
class EmptyParserElement extends ParserElement { |
class EmptyParserElement extends ParserElement |
40 |
|
{ |
41 |
public void start(String qName, Attributes atts) |
public void start(String qName, Attributes atts) |
42 |
throws SAXException |
throws SAXException |
43 |
{ |
{ |
55 |
/* |
/* |
56 |
* Element ignoring subtree |
* Element ignoring subtree |
57 |
*/ |
*/ |
58 |
class Ignore extends ParserElement { |
class Ignore extends ParserElement |
59 |
|
{ |
60 |
public void start(String qName, Attributes atts) |
public void start(String qName, Attributes atts) |
61 |
{ |
{ |
62 |
ignoreAll++; |
ignoreAll++; |
80 |
* will be solved and analyzed once the XML file has been |
* will be solved and analyzed once the XML file has been |
81 |
* entirely parsed. |
* entirely parsed. |
82 |
*/ |
*/ |
83 |
class Alias extends EmptyParserElement { |
class Alias extends EmptyParserElement |
84 |
|
{ |
85 |
public void start(String qName, Attributes atts) |
public void start(String qName, Attributes atts) |
86 |
throws SAXException |
throws SAXException |
87 |
{ |
{ |
99 |
super.end(qName); |
super.end(qName); |
100 |
} |
} |
101 |
} |
} |
102 |
|
|
103 |
/* |
/* |
104 |
* Root element. This is a representative of the <ldml> tag. |
* Root element. This is a representative of the <ldml> tag. |
105 |
* There should be only one tag of that sort in the XML file. |
* There should be only one tag of that sort in the XML file. |
110 |
public void start(String qName, Attributes atts) |
public void start(String qName, Attributes atts) |
111 |
throws SAXException |
throws SAXException |
112 |
{ |
{ |
|
if (parentElement != null) |
|
|
throw new SAXException("<ldml> tag has already been used"); |
|
|
|
|
|
Element elt = new Element(Parser.this, Element.ROOT, qName); |
|
|
|
|
113 |
super.start(qName, atts); |
super.start(qName, atts); |
114 |
parentElement = elt; |
if (parentElement == null) |
115 |
rootElement = elt; |
{ |
116 |
|
Element elt = new Element(Parser.this, Element.ROOT, qName); |
117 |
|
|
118 |
|
rootElement = elt; |
119 |
|
parentElement = elt; |
120 |
|
} |
121 |
|
else |
122 |
|
{ |
123 |
|
parentElement = rootElement; |
124 |
|
} |
125 |
} |
} |
126 |
} |
} |
127 |
|
|
155 |
} |
} |
156 |
} |
} |
157 |
|
|
158 |
|
abstract class DataBase extends ParserElement |
159 |
|
{ |
160 |
|
StringBuffer data = new StringBuffer(); |
161 |
|
|
162 |
|
public void start(String qName, Attributes atts) |
163 |
|
throws SAXException |
164 |
|
{ |
165 |
|
data.setLength(0); |
166 |
|
} |
167 |
|
|
168 |
|
public void characters(char[] ch, int start, int length) |
169 |
|
{ |
170 |
|
data.append(ch, start, length); |
171 |
|
} |
172 |
|
} |
173 |
|
|
174 |
/* |
/* |
175 |
* Data element. This is a pure leaf node of the tree. |
* Data element. This is a pure leaf node of the tree. |
176 |
*/ |
*/ |
177 |
class Data extends ParserElement |
class Data extends DataBase |
178 |
{ |
{ |
|
StringBuffer data; |
|
179 |
DataElement elt; |
DataElement elt; |
180 |
|
|
181 |
public void start(String qName, Attributes atts) |
public void start(String qName, Attributes atts) |
182 |
|
throws SAXException |
183 |
{ |
{ |
184 |
data = new StringBuffer(); |
super.start(qName, atts); |
185 |
parentElement = elt = new DataElement(Parser.this, parentElement, qName); |
parentElement = elt = new DataElement(Parser.this, parentElement, qName); |
186 |
} |
} |
187 |
|
|
188 |
public void characters(char[] ch, int start, int length) |
public void characters(char[] ch, int start, int length) |
189 |
{ |
{ |
190 |
data.append(ch, start, length); |
data.append(ch, start, length); |
242 |
} |
} |
243 |
} |
} |
244 |
|
|
245 |
|
class Collations extends GroupList |
246 |
|
{ |
247 |
|
public void start(String qName, Attributes atts) |
248 |
|
throws SAXException |
249 |
|
{ |
250 |
|
super.start(qName, atts); |
251 |
|
String vsl = atts.getValue("validSubLocales"); |
252 |
|
if (vsl != null && vsl.length() > 0) |
253 |
|
{ |
254 |
|
ListDataElement lde = (ListDataElement) parentElement; |
255 |
|
lde.listData.put("validSubLocales", vsl); |
256 |
|
} |
257 |
|
} |
258 |
|
|
259 |
|
} |
260 |
|
|
261 |
/* |
/* |
262 |
* This is a group which contains an ordered list of element. |
* This is a group which contains an ordered list of element. |
263 |
*/ |
*/ |
279 |
} |
} |
280 |
} |
} |
281 |
|
|
282 |
/* |
/* |
283 |
* This is a element of an ordered list. |
* This is a element of an ordered list. |
284 |
*/ |
*/ |
285 |
class OrderedList extends EmptyParserElement |
class OrderedList extends Data |
286 |
{ |
{ |
287 |
OrderedListElement parentList; |
OrderedListBaseElement parentList; |
|
StringBuffer listData = new StringBuffer(); |
|
|
DataElement elt; |
|
288 |
|
|
289 |
public void start(String qName, Attributes atts) |
public void start(String qName, Attributes atts) |
290 |
throws SAXException |
throws SAXException |
291 |
{ |
{ |
292 |
|
parentList = (OrderedListBaseElement)parentElement; |
293 |
|
|
294 |
super.start(qName, atts); |
super.start(qName, atts); |
|
|
|
|
listData.setLength(0); |
|
|
parentList = (OrderedListElement)parentElement; |
|
|
parentElement = elt = new DataElement(Parser.this, parentElement, qName); |
|
295 |
} |
} |
296 |
|
|
297 |
public void end(String qName) |
public void end(String qName) |
298 |
{ |
{ |
299 |
elt.data = listData.toString(); |
super.end(qName); |
|
parentElement = elt.superElement; |
|
300 |
parentList.listData.add(elt); |
parentList.listData.add(elt); |
301 |
} |
} |
|
|
|
|
public void characters(char[] ch, int start, int length) |
|
|
{ |
|
|
listData.append(ch, start, length); |
|
|
} |
|
302 |
} |
} |
303 |
|
|
304 |
/* |
/* |
305 |
* This is a list element. However the elements are always introduced in the main tree. |
* This is a list element. However the elements are always introduced in the main tree. |
306 |
* We use the typename to differentiate the various subtree. |
* We use the typename to differentiate the various subtree. |
357 |
} |
} |
358 |
} |
} |
359 |
|
|
360 |
|
/* |
361 |
|
* This parsing element make the presence of "type" imperative. |
362 |
|
*/ |
363 |
class GroupWithType extends Group |
class GroupWithType extends Group |
364 |
{ |
{ |
365 |
public void start(String qName, Attributes atts) |
public void start(String qName, Attributes atts) |
370 |
throw new SAXException("<" + qName + "> must have a type"); |
throw new SAXException("<" + qName + "> must have a type"); |
371 |
} |
} |
372 |
} |
} |
373 |
|
|
374 |
/* |
/* |
375 |
* Specific element as it has two meanings depending on the parent element. |
* This is the reset element for collation rules. |
376 |
*/ |
*/ |
377 |
class Language extends ParserElement |
class Reset extends DataBase |
378 |
{ |
{ |
379 |
List list; |
private ResetElement resetElement; |
380 |
Data data; |
private OrderedListElement parentList; |
381 |
ParserElement elt; |
private StringBuffer sb = new StringBuffer(); |
382 |
|
|
383 |
public void start(String qName, Attributes atts) |
public void start(String qName, Attributes atts) |
384 |
throws SAXException |
throws SAXException |
385 |
{ |
{ |
386 |
if (parentElement.qualifiedName.equals("identity")) |
parentList = (OrderedListElement)parentElement; |
387 |
{ |
resetElement = new ResetElement(Parser.this, parentElement, qName); |
388 |
elt = new GroupWithType(); |
|
389 |
} |
super.start(qName, atts); |
390 |
else |
|
391 |
|
String value; |
392 |
|
|
393 |
|
sb.setLength(0); |
394 |
|
|
395 |
|
value = atts.getValue("before"); |
396 |
|
if (value != null) |
397 |
{ |
{ |
398 |
elt = new List(); |
if (value.equals("primary")) |
399 |
|
resetElement.before = ResetElement.BEFORE_PRIMARY; |
400 |
|
else if (value.equals("secondary")) |
401 |
|
resetElement.before = ResetElement.BEFORE_SECONDARY; |
402 |
|
else if (value.equals("tertiary")) |
403 |
|
resetElement.before = ResetElement.BEFORE_TERTIARY; |
404 |
|
else if (value.equals("identical")) |
405 |
|
resetElement.before = ResetElement.BEFORE_IDENTICAL; |
406 |
|
else |
407 |
|
throw new SAXException("before only accept primary, secondary, tertiary or identical"); |
408 |
} |
} |
409 |
|
|
410 |
elt.previousElement = previousElement; |
parentElement = resetElement; |
|
elt.start(qName, atts); |
|
411 |
} |
} |
412 |
|
|
413 |
public void end(String qName) |
public void end(String qName) |
414 |
{ |
{ |
415 |
elt.end(qName); |
if (sb.length() != 0) |
416 |
|
resetElement.data = sb.toString(); |
417 |
|
|
418 |
|
parentElement = resetElement.superElement; |
419 |
|
parentList.listData.add(resetElement); |
420 |
} |
} |
421 |
|
|
422 |
public void characters(char[] ch, int start, int length) |
public void characters(char ch[], int ofs, int len) |
423 |
|
{ |
424 |
|
sb.append(ch, ofs, len); |
425 |
|
} |
426 |
|
} |
427 |
|
|
428 |
|
class Expansion extends ParserElement |
429 |
|
{ |
430 |
|
ExpansionElement elt; |
431 |
|
|
432 |
|
public void start(String qName, Attributes atts) |
433 |
|
throws SAXException |
434 |
|
{ |
435 |
|
elt = new ExpansionElement(Parser.this, parentElement, qName); |
436 |
|
parentElement = elt; |
437 |
|
} |
438 |
|
|
439 |
|
public void end(String qName) |
440 |
|
throws SAXException |
441 |
|
{ |
442 |
|
parentElement = elt.superElement; |
443 |
|
elt.fixExpansionData(); |
444 |
|
} |
445 |
|
|
446 |
|
public void characters(char[] ch, int ofs, int len) |
447 |
|
{ |
448 |
|
} |
449 |
|
} |
450 |
|
|
451 |
|
class CP extends EmptyParserElement |
452 |
|
{ |
453 |
|
public void start(String qName, Attributes atts) |
454 |
|
throws SAXException |
455 |
|
{ |
456 |
|
String hex = atts.getValue("hex"); |
457 |
|
char code; |
458 |
|
|
459 |
|
if (hex == null) |
460 |
|
throw new SAXException("<cp> needs an hex argument"); |
461 |
|
|
462 |
|
if (!(previousElement instanceof DataBase)) |
463 |
|
throw new SAXException("<cp> needs a data type element as parent"); |
464 |
|
|
465 |
|
code = (char)Integer.parseInt(hex, 16); |
466 |
|
((DataBase)previousElement).data.append(code); |
467 |
|
} |
468 |
|
|
469 |
|
public void end(String qName) |
470 |
{ |
{ |
|
elt.characters(ch, start, length); |
|
471 |
} |
} |
472 |
} |
} |
473 |
|
|
474 |
|
/* |
475 |
|
* This is specific to some elements which are both presents as an identity element |
476 |
|
* and as a list element. We use the context to chose the right parsing element to use. |
477 |
|
*/ |
478 |
class ListOrGroup extends ParserElement |
class ListOrGroup extends ParserElement |
479 |
{ |
{ |
480 |
List list; |
List list; |
498 |
} |
} |
499 |
|
|
500 |
public void end(String qName) |
public void end(String qName) |
501 |
|
throws SAXException |
502 |
{ |
{ |
503 |
elt.end(qName); |
elt.end(qName); |
504 |
} |
} |
526 |
allElements.put("script", new ListOrGroup()); |
allElements.put("script", new ListOrGroup()); |
527 |
|
|
528 |
allElements.put("languages", new GroupList()); |
allElements.put("languages", new GroupList()); |
529 |
allElements.put("language", new Language()); |
allElements.put("language", new ListOrGroup()); |
530 |
|
|
531 |
allElements.put("scripts", new GroupList()); |
allElements.put("scripts", new GroupList()); |
532 |
|
|
533 |
allElements.put("variants", new GroupList()); |
allElements.put("variants", new GroupList()); |
534 |
allElements.put("variant", new Language()); |
allElements.put("variant", new ListOrGroup()); |
535 |
|
|
536 |
allElements.put("keys", new GroupList()); |
allElements.put("keys", new GroupList()); |
537 |
allElements.put("key", new List()); |
allElements.put("key", new List()); |
596 |
allElements.put("layout", new Ignore()); |
allElements.put("layout", new Ignore()); |
597 |
allElements.put("special", new Ignore()); |
allElements.put("special", new Ignore()); |
598 |
|
|
599 |
allElements.put("collations", new Group()); |
allElements.put("collations", new Collations()); |
600 |
allElements.put("collation", new Group()); |
allElements.put("collation", new DetailedList()); |
601 |
allElements.put("rules", new GroupOrderedList()); |
allElements.put("rules", new GroupOrderedList()); |
602 |
allElements.put("base", new Ignore()); |
allElements.put("base", new Group()); |
603 |
|
allElements.put("reset", new Reset()); |
604 |
allElements.put("p", new OrderedList()); |
allElements.put("p", new OrderedList()); |
605 |
allElements.put("pc", new OrderedList()); |
allElements.put("pc", new OrderedList()); |
606 |
allElements.put("s", new OrderedList()); |
allElements.put("s", new OrderedList()); |
610 |
allElements.put("i", new OrderedList()); |
allElements.put("i", new OrderedList()); |
611 |
allElements.put("ic", new OrderedList()); |
allElements.put("ic", new OrderedList()); |
612 |
allElements.put("settings", new Data()); |
allElements.put("settings", new Data()); |
613 |
|
allElements.put("x", new Expansion()); |
614 |
|
allElements.put("extend", new Data()); |
615 |
|
|
616 |
|
allElements.put("first_tertiary_ignorable", new Group()); |
617 |
|
allElements.put("first_secondary_ignorable", new Group()); |
618 |
|
allElements.put("first_primary_ignorable", new Group()); |
619 |
|
allElements.put("last_tertiary_ignorable", new Group()); |
620 |
|
allElements.put("last_secondary_ignorable", new Group()); |
621 |
|
allElements.put("last_primary_ignorable", new Group()); |
622 |
|
allElements.put("last_variable", new Group()); |
623 |
|
allElements.put("last_non_ignorable", new Group()); |
624 |
|
|
625 |
allElements.put("timeZoneNames", new GroupList()); |
allElements.put("timeZoneNames", new GroupList()); |
626 |
allElements.put("zone", new DetailedList()); |
allElements.put("zone", new DetailedList()); |
634 |
allElements.put("territories", new GroupList()); |
allElements.put("territories", new GroupList()); |
635 |
|
|
636 |
allElements.put("supplementalData", new Ignore()); |
allElements.put("supplementalData", new Ignore()); |
637 |
|
|
638 |
|
allElements.put("cp", new CP()); |
639 |
} |
} |
640 |
|
|
641 |
public Element getParentElement() |
public Element getParentElement() |
643 |
return parentElement; |
return parentElement; |
644 |
} |
} |
645 |
|
|
646 |
public void setName(String name) |
public void setURL(URL url) |
647 |
{ |
{ |
648 |
this.name = name; |
this.url = url; |
649 |
} |
} |
650 |
|
|
651 |
public String getName() |
public URL getURL() |
652 |
{ |
{ |
653 |
return name; |
return url; |
654 |
} |
} |
655 |
|
|
656 |
public void setURL(URL url) |
public void setName(String name) |
657 |
{ |
{ |
658 |
this.url = url; |
this.name = name; |
659 |
} |
} |
660 |
|
|
661 |
public URL getURL() |
public String getName() |
662 |
{ |
{ |
663 |
return url; |
return name; |
664 |
} |
} |
665 |
|
|
666 |
/* |
/* |
729 |
|
|
730 |
public void characters(char[] ch, int start, int length) |
public void characters(char[] ch, int start, int length) |
731 |
{ |
{ |
732 |
currentElement.characters(ch, start, length); |
if (currentElement != null) |
733 |
|
{ |
734 |
|
currentElement.characters(ch, start, length); |
735 |
|
} |
736 |
} |
} |
737 |
|
|
738 |
|
|