View Javadoc

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      //Pretty print
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     //Pattern is: disjunction with an inequality on one side or the
187     //other
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 }