annotate src/luan/modules/parsers/Xml.java @ 1471:f5b8c7e1ac82

xml
author Franklin Schmidt <fschmidt@gmail.com>
date Tue, 14 Apr 2020 20:20:45 -0600
parents 35f3bfd4f51d
children 2e8a5df45d56
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1466
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
1 package luan.modules.parsers;
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
2
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
3 import java.util.Collections;
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
4 import java.util.Map;
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
5 import java.util.LinkedHashMap;
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
6 import java.util.List;
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
7 import java.util.ArrayList;
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
8 import goodjava.parser.ParseException;
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
9 import goodjava.xml.XmlElement;
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
10 import goodjava.xml.XmlParser;
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
11 import luan.Luan;
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
12 import luan.LuanTable;
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
13 import luan.LuanException;
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
14
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
15
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
16 public final class Xml {
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
17
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
18 public static String toString(LuanTable tbl) throws LuanException {
1468
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
19 XmlElement[] elements = elements(tbl);
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
20 if( elements.length != 1 )
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
21 throw new LuanException("XML must have 1 root element");
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
22 return elements[0].toString();
1466
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
23 }
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
24
1468
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
25 private static final Integer ONE = Integer.valueOf(1);
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
26 private static final Integer TWO = Integer.valueOf(2);
1471
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
27 private static final String LIST = "$list";
1468
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
28
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
29 private static XmlElement[] elements(LuanTable tbl) throws LuanException {
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
30 List<XmlElement> list = new ArrayList<XmlElement>();
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
31 for( Map.Entry entry : tbl.iterable() ) {
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
32 Object key = entry.getKey();
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
33 if( key.equals(ONE) )
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
34 continue;
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
35 if( !(key instanceof String) )
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
36 throw new LuanException("XML key must be string");
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
37 String name = (String)key;
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
38 Object value = entry.getValue();
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
39 if( value instanceof String ) {
1471
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
40 list.add( element(name,value) );
1468
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
41 } else {
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
42 LuanTable t = (LuanTable)value;
1471
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
43 LuanTable tList = (LuanTable)t.get(LIST);
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
44 if( tList == null ) {
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
45 list.add( element(name,t) );
1468
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
46 } else {
1471
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
47 for( Object obj : tList.asList() ) {
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
48 list.add( element(name,obj) );
1468
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
49 }
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
50 }
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
51 }
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
52 }
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
53 return list.toArray(new XmlElement[0]);
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
54 }
1466
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
55
1471
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
56 private static XmlElement element(String name,Object obj) throws LuanException {
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
57 if( obj instanceof String ) {
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
58 return new XmlElement( name, Collections.emptyMap(), (String)obj );
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
59 }
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
60 LuanTable t = (LuanTable)obj;
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
61 Map<String,String> attributes = attributes(t);
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
62 String s = (String)t.get(TWO);
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
63 if( s != null ) {
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
64 return new XmlElement(name,attributes,s);
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
65 } else {
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
66 XmlElement[] elements = elements(t);
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
67 if( elements.length==0 ) {
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
68 return new XmlElement(name,attributes);
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
69 } else {
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
70 return new XmlElement(name,attributes,elements);
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
71 }
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
72 }
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
73 }
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
74
1466
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
75 private static Map<String,String> attributes(LuanTable tbl) throws LuanException {
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
76 Object obj = tbl.get(ONE);
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
77 if( obj==null )
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
78 return Collections.emptyMap();
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
79 LuanTable t = (LuanTable)obj;
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
80 Map<String,String> map = new LinkedHashMap<String,String>();
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
81 for( Map.Entry entry : t.iterable() ) {
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
82 String name =(String)entry.getKey();
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
83 String value =(String)entry.getValue();
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
84 map.put(name,value);
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
85 }
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
86 return map;
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
87 }
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
88
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
89
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
90 public static LuanTable parse(Luan luan,String s) throws ParseException, LuanException {
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
91 XmlElement element = XmlParser.parse(s);
1468
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
92 LuanTable tbl = new LuanTable(luan);
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
93 addElements(tbl,new XmlElement[]{element});
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
94 return tbl;
1466
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
95 }
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
96
1468
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
97 private static LuanTable addElements(LuanTable tbl,XmlElement[] elements) throws LuanException {
1466
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
98 for( XmlElement element : elements ) {
1468
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
99 LuanTable t = new LuanTable(tbl.luan());
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
100 if( !element.attributes.isEmpty() ) {
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
101 LuanTable attrs = new LuanTable(tbl.luan());
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
102 for( Map.Entry<String,String> entry : element.attributes.entrySet() ) {
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
103 attrs.put(entry.getKey(),entry.getValue());
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
104 }
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
105 t.put( 1, attrs );
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
106 }
1471
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
107 Object value = t;
1468
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
108 if( element.content == null ) {
1471
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
109 // nothing
1468
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
110 } else if( element.content instanceof String ) {
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
111 if( t.isEmpty() ) {
1471
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
112 value = element.content;
1468
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
113 } else {
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
114 t.put( 2, element.content );
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
115 }
1466
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
116 } else {
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
117 XmlElement[] els = (XmlElement[])element.content;
1468
Franklin Schmidt <fschmidt@gmail.com>
parents: 1466
diff changeset
118 addElements(t,els);
1471
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
119 }
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
120 Object old = tbl.get(element.name);
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
121 if( old==null ) {
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
122 tbl.put(element.name,value);
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
123 } else {
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
124 LuanTable list = null;
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
125 if( old instanceof LuanTable )
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
126 list = (LuanTable)((LuanTable)old).get(LIST);
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
127 if( list==null ) {
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
128 list = new LuanTable(tbl.luan());
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
129 list.rawAdd(old);
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
130 LuanTable wrap = new LuanTable(tbl.luan());
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
131 wrap.put(LIST,list);
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
132 tbl.put(element.name,wrap);
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
133 }
Franklin Schmidt <fschmidt@gmail.com>
parents: 1468
diff changeset
134 list.rawAdd(value);
1466
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
135 }
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
136 }
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
137 return tbl;
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
138 }
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
139
670b7d089699 xml support
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
140 }