001 /*
002 * AnnotationSchema.java
003 *
004 * Copyright (c) 1995-2010, The University of Sheffield. See the file
005 * COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
006 *
007 * This file is part of GATE (see http://gate.ac.uk/), and is free
008 * software, licenced under the GNU Library General Public License,
009 * Version 2, June 1991 (in the distribution as file licence.html,
010 * and also available at http://gate.ac.uk/gate/licence.html).
011 *
012 * Cristian URSU, 27/Sept/2000
013 *
014 * $Id: AnnotationSchema.java 13142 2010-10-14 08:49:36Z markagreenwood $
015 */
016 package gate.creole;
017
018 import java.io.InputStream;
019 import java.net.URL;
020 import java.util.*;
021
022 import org.jdom.JDOMException;
023 import org.jdom.Namespace;
024 import org.jdom.input.SAXBuilder;
025
026 import gate.Resource;
027
028 /** This class handles annotation schemas.An annotation schema is a
029 * representation of an annotation, together with its types and their
030 * attributes, values and types.
031 */
032 public class AnnotationSchema extends AbstractLanguageResource{
033 public static final String FILE_URL_PARAM_NAME = "xmlFileUrl";
034
035 /** Debug flag */
036 private static final boolean DEBUG = false;
037
038 /** A map between XSchema types and Java Types */
039 private static Map<String, Class<?>> xSchema2JavaMap;
040
041 /** A map between Java types and XSchema */
042 private static Map<Class<?>, String> java2xSchemaMap;
043
044 /** This sets up two Maps between XSchema types and their coresponding
045 * Java types + a DOM xml parser
046 */
047 private static void setUpStaticData()
048 throws ResourceInstantiationException
049 {
050 xSchema2JavaMap = new HashMap<String, Class<?>>();
051 java2xSchemaMap = new HashMap<Class<?>, String>();
052
053 xSchema2JavaMap.put("string", String.class);
054 xSchema2JavaMap.put("integer", Integer.class);
055 xSchema2JavaMap.put("int", Integer.class);
056 xSchema2JavaMap.put("boolean", Boolean.class);
057 xSchema2JavaMap.put("float", Float.class);
058 xSchema2JavaMap.put("double", Double.class);
059 xSchema2JavaMap.put("short", Short.class);
060 xSchema2JavaMap.put("byte", Byte.class);
061
062 java2xSchemaMap.put(String.class, "string");
063 java2xSchemaMap.put(Integer.class, "integer");
064 java2xSchemaMap.put(Boolean.class, "boolean");
065 java2xSchemaMap.put(Float.class, "float");
066 java2xSchemaMap.put(Double.class, "double");
067 java2xSchemaMap.put(Short.class, "short");
068 java2xSchemaMap.put(Byte.class, "byte");
069 } //setUpStaticData
070
071 /** The name of the annotation */
072 protected String annotationName = null;
073
074 /** Returns the value of annotation name */
075 public String getAnnotationName(){
076 return annotationName;
077 } // getAnnotationName
078
079 /** Sets the annotation name */
080 public void setAnnotationName(String annotationName) {
081 this.annotationName = annotationName;
082 } // setAnnotationName
083
084 /** Schemas for the attributes */
085 protected Set<FeatureSchema> featureSchemaSet = null;
086
087 /** Constructs an annotation schema. */
088 public AnnotationSchema(){
089 } // AnnotationSchema
090
091 /** Returns the feature schema set */
092 public Set<FeatureSchema> getFeatureSchemaSet(){
093 return featureSchemaSet;
094 } // getAttributeSchemas
095
096 /** Sets the feature schema set */
097 public void setFeatureSchemaSet(Set<FeatureSchema> featureSchemaSet) {
098 this.featureSchemaSet = featureSchemaSet;
099 } // setFeatureSchemaSet
100
101 /** @return a FeatureSchema object from featureSchemaSet, given a
102 * feature name.It will return null if the feature name is not found.
103 */
104 public FeatureSchema getFeatureSchema(String featureName) {
105 if(featureSchemaSet == null) return null;
106 for(FeatureSchema fs : featureSchemaSet){
107 if (fs.getFeatureName().equals(featureName)) return fs;
108 }
109 return null;
110 } // getFeatureSchema
111
112 /** Initialise this resource, and return it. If the schema XML source file
113 * URL has been set, it will construct itself from that file.
114 */
115 public Resource init() throws ResourceInstantiationException {
116 // set up the static data if it's not there already
117 if(xSchema2JavaMap == null || java2xSchemaMap == null)
118 setUpStaticData();
119
120 // parse the XML file if we have its URL
121 if(xmlFileUrl != null) fromXSchema(xmlFileUrl);
122
123 return this;
124 } // init()
125
126 /** The xml file URL of the resource */
127 protected URL xmlFileUrl;
128
129 /**
130 * The namepsace used in the xml file
131 */
132 protected Namespace namespace;
133
134 /** Set method for the resource xml file URL */
135 public void setXmlFileUrl(URL xmlFileUrl) { this.xmlFileUrl = xmlFileUrl; }
136
137 /** Get method for the resource xml file URL */
138 public URL getXmlFileUrl() { return xmlFileUrl; }
139
140 /** Creates an AnnotationSchema object from an XSchema file
141 * @param anXSchemaURL the URL where to find the XSchema file
142 */
143 public void fromXSchema(URL anXSchemaURL)
144 throws ResourceInstantiationException {
145 org.jdom.Document jDom = null;
146 SAXBuilder saxBuilder = new SAXBuilder(false);
147 try {
148 try{
149 jDom = saxBuilder.build(anXSchemaURL);
150 }catch(JDOMException je){
151 throw new ResourceInstantiationException(je);
152 }
153 } catch (java.io.IOException ex) {
154 throw new ResourceInstantiationException(ex);
155 }
156 workWithJDom(jDom);
157 } // fromXSchema
158
159 /** Creates an AnnotationSchema object from an XSchema file
160 * @param anXSchemaInputStream the Input Stream containing the XSchema file
161 */
162 public void fromXSchema(InputStream anXSchemaInputStream)
163 throws ResourceInstantiationException {
164 org.jdom.Document jDom = null;
165 SAXBuilder saxBuilder = new SAXBuilder(false);
166 try {
167 try{
168 jDom = saxBuilder.build(anXSchemaInputStream);
169 }catch(JDOMException je){
170 throw new ResourceInstantiationException(je);
171 }
172 } catch (java.io.IOException ex) {
173 throw new ResourceInstantiationException(ex);
174 }
175 workWithJDom(jDom);
176 } // end fromXSchema
177
178 /** This method uses the JDom structure for our XSchema needs. What it does is
179 * to add semantics to the XML elements defined in XSchema. In the end we need
180 * to construct an AnnotationSchema object form an XSchema file.
181 *
182 * @param jDom the JDOM structure containing the XSchema document. It must not
183 * be <b>null<b>
184 */
185 private void workWithJDom(org.jdom.Document jDom){
186 // Use the jDom structure the way we want
187 org.jdom.Element rootElement = jDom.getRootElement();
188 namespace = rootElement.getNamespace();
189 // get all children elements from the rootElement
190 List rootElementChildrenList = rootElement.getChildren("element", namespace);
191 Iterator rootElementChildrenIterator = rootElementChildrenList.iterator();
192 while (rootElementChildrenIterator.hasNext()){
193 org.jdom.Element childElement =
194 (org.jdom.Element) rootElementChildrenIterator.next();
195 createAnnotationSchemaObject(childElement);
196 }//end while
197 } // workWithJdom
198
199 /** This method creates an AnnotationSchema object fom an org.jdom.Element
200 * @param anElement is an XSchema element element
201 */
202 private void createAnnotationSchemaObject(org.jdom.Element anElement){
203 // Get the value of the name attribute. If this attribute doesn't exists
204 // then it will receive a default one.
205 annotationName = anElement.getAttributeValue("name");
206 if (annotationName == null)
207 annotationName = "UnknownElement";
208 // See if this element has a complexType element inside it
209 org.jdom.Element complexTypeElement = anElement.getChild("complexType",
210 namespace);
211 if (complexTypeElement != null){
212 List complexTypeCildrenList = complexTypeElement.getChildren("attribute",
213 namespace);
214 Iterator complexTypeCildrenIterator = complexTypeCildrenList.iterator();
215 if (complexTypeCildrenIterator.hasNext())
216 featureSchemaSet = new LinkedHashSet<FeatureSchema>();
217 while (complexTypeCildrenIterator.hasNext()) {
218 org.jdom.Element childElement =
219 (org.jdom.Element) complexTypeCildrenIterator.next();
220 createAndAddFeatureSchemaObject(childElement);
221 }// end while
222 }// end if
223 } // createAnnoatationSchemaObject
224
225 /** This method creates and adds a FeatureSchema object to the current
226 * AnnotationSchema one.
227 * @param anAttributeElement is an XSchema attribute element
228 */
229 public void createAndAddFeatureSchemaObject(org.jdom.Element
230 anAttributeElement) {
231 String featureName = null;
232 Class<?> featureType = null;
233 String featureUse = null;
234 String featureValue = null;
235 Set featurePermittedValuesSet = null;
236
237 // Get the value of the name attribute. If this attribute doesn't exists
238 // then it will receive a default one.
239 featureName = anAttributeElement.getAttributeValue("name");
240 if (featureName == null)
241 featureName = "UnknownFeature";
242
243 // See if it has a type attribute associated
244 String featureTypeName = anAttributeElement.getAttributeValue("type");
245 if (featureTypeName != null)
246 // Set it to the corresponding Java type
247 featureType = xSchema2JavaMap.get(featureTypeName);
248
249 // Get the value of use attribute
250 featureUse = anAttributeElement.getAttributeValue("use");
251 if (featureUse == null)
252 // Set it to the default value
253 featureUse = "optional";
254
255 // Get the value of value attribute
256 featureValue = anAttributeElement.getAttributeValue("value");
257 if (featureValue == null)
258 featureValue = "";
259
260 // Let's check if it has a simpleType element inside
261 org.jdom.Element simpleTypeElement =
262 anAttributeElement.getChild("simpleType",
263 namespace);
264
265 // If it has (!= null) then check to see if it has a restrictionElement
266 if (simpleTypeElement != null) {
267 org.jdom.Element restrictionElement =
268 simpleTypeElement.getChild("restriction",
269 namespace);
270 if (restrictionElement != null) {
271 // Get the type attribute for restriction element
272 featureTypeName = restrictionElement.getAttributeValue("base");
273 if (featureTypeName == null) featureTypeName = "string";
274 // Set it to the corresponding Java type
275 featureType = xSchema2JavaMap.get(featureTypeName);
276
277 // Check to see if there are any enumeration elements inside
278 List enumerationElementChildrenList =
279 restrictionElement.getChildren("enumeration",
280 namespace);
281 Iterator enumerationChildrenIterator =
282 enumerationElementChildrenList.iterator();
283
284 // Check if there is any enumeration element in the list
285 if (enumerationChildrenIterator.hasNext())
286 featurePermittedValuesSet = new HashSet();
287 while (enumerationChildrenIterator.hasNext()) {
288 org.jdom.Element enumerationElement =
289 (org.jdom.Element) enumerationChildrenIterator.next();
290 String permissibleValue =
291 enumerationElement.getAttributeValue("value");
292 // Add that value to the featureSchema possible values set.
293 featurePermittedValuesSet.add(permissibleValue);
294 }// end while
295 }// end if( restrictionElement != null)
296 }// end if (simpleTypeElement != null)
297
298 // If it doesn't have a simpleTypeElement inside and featureType is null or
299 // it wasn't recognised, then we set the default type to string.
300 if (simpleTypeElement == null && featureType == null )
301 featureType = xSchema2JavaMap.get("string");
302
303 // Create an add a featureSchema object
304 FeatureSchema featureSchema = new FeatureSchema(
305 featureName,
306 featureType,
307 featureValue,
308 featureUse,
309 featurePermittedValuesSet);
310 featureSchemaSet.add(featureSchema);
311 } // createAndAddFeatureSchemaObject
312
313 /** @return a String containing the XSchema document representing
314 * an AnnotationSchema object.
315 */
316 public String toXSchema(){
317 StringBuffer schemaString = new StringBuffer();
318 schemaString.append("<?xml version=\"1.0\"?>\n" +
319 "<schema xmlns=\"http://www.w3.org/2000/10/XMLSchema\">\n"+
320 " <element name=\"" + annotationName + "\"");
321
322 if (featureSchemaSet == null)
323 schemaString.append("/>\n");
324 else {
325 schemaString.append(">\n <complexType>\n");
326 for(FeatureSchema fs : featureSchemaSet){
327 schemaString.append(fs.toXSchema(java2xSchemaMap));
328 }
329 schemaString.append(" </complexType>\n");
330 schemaString.append(" </element>\n");
331 }// end if else
332 schemaString.append("</schema>\n");
333 return schemaString.toString();
334 }// toXSchema
335 } // AnnotationSchema
336
|