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