1 package zeus.ontology;
2
3 import java.io.File;
4 import java.io.FileWriter;
5 import java.io.Writer;
6 import java.io.IOException;
7
8 import java.util.List;
9 import java.util.Enumeration;
10 import java.util.Vector;
11 import java.util.Iterator;
12 import java.util.HashMap;
13
14 public class SchemaWriter {
15
16 private HashMap namespaces;
17
18 private String defaultNamespace;
19
20 private boolean override;
21
22 public SchemaWriter() {
23 namespaces = new HashMap();
24 namespaces.put("xsd", "http://www.w3.org/2001/XMLSchema");
25 setDefaultNamespace("xsd");
26 }
27
28 public void writeRestrictions(File types, List restrictions) {
29
30 String output = makeSchema(restrictions);
31
32 try {
33 Writer writer = new FileWriter(types);
34 writer.write(output);
35 writer.close();
36 }
37 catch(IOException i) {
38 System.out.println(i);
39 }
40
41 }
42
43 /***
44 * Also used by service renderers, be aware when modifying.
45 */
46 public String makeSchema(List restrictions) {
47
48 String output = "<?xml version='1.0' encoding='ISO-8859-1'?>\n\n";
49
50 output += "<xsd:schema ";
51
52 output += getNamespaces();
53
54 output += ">\n";
55
56 for(Iterator i = restrictions.iterator() ; i.hasNext() ; ) {
57 String[] item = (String[])i.next();
58 output += translateType(item[0], item[1], item[2]);
59 }
60
61 output += "</xsd:schema>\n";
62
63
64 output = zeus.util.XMLFormatter.formatXML(output);
65
66 return output;
67 }
68
69 private String translateType(String typeName, String base, String value) {
70
71 String output = "";
72
73 output += "<xsd:simpleType";
74 if(typeName != null && !typeName.equals("")) {
75 output += " name=\"" + typeName + "\" ";
76 }
77 output += ">\n";
78
79 output += translateRestriction(base, value);
80
81 output += "</xsd:simpleType>\n";
82
83 return output;
84 }
85
86 private String translateRestriction(String type, String restriction) {
87 String output = "";
88
89 if(restriction.matches("((.*[<>].*//|.*)|(.*//|.*[<>].*))")) {
90 return union(type, restriction);
91 }
92
93 output += "<xsd:restriction";
94
95 if(type != null && getType(type) != null) {
96 output += " base=\"" + getType(type) + "\" ";
97 }
98
99 output += ">\n";
100
101 output += parseRestriction(restriction);
102
103 output += "</xsd:restriction>\n";
104
105 return output;
106 }
107
108 private String getType(String type) {
109
110 if(override) {
111 return defaultNamespace + ":" + type;
112 }
113
114 if(type.toLowerCase().equals("string")) {
115 return "xsd:string";
116 }
117 else if(type.toLowerCase().equals("integer")) {
118 return "xsd:integer";
119 }
120 else if(type.toLowerCase().equals("real")) {
121 return "xsd:real";
122 }
123 else if(type.toLowerCase().equals("boolean")) {
124 return "xsd:boolean";
125 }
126 else if(type.toLowerCase().equals("date")) {
127 return "xsd:date";
128 }
129 else if(type.toLowerCase().equals("time")) {
130 return "xsd:time";
131 }
132 else {
133 return defaultNamespace + ":" + type.toLowerCase();
134 }
135 }
136
137 private String parseRestriction(String value) {
138
139 if(value == null || value.equals("")) {
140 return "";
141 }
142 value = value.trim();
143
144 if(value.matches(".*//|.*")) {
145 String pt1 = parseRestriction(getLHS(value, "|"));
146 String pt2 = parseRestriction(getRHS(value, "|"));
147 return pt1 + pt2;
148 }
149 else if(value.matches(".*&.*")) {
150 String pt1 = parseRestriction(getLHS(value, "&"));
151 String pt2 = parseRestriction(getRHS(value, "&"));
152 return pt1 + pt2;
153 }
154 else if(value.matches(".*>=.*")) {
155 return "<xsd:minInclusive value=\"" + getRHS(value, ">=") + "\" />\n";
156 }
157 else if(value.matches(".*<=.*")) {
158 return "<xsd:maxInclusive value=\"" + getRHS(value, "<=") + "\" />\n";
159 }
160 else if(value.matches(".*>.*")) {
161 return "<xsd:minExclusive value=\"" + getRHS(value, ">") + "\" />\n";
162 }
163 else if(value.matches(".*<.*")) {
164 return "<xsd:maxExclusive value=\"" + getRHS(value, "<") + "\" />\n";
165 }
166 else if(value.matches(".*=.*")) {
167 return "<xsd:enumeration value=\"" + getRHS(value, "=") + "\" />\n";
168 }
169 else if(value.matches("..*")) {
170 return "<xsd:enumeration value=\"" + value + "\" />\n";
171 }
172
173 return "";
174 }
175
176 private String getLHS(String target, String search) {
177 return target.substring(0, target.indexOf(search)).trim();
178 }
179
180 private String getRHS(String target, String search) {
181 return target.substring(target.indexOf(search) + search.length()).trim();
182 }
183
184 private String union(String type, String value) {
185
186
187
188 if(!value.matches("((.*[<>].*//|.*)|(.*//|.*[<>].*))")) {
189 return parseRestriction(value);
190 }
191
192 String output = "";
193
194 output += "<xsd:union>\n";
195
196 output += translateType(null, type, getLHS(value, "|"));
197 output += translateType(null, type, getRHS(value, "|"));
198
199 output += "</xsd:union>\n";
200
201 return output;
202 }
203
204 private String getNamespaces() {
205 String output = "";
206
207 for(Iterator i = namespaces.keySet().iterator() ; i.hasNext() ; ) {
208 String key = (String)i.next();
209 output += "xmlns:" + key + "=\"" + namespaces.get(key) + "\"\n";
210 }
211
212 return output.trim();
213 }
214
215 public void setDefaultNamespace(String key) {
216 if(namespaces.keySet().contains(key)) {
217 defaultNamespace = key;
218 }
219 }
220
221 public void addNamespace(String key, String namespace) {
222 if(key != null && namespace != null && !key.equals("xsd")) {
223 namespaces.put(key, namespace);
224 }
225 }
226
227 public void enableOverrideNamespaces() {
228 override = true;
229 }
230
231 public void disableOverrideNamespaces() {
232 override = false;
233 }
234
235 }