KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > celtix > configuration > impl > TypeSchema


1 package org.objectweb.celtix.configuration.impl;
2
3
4 import java.io.File JavaDoc;
5 import java.io.IOException JavaDoc;
6 import java.io.InputStream JavaDoc;
7 import java.io.Reader JavaDoc;
8 import java.net.MalformedURLException JavaDoc;
9 import java.net.URI JavaDoc;
10 import java.net.URISyntaxException JavaDoc;
11 import java.net.URL JavaDoc;
12 import java.util.Collection JavaDoc;
13 import java.util.HashMap JavaDoc;
14 import java.util.Map JavaDoc;
15 import java.util.logging.Level JavaDoc;
16 import java.util.logging.Logger JavaDoc;
17
18 import javax.xml.XMLConstants JavaDoc;
19 import javax.xml.bind.JAXBContext;
20 import javax.xml.bind.JAXBElement;
21 import javax.xml.bind.JAXBException;
22 import javax.xml.bind.Unmarshaller;
23 import javax.xml.namespace.QName JavaDoc;
24 import javax.xml.parsers.DocumentBuilder JavaDoc;
25 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
26 import javax.xml.parsers.ParserConfigurationException JavaDoc;
27 import javax.xml.transform.Source JavaDoc;
28 import javax.xml.transform.dom.DOMSource JavaDoc;
29 import javax.xml.validation.Schema JavaDoc;
30 import javax.xml.validation.SchemaFactory JavaDoc;
31 import javax.xml.validation.Validator JavaDoc;
32
33 import org.w3c.dom.Document JavaDoc;
34 import org.w3c.dom.Element JavaDoc;
35 import org.w3c.dom.Node JavaDoc;
36 import org.w3c.dom.ls.LSInput JavaDoc;
37 import org.w3c.dom.ls.LSResourceResolver JavaDoc;
38
39 import org.xml.sax.ErrorHandler JavaDoc;
40 import org.xml.sax.InputSource JavaDoc;
41 import org.xml.sax.SAXException JavaDoc;
42 import org.xml.sax.SAXParseException JavaDoc;
43
44 import org.objectweb.celtix.common.i18n.Message;
45 import org.objectweb.celtix.common.logging.LogUtils;
46 import org.objectweb.celtix.configuration.ConfigurationException;
47 import org.objectweb.celtix.configuration.ConfigurationItemMetadata;
48 import org.objectweb.celtix.jaxb.JAXBUtils;
49 import org.objectweb.celtix.resource.DefaultResourceManager;
50
51 public class TypeSchema {
52
53     static final Logger JavaDoc LOG = LogUtils.getL7dLogger(TypeSchema.class);
54     
55     private Schema JavaDoc schema;
56     private Validator JavaDoc validator;
57     private final String JavaDoc namespaceURI;
58     private String JavaDoc packageName;
59     private final Map JavaDoc<String JavaDoc, QName JavaDoc> elementDefinitions;
60     private final Map JavaDoc<String JavaDoc, String JavaDoc> typeDefinitions;
61     private final boolean forceDefaults;
62     
63     /**
64      * prevent instantiation
65      */

66     protected TypeSchema(String JavaDoc nsuri, String JavaDoc baseURI, String JavaDoc location, Boolean JavaDoc fd) {
67         forceDefaults = fd;
68         namespaceURI = nsuri;
69         elementDefinitions = new HashMap JavaDoc<String JavaDoc, QName JavaDoc>();
70         typeDefinitions = new HashMap JavaDoc<String JavaDoc, String JavaDoc>();
71         
72         LOG.fine("Creating type schema for namespace " + namespaceURI);
73
74         InputSource JavaDoc is = getSchemaInputSource(baseURI, location);
75
76         Document JavaDoc document = null;
77         try {
78             DocumentBuilderFactory JavaDoc factory = DocumentBuilderFactory.newInstance();
79             factory.setNamespaceAware(true);
80             DocumentBuilder JavaDoc parser = factory.newDocumentBuilder();
81             document = parser.parse(is);
82         } catch (ParserConfigurationException JavaDoc ex) {
83             throw new ConfigurationException JavaDoc(new Message("PARSER_CONFIGURATION_ERROR_EXC",
84                                                          LOG, location), ex);
85         } catch (SAXException JavaDoc ex) {
86             throw new ConfigurationException JavaDoc(new Message("PARSE_ERROR_EXC", LOG), ex);
87         } catch (IOException JavaDoc ex) {
88             throw new ConfigurationException JavaDoc(new Message("FILE_OPEN_ERROR_EXC", LOG, location), ex);
89         }
90
91         deserialize(document);
92
93         Source JavaDoc src = new DOMSource JavaDoc(document);
94         src.setSystemId(is.getSystemId());
95
96         SchemaFactory JavaDoc factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
97         final LSResourceResolver JavaDoc oldResolver = factory.getResourceResolver();
98      
99         LSResourceResolver JavaDoc resolver = new LSResourceResolver JavaDoc() {
100
101             public LSInput JavaDoc resolveResource(String JavaDoc type, String JavaDoc nsURI,
102                                            String JavaDoc publicId, String JavaDoc systemId, String JavaDoc baseURI) {
103                 if (LOG.isLoggable(Level.FINE)) {
104                     LOG.fine("resolving resource type: " + type + "\n"
105                             + " namespaceURI:" + nsURI + "\n"
106                             + " publicId:" + publicId + "\n"
107                             + " systemId:" + systemId + "\n"
108                             + " baseURI:" + baseURI);
109                 }
110                 
111                 if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(type)) {
112                     LSInput JavaDoc lsi = new SchemaInput(type, nsURI, publicId, systemId, baseURI);
113                     String JavaDoc resourceName = systemId;
114                     
115                     InputSource JavaDoc src = getSchemaInputSource(baseURI, resourceName);
116                     lsi.setByteStream(src.getByteStream());
117                     lsi.setSystemId(src.getSystemId());
118                     return lsi;
119                 }
120                 return oldResolver == null ? null
121                     : oldResolver.resolveResource(type, nsURI, publicId, systemId, baseURI);
122             }
123         };
124         
125         factory.setResourceResolver(resolver);
126         try {
127             schema = factory.newSchema(src);
128         } catch (SAXException JavaDoc ex) {
129             throw new ConfigurationException JavaDoc(new Message("SCHEMA_CREATION_ERROR_EXC", LOG, location), ex);
130         }
131         document = null;
132         
133         LOG.fine("Created type schema for namespace " + namespaceURI);
134     }
135
136     public Validator JavaDoc getValidator() {
137         if (null == validator) {
138             Schema JavaDoc s = getSchema();
139             validator = s.newValidator();
140             validator.setErrorHandler(new TypeSchemaErrorHandler());
141         }
142         return validator;
143     }
144
145     public Collection JavaDoc<String JavaDoc> getTypes() {
146         return typeDefinitions.keySet();
147     }
148
149     public boolean hasType(String JavaDoc typeName) {
150         return typeDefinitions.containsKey(typeName);
151     }
152     
153     public Collection JavaDoc<String JavaDoc> getElements() {
154         return elementDefinitions.keySet();
155     }
156     
157     public boolean hasElement(String JavaDoc elementName) {
158         return elementDefinitions.containsKey(elementName);
159     }
160
161     public QName JavaDoc getDeclaredType(String JavaDoc typeName) {
162         return elementDefinitions.get(typeName);
163     }
164
165     public String JavaDoc getXMLSchemaBaseType(String JavaDoc typeName) {
166         if (!hasType(typeName)) {
167             throw new ConfigurationException JavaDoc(new Message("TYPE_NOT_DEFINED_IN_NAMESPACE_EXC", LOG,
168                                                          typeName, namespaceURI));
169                                                       
170         }
171         return typeDefinitions.get(typeName);
172     }
173
174     public String JavaDoc getPackageName() {
175         return packageName;
176     }
177
178     public Schema JavaDoc getSchema() {
179         return schema;
180     }
181     
182     public Object JavaDoc unmarshalDefaultValue(ConfigurationItemMetadata item, Element data) {
183         return unmarshalDefaultValue(item, data, false);
184     }
185
186     public Object JavaDoc unmarshalDefaultValue(ConfigurationItemMetadata item, Element data, boolean doValidate) {
187         try {
188             return unmarshal(item.getType(), data, doValidate);
189         } catch (JAXBException ex) {
190             if (forceDefaults) {
191                 Message msg = new Message("DEFAULT_VALUE_UNMARSHAL_ERROR_EXC", LOG, item.getName());
192                 throw new ConfigurationException JavaDoc(msg, ex);
193             }
194             return null;
195         }
196     }
197     
198     public Object JavaDoc unmarshal(QName JavaDoc type, Element data) throws JAXBException {
199         return unmarshal(type, data, true);
200     }
201
202     public Object JavaDoc unmarshal(QName JavaDoc type, Element data, boolean doValidate) throws JAXBException {
203         
204         if (LOG.isLoggable(Level.FINE)) {
205             LOG.fine("unmarshalling: element namespaceURI: " + data.getNamespaceURI() + "\n"
206                      + " localName: " + data.getLocalName() + "\n"
207                      + " type: " + type + "\n"
208                      + " type schema package name: " + packageName);
209         }
210         JAXBContext context = null;
211         Object JavaDoc obj = null;
212
213         context = JAXBContext.newInstance(packageName, getClass().getClassLoader());
214         Unmarshaller u = context.createUnmarshaller();
215         if (doValidate) {
216             u.setSchema(schema);
217         }
218         obj = u.unmarshal(data);
219         if (obj instanceof JAXBElement<?>) {
220             JAXBElement<?> el = (JAXBElement<?>)obj;
221             obj = el.getValue();
222             /*
223              * if (el.getName().equals(type)) { obj = el.getValue(); }
224              */

225         }
226
227         if (null != obj && LOG.isLoggable(Level.FINE)) {
228             LOG.fine("Unmarshaled default value into object of type: " + obj.getClass().getName()
229                      + " value: " + obj);
230         }
231         return obj;
232     }
233
234     private void deserialize(Document JavaDoc document) {
235         deseralizePackageName(document);
236         deserializeTypes(document);
237         deserializeElements(document);
238     }
239
240     private void deserializeElements(Document JavaDoc document) {
241         Element root = document.getDocumentElement();
242         for (Node JavaDoc nd = root.getFirstChild(); nd != null; nd = nd.getNextSibling()) {
243             if (Node.ELEMENT_NODE == nd.getNodeType() && "element".equals(nd.getLocalName())) {
244                 String JavaDoc elementName = ((Element)nd).getAttribute("name");
245
246                 QName JavaDoc type = ConfigurationMetadataUtils
247                     .elementAttributeToQName(document, (Element)nd, "type");
248
249                 elementDefinitions.put(elementName, type);
250                 if (LOG.isLoggable(Level.FINE)) {
251                     LOG.fine("Added type " + type + " for key: " + elementName);
252                 }
253             }
254         }
255     }
256
257     private void deserializeTypes(Document JavaDoc document) {
258         Element root = document.getDocumentElement();
259         for (Node JavaDoc nd = root.getFirstChild(); nd != null; nd = nd.getNextSibling()) {
260             if (Node.ELEMENT_NODE == nd.getNodeType()
261                 && ("simpleType".equals(nd.getLocalName()) || ("complexType".equals(nd.getLocalName())))) {
262
263                 String JavaDoc typeName = ((Element)nd).getAttribute("name");
264
265                 String JavaDoc baseType = null;
266                 if ("simpleType".equals(nd.getLocalName())) {
267                     baseType = getBaseType(document, typeName);
268                 }
269
270                 if (!typeDefinitions.containsKey(typeName)) {
271                     typeDefinitions.put(typeName, baseType);
272                     if (LOG.isLoggable(Level.FINE)) {
273                         LOG.fine("Added base type " + baseType + " for key: " + typeName);
274                     }
275                 }
276
277             }
278         }
279     }
280
281     private String JavaDoc getBaseType(Document JavaDoc document, String JavaDoc typeName) {
282         String JavaDoc currentType = typeName;
283         QName JavaDoc baseType;
284         do {
285             baseType = getBaseTypeInternal(document, currentType);
286             if (null == baseType) {
287                 LOG.severe(new Message("UNDEFINED_SIMPLE_TYPE_MSG", LOG, typeName).toString());
288                 return null;
289             } else if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(baseType.getNamespaceURI())) {
290                 if (LOG.isLoggable(Level.FINE)) {
291                     LOG.fine("Base type for " + typeName + ": " + baseType);
292                 }
293                 return baseType.getLocalPart();
294             } else if (!namespaceURI.equals(baseType.getNamespaceURI())) {
295                 LOG.severe(new Message("SIMPLE_TYPE_DEFINED_IN_OTHER_NAMESPACE_MSG", LOG, typeName,
296                                        namespaceURI).toString());
297                 return null;
298             }
299             currentType = baseType.getLocalPart();
300         } while (true);
301     }
302
303     private QName JavaDoc getBaseTypeInternal(Document JavaDoc document, String JavaDoc type) {
304         Element root = document.getDocumentElement();
305         Element simpleTypeElement = null;
306
307         for (Node JavaDoc nd = root.getFirstChild(); nd != null; nd = nd.getNextSibling()) {
308             if (Node.ELEMENT_NODE == nd.getNodeType() && "simpleType".equals(nd.getLocalName())
309                 && ((Element)nd).getAttribute("name").equals(type)) {
310                 simpleTypeElement = (Element)nd;
311             }
312         }
313         if (null == simpleTypeElement) {
314             return null;
315         }
316
317         for (Node JavaDoc nd = simpleTypeElement.getFirstChild(); nd != null; nd = nd.getNextSibling()) {
318             if (Node.ELEMENT_NODE == nd.getNodeType() && "restriction".equals(nd.getLocalName())) {
319                 // TODO restriction element can have base attribute OR
320
// simpleType
321
// child element. Currently we only handle the base attribute
322
// case.
323

324                 return ConfigurationMetadataUtils.elementAttributeToQName(document, (Element)nd, "base");
325             }
326         }
327         return null;
328     }
329
330     private void deseralizePackageName(Document JavaDoc document) {
331         Element root = document.getDocumentElement();
332         Element annotationElement = null;
333         for (Node JavaDoc nd = root.getFirstChild(); nd != null; nd = nd.getNextSibling()) {
334             if (Node.ELEMENT_NODE == nd.getNodeType() && "annotation".equals(nd.getLocalName())) {
335                 annotationElement = (Element)nd;
336                 break;
337             }
338         }
339         Element appInfoElement = null;
340         if (null != annotationElement) {
341             for (Node JavaDoc nd = annotationElement.getFirstChild(); nd != null; nd = nd.getNextSibling()) {
342                 if (Node.ELEMENT_NODE == nd.getNodeType() && "appinfo".equals(nd.getLocalName())) {
343                     appInfoElement = (Element)nd;
344                     break;
345                 }
346             }
347         }
348         Element schemaBindingsElement = null;
349         if (null != appInfoElement) {
350             for (Node JavaDoc nd = appInfoElement.getFirstChild(); nd != null; nd = nd.getNextSibling()) {
351                 if (Node.ELEMENT_NODE == nd.getNodeType() && "schemaBindings".equals(nd.getLocalName())) {
352                     schemaBindingsElement = (Element)nd;
353                     break;
354                 }
355             }
356         }
357         Element packageElement = null;
358         if (null != schemaBindingsElement) {
359             for (Node JavaDoc nd = schemaBindingsElement.getFirstChild(); nd != null; nd = nd.getNextSibling()) {
360                 if (Node.ELEMENT_NODE == nd.getNodeType() && "package".equals(nd.getLocalName())) {
361                     packageElement = (Element)nd;
362                     break;
363                 }
364             }
365         }
366
367         if (null != packageElement) {
368             packageName = packageElement.getAttribute("name");
369         } else {
370             packageName = JAXBUtils.namespaceURIToPackage(namespaceURI);
371         }
372
373         if (null == packageName) {
374             throw new ConfigurationException JavaDoc(new Message("MISSING_PACKAGE_NAME_EXC", LOG, namespaceURI));
375         }
376
377     }
378     
379     static InputSource JavaDoc getSchemaInputSource(String JavaDoc baseURI, String JavaDoc location) {
380         URI JavaDoc uri = null;
381         URI JavaDoc base = null;
382         URI JavaDoc resolved = null;
383         try {
384             uri = new URI JavaDoc(location);
385             if (baseURI != null) {
386                 try {
387                     base = new URI JavaDoc(baseURI);
388                     resolved = base.resolve(uri);
389                 } catch (URISyntaxException JavaDoc ex) {
390                     base = null;
391                     resolved = null;
392                 }
393             }
394         } catch (URISyntaxException JavaDoc ex) {
395             Message msg = new Message("SCHEMA_LOCATION_ERROR_EXC", LOG, location);
396             throw new ConfigurationException JavaDoc(msg, ex);
397         }
398
399         if (!uri.isAbsolute() && resolved != null && resolved.isAbsolute()) {
400             uri = resolved;
401         }
402
403         if (uri.isAbsolute()) {
404             if ("file".equals(uri.getScheme())) {
405                 String JavaDoc path = uri.getPath();
406                 if (null == path) {
407                     Message msg = new Message("FILE_OPEN_ERROR_EXC", LOG, location);
408                     throw new ConfigurationException JavaDoc(msg);
409                 }
410                 File JavaDoc file = new File JavaDoc(path);
411                 if (file.exists()) {
412                     return new InputSource JavaDoc(file.toURI().toString());
413                 }
414             } else {
415                 //TODO - other protocols like HTTP?
416
}
417         }
418         
419         // uri path is a system resource
420
URL JavaDoc url = DefaultResourceManager.instance().resolveResource(location, URL JavaDoc.class);
421         if (null != url) {
422             return new InputSource JavaDoc(url.toString());
423         }
424         
425         //ok, try URL resolving
426
if (baseURI != null) {
427             try {
428                 url = new URL JavaDoc(baseURI);
429                 url = new URL JavaDoc(url, location);
430                 InputStream JavaDoc ins = url.openStream();
431                 if (ins != null) {
432                     InputSource JavaDoc src = new InputSource JavaDoc(ins);
433                     src.setSystemId(url.toString());
434                     return src;
435                 }
436             } catch (MalformedURLException JavaDoc e) {
437                 //ignore
438
} catch (IOException JavaDoc e) {
439                 //ignore
440
}
441         }
442         
443         /*
444         System.out.println(baseURI);
445         System.out.println(location);
446         System.out.println(uri);
447         if (baseURI != null) {
448             System.out.println(base);
449             System.out.println(resolved);
450         }
451         */

452         
453         throw new ConfigurationException JavaDoc(new Message("SCHEMA_LOCATION_ERROR_EXC", LOG, location));
454     }
455
456     // ErrorHandler interface
457

458     static class TypeSchemaErrorHandler implements ErrorHandler JavaDoc {
459
460         public void error(SAXParseException JavaDoc exception) throws SAXParseException JavaDoc {
461             throw exception;
462         }
463
464         public void fatalError(SAXParseException JavaDoc exception) throws SAXParseException JavaDoc {
465             throw exception;
466         }
467
468         public void warning(SAXParseException JavaDoc exception) throws SAXParseException JavaDoc {
469             throw exception;
470         }
471     }
472     
473     static final class SchemaInput implements LSInput JavaDoc {
474         String JavaDoc type;
475         String JavaDoc namespaceURI;
476         String JavaDoc publicId;
477         String JavaDoc systemId;
478         String JavaDoc baseURI;
479         InputStream JavaDoc is;
480         
481         SchemaInput(String JavaDoc t, String JavaDoc nsuri, String JavaDoc pid, String JavaDoc sid, String JavaDoc buri) {
482             type = t;
483             namespaceURI = nsuri;
484             publicId = pid;
485             systemId = sid;
486             baseURI = buri;
487         }
488         
489         public String JavaDoc getBaseURI() {
490             return baseURI;
491         }
492
493         public InputStream JavaDoc getByteStream() {
494             return is;
495         }
496
497         public boolean getCertifiedText() {
498             return false;
499         }
500
501         public Reader JavaDoc getCharacterStream() {
502             return null;
503         }
504
505         public String JavaDoc getEncoding() {
506             return null;
507         }
508
509         public String JavaDoc getPublicId() {
510             return publicId;
511         }
512
513         public String JavaDoc getStringData() {
514             return null;
515         }
516
517         public String JavaDoc getSystemId() {
518             return systemId;
519         }
520
521         public void setBaseURI(String JavaDoc buri) {
522             baseURI = buri;
523         }
524
525         public void setByteStream(InputStream JavaDoc byteStream) {
526             is = byteStream;
527         }
528
529         public void setCertifiedText(boolean certifiedText) {
530         }
531
532         public void setCharacterStream(Reader JavaDoc characterStream) {
533         }
534
535         public void setEncoding(String JavaDoc encoding) {
536         }
537
538         public void setPublicId(String JavaDoc pid) {
539             publicId = pid;
540         }
541
542         public void setStringData(String JavaDoc stringData) {
543         }
544
545         public void setSystemId(String JavaDoc sid) {
546             systemId = sid;
547         }
548             
549     }
550 }
551
Popular Tags