KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > xb > binding > parser > xni > XniJBossXBParser


1 /*
2  * JBoss, the OpenSource J2EE webOS
3  *
4  * Distributable under LGPL license.
5  * See terms of license at gnu.org.
6  */

7 package org.jboss.xb.binding.parser.xni;
8
9 import org.jboss.xb.binding.parser.JBossXBParser;
10 import org.jboss.xb.binding.JBossXBException;
11 import org.jboss.xb.binding.Unmarshaller;
12 import org.jboss.xb.binding.AttributesImpl;
13 import org.jboss.logging.Logger;
14 import org.apache.xerces.parsers.IntegratedParserConfiguration;
15 import org.apache.xerces.parsers.XMLDocumentParser;
16 import org.apache.xerces.util.SymbolTable;
17 import org.apache.xerces.xni.grammars.XMLGrammarPool;
18 import org.apache.xerces.xni.parser.XMLComponentManager;
19 import org.apache.xerces.xni.parser.XMLParserConfiguration;
20 import org.apache.xerces.xni.parser.XMLErrorHandler;
21 import org.apache.xerces.xni.parser.XMLParseException;
22 import org.apache.xerces.xni.parser.XMLInputSource;
23 import org.apache.xerces.xni.parser.XMLEntityResolver;
24 import org.apache.xerces.xni.XNIException;
25 import org.apache.xerces.xni.NamespaceContext;
26 import org.apache.xerces.xni.XMLLocator;
27 import org.apache.xerces.xni.Augmentations;
28 import org.apache.xerces.xni.XMLAttributes;
29 import org.apache.xerces.xni.XMLString;
30 import org.apache.xerces.xni.QName;
31 import org.apache.xerces.xni.XMLResourceIdentifier;
32 import org.apache.xerces.impl.xs.XSMessageFormatter;
33 import org.apache.xerces.impl.xs.JBossXBSchemaValidator;
34 import org.apache.xerces.xs.XSElementDeclaration;
35 import org.apache.xerces.xs.XSTypeDefinition;
36 import org.xml.sax.EntityResolver JavaDoc;
37 import org.xml.sax.SAXException JavaDoc;
38 import org.xml.sax.InputSource JavaDoc;
39
40 import java.io.Reader JavaDoc;
41 import java.io.IOException JavaDoc;
42 import java.io.InputStream JavaDoc;
43
44
45 /**
46  * @author <a HREF="mailto:alex@jboss.org">Alexey Loubyansky</a>
47  * @version <tt>$Revision: 1.1.2.1 $</tt>
48  */

49 public class XniJBossXBParser
50    implements JBossXBParser
51 {
52    private static final Logger log = Logger.getLogger(XniJBossXBParser.class);
53    private final XMLParserConfiguration config;
54    private final DocumentParser parser;
55    private JBossXBParser.ContentHandler contentHandler;
56
57    public XniJBossXBParser()
58    {
59       config = new ParserConfiguration();
60       parser = new DocumentParser(config);
61
62       config.setErrorHandler(new XMLErrorHandler()
63       {
64          public void warning(String JavaDoc domain, String JavaDoc key, XMLParseException exception) throws XNIException
65          {
66             log.warn("domain=" + domain + ", key=" + key + ": " + exception.getMessage());
67          }
68
69          public void error(String JavaDoc domain, String JavaDoc key, XMLParseException exception) throws XNIException
70          {
71             log.error("domain=" + domain + ", key=" + key + ": " + exception.getMessage());
72             throw exception;
73          }
74
75          public void fatalError(String JavaDoc domain, String JavaDoc key, XMLParseException exception) throws XNIException
76          {
77             log.error("domain=" + domain + ", key=" + key + ": " + exception.getMessage());
78             throw exception;
79          }
80       }
81       );
82
83       config.setFeature(Unmarshaller.NAMESPACES, true);
84       config.setFeature(Unmarshaller.VALIDATION, true);
85       config.setFeature(Unmarshaller.SCHEMA_VALIDATION, true);
86       config.setFeature(Unmarshaller.SCHEMA_FULL_CHECKING, true);
87       config.setFeature(Unmarshaller.DYNAMIC_VALIDATION, true);
88    }
89
90    public void setEntityResolver(final EntityResolver entityResolver) throws JBossXBException
91    {
92       config.setEntityResolver(new XMLEntityResolver()
93       {
94          private EntityResolver resolver;
95
96          {
97             this.resolver = entityResolver;
98          }
99
100          public XMLInputSource resolveEntity(XMLResourceIdentifier resId) throws XNIException,
101             IOException JavaDoc
102          {
103             XMLInputSource result;
104             try
105             {
106                InputSource source = resolver.resolveEntity(resId.getPublicId(), resId.getExpandedSystemId());
107                if(source != null)
108                {
109                   if(source.getCharacterStream() != null)
110                   {
111                      result = new XMLInputSource(resId.getPublicId(),
112                         resId.getExpandedSystemId(),
113                         resId.getBaseSystemId(),
114                         source.getCharacterStream(),
115                         source.getEncoding()
116                      );
117                   }
118                   else if(source.getByteStream() != null)
119                   {
120                      result = new XMLInputSource(resId.getPublicId(),
121                         resId.getExpandedSystemId(),
122                         resId.getBaseSystemId(),
123                         source.getByteStream(),
124                         source.getEncoding()
125                      );
126                   }
127                   else if(source.getSystemId() != null)
128                   {
129                      result = new XMLInputSource(resId.getPublicId(), source.getSystemId(), resId.getBaseSystemId());
130                   }
131                   else
132                   {
133                      throw new IllegalStateException JavaDoc(
134                         "Resolved source contains no about the source, i.e. systemId, byte stream and character stream are all null."
135                      );
136                   }
137                }
138                else
139                {
140                   result = null;
141                }
142             }
143             catch(SAXException JavaDoc e)
144             {
145                throw new XNIException("Failed to resolve entity: publicId=" +
146                   resId.getPublicId() +
147                   ", literal systemId=" +
148                   resId.getLiteralSystemId() +
149                   ", base systemId=" +
150                   resId.getBaseSystemId()
151                   + ", expanded systemId=" + resId.getExpandedSystemId()
152                );
153             }
154             return result;
155          }
156       }
157       );
158    }
159
160    public void setProperty(String JavaDoc name, Object JavaDoc value) throws JBossXBException
161    {
162       config.setProperty(name, value);
163    }
164
165    public void setFeature(String JavaDoc name, boolean value) throws JBossXBException
166    {
167       config.setFeature(name, value);
168    }
169
170    public void parse(String JavaDoc systemId, ContentHandler handler) throws JBossXBException
171    {
172       this.contentHandler = handler;
173
174       XMLInputSource xmlSource = new XMLInputSource(null, systemId, null);
175       try
176       {
177          parser.parse(xmlSource);
178       }
179       catch(Exception JavaDoc e)
180       {
181          throw new JBossXBException("Failed to parse document " + systemId, e);
182       }
183    }
184
185    public void parse(InputStream JavaDoc is, ContentHandler handler) throws JBossXBException
186    {
187       this.contentHandler = handler;
188
189       XMLInputSource xmlSource = new XMLInputSource(null, null, null, is, null);//todo encoding?
190
try
191       {
192          parser.parse(xmlSource);
193       }
194       catch(Exception JavaDoc e)
195       {
196          throw new JBossXBException("Failed to parse document", e);
197       }
198    }
199
200    public void parse(Reader JavaDoc reader, ContentHandler handler) throws JBossXBException
201    {
202       this.contentHandler = handler;
203
204       XMLInputSource xmlSource = new XMLInputSource(null, null, null, reader, null);//todo encoding?
205
try
206       {
207          parser.parse(xmlSource);
208       }
209       catch(Exception JavaDoc e)
210       {
211          throw new JBossXBException("Failed to parse document", e);
212       }
213    }
214
215    // Inner
216

217    class DocumentParser
218       extends XMLDocumentParser
219    {
220       private boolean namespaces;
221       private boolean prefixes;
222       private NamespaceContext namespaceContext;
223       private QName qName = new QName();
224       private SAXAttributes saxAttrs = new SAXAttributes();
225
226       public DocumentParser(XMLParserConfiguration config)
227       {
228          super(config);
229          namespaces = config.getFeature(Unmarshaller.NAMESPACES);
230          //prefixes = config.getFeature(Unmarshaller.NAMESPACE_PREFIXES);
231
prefixes = false;
232       }
233
234       public void startDocument(XMLLocator locator, String JavaDoc encoding,
235                                 NamespaceContext namespaceContext,
236                                 Augmentations augs)
237          throws XNIException
238       {
239          this.namespaceContext = namespaceContext;
240       }
241
242       public void xmlDecl(String JavaDoc version, String JavaDoc encoding, String JavaDoc standalone, Augmentations augs)
243          throws XNIException
244       {
245       }
246
247       public void doctypeDecl(String JavaDoc rootElement, String JavaDoc publicId, String JavaDoc systemId, Augmentations augs)
248          throws XNIException
249       {
250       }
251
252       public void comment(XMLString text, Augmentations augs) throws XNIException
253       {
254       }
255
256       public void processingInstruction(String JavaDoc target, XMLString data, Augmentations augs)
257          throws XNIException
258       {
259       }
260
261       public void startElement(QName name, XMLAttributes attributes, Augmentations augs)
262          throws XNIException
263       {
264          XSTypeDefinition type = null;
265          if(augs != null)
266          {
267             JBossXBSchemaValidator validator = (JBossXBSchemaValidator)augs.getItem("jbossxb.validator");
268             if(validator != null)
269             {
270                XSElementDeclaration element = validator.getCurrentElementDelcaration();
271                type = element.getTypeDefinition();
272             }
273          }
274
275          if(type == null)
276          {
277             if(log.isTraceEnabled())
278             {
279                log.trace("Type is not available for " + name.rawname);
280             }
281          }
282
283          if(namespaces)
284          {
285             int count = startNamespaceMapping();
286
287             // If there were no new namespaces declared then we can skip searching
288
// the attribute list for namespace declarations. Otherwise, remove namespace declaring attributes
289
if(count > 0)
290             {
291                int len = attributes.getLength();
292                for(int i = len - 1; i >= 0; i--)
293                {
294                   attributes.getName(i, qName);
295
296                   if((qName.prefix != null && qName.prefix.equals("xmlns")) ||
297                      qName.rawname.equals("xmlns"))
298                   {
299                      if(!prefixes)
300                      {
301                         attributes.removeAttributeAt(i);
302                      }
303                      else
304                      {
305                         // localpart should be empty string as per SAX documentation:
306
// http://www.saxproject.org/?selected=namespaces
307
qName.prefix = "";
308                         qName.uri = "";
309                         qName.localpart = "";
310                         attributes.setName(i, qName);
311                      }
312                   }
313                }
314             }
315          }
316
317          String JavaDoc uri = name.uri != null ? name.uri : "";
318          String JavaDoc localpart = namespaces ? name.localpart : "";
319          saxAttrs.setAttrs(attributes);
320          contentHandler.startElement(uri, localpart, name.rawname, saxAttrs, type);
321       }
322 /*
323       public void emptyElement(QName element, XMLAttributes attributes, Augmentations augs)
324          throws XNIException
325       {
326          AttributesImpl attrs = toSaxAttributes(attributes);
327          contentHandler.startElement(element.uri, element.localpart, element.rawname, attrs);
328       }
329 */

330       public void startGeneralEntity(String JavaDoc name,
331                                      XMLResourceIdentifier identifier,
332                                      String JavaDoc encoding,
333                                      Augmentations augs) throws XNIException
334       {
335       }
336
337       public void textDecl(String JavaDoc version, String JavaDoc encoding, Augmentations augs) throws XNIException
338       {
339       }
340
341       public void endGeneralEntity(String JavaDoc name, Augmentations augs) throws XNIException
342       {
343       }
344
345       public void characters(XMLString text, Augmentations augs) throws XNIException
346       {
347          // todo look at this later
348
// do not notify content handler if these are just whitespaces
349
int i = text.offset;
350          while(i < text.offset + text.length)
351          {
352             if(!Character.isWhitespace(text.ch[i++]))
353             {
354                contentHandler.characters(text.ch, text.offset, text.length);
355                break;
356             }
357          }
358       }
359
360       public void ignorableWhitespace(XMLString text, Augmentations augs) throws XNIException
361       {
362       }
363
364       public void endElement(QName element, Augmentations augs) throws XNIException
365       {
366          String JavaDoc uri = element.uri != null ? element.uri : "";
367          String JavaDoc localpart = namespaces ? element.localpart : "";
368          contentHandler.endElement(uri, localpart, element.rawname);
369       }
370
371       public void startCDATA(Augmentations augs) throws XNIException
372       {
373       }
374
375       public void endCDATA(Augmentations augs) throws XNIException
376       {
377       }
378
379       public void endDocument(Augmentations augs) throws XNIException
380       {
381          super.endDocument(augs);
382       }
383
384       // Private
385

386       protected final int startNamespaceMapping()
387       {
388          int count = namespaceContext.getDeclaredPrefixCount();
389          if(count > 0)
390          {
391             String JavaDoc prefix = null;
392             String JavaDoc uri = null;
393             for(int i = 0; i < count; i++)
394             {
395                prefix = namespaceContext.getDeclaredPrefixAt(i);
396                uri = namespaceContext.getURI(prefix);
397                contentHandler.startPrefixMapping(prefix, (uri == null) ? "" : uri);
398             }
399          }
400          return count;
401       }
402
403       private AttributesImpl toSaxAttributes(XMLAttributes attributes)
404       {
405          AttributesImpl attrs = null;
406          if(attributes != null)
407          {
408             attrs = new AttributesImpl(attributes.getLength());
409             for(int i = 0; i < attributes.getLength(); ++i)
410             {
411                if(!"xmlns".equals(attributes.getPrefix(i)))
412                {
413                   attrs.add(attributes.getURI(i),
414                      attributes.getLocalName(i),
415                      attributes.getQName(i),
416                      attributes.getType(i),
417                      attributes.getValue(i)
418                   );
419                }
420             }
421          }
422          return attrs;
423       }
424    }
425
426    class ParserConfiguration
427       extends IntegratedParserConfiguration
428    {
429       public ParserConfiguration()
430       {
431       }
432
433       public ParserConfiguration(SymbolTable symbolTable)
434       {
435          super(symbolTable);
436       }
437
438       public ParserConfiguration(SymbolTable symbolTable, XMLGrammarPool grammarPool)
439       {
440          super(symbolTable, grammarPool);
441       }
442
443       public ParserConfiguration(SymbolTable symbolTable,
444                                  XMLGrammarPool grammarPool,
445                                  XMLComponentManager parentSettings)
446       {
447          super(symbolTable, grammarPool, parentSettings);
448       }
449
450       protected void configurePipeline()
451       {
452          // use XML 1.0 datatype library
453
setProperty(DATATYPE_VALIDATOR_FACTORY, fDatatypeValidatorFactory);
454
455          // setup DTD pipeline
456
configureDTDPipeline();
457
458          // setup document pipeline
459
if(fFeatures.get(NAMESPACES) == Boolean.TRUE)
460          {
461             fProperties.put(NAMESPACE_BINDER, fNamespaceBinder);
462             fScanner = fNamespaceScanner;
463             fProperties.put(DOCUMENT_SCANNER, fNamespaceScanner);
464             if(fDTDValidator != null)
465             {
466                fProperties.put(DTD_VALIDATOR, fDTDValidator);
467                fNamespaceScanner.setDTDValidator(fDTDValidator);
468                fNamespaceScanner.setDocumentHandler(fDTDValidator);
469                fDTDValidator.setDocumentSource(fNamespaceScanner);
470                fDTDValidator.setDocumentHandler(fDocumentHandler);
471                if(fDocumentHandler != null)
472                {
473                   fDocumentHandler.setDocumentSource(fDTDValidator);
474                }
475                fLastComponent = fDTDValidator;
476             }
477             else
478             {
479                fNamespaceScanner.setDocumentHandler(fDocumentHandler);
480                fNamespaceScanner.setDTDValidator(null);
481                if(fDocumentHandler != null)
482                {
483                   fDocumentHandler.setDocumentSource(fNamespaceScanner);
484                }
485                fLastComponent = fNamespaceScanner;
486             }
487          }
488          else
489          {
490             fScanner = fNonNSScanner;
491             fProperties.put(DOCUMENT_SCANNER, fNonNSScanner);
492             if(fNonNSDTDValidator != null)
493             {
494                fProperties.put(DTD_VALIDATOR, fNonNSDTDValidator);
495                fNonNSScanner.setDocumentHandler(fNonNSDTDValidator);
496                fNonNSDTDValidator.setDocumentSource(fNonNSScanner);
497                fNonNSDTDValidator.setDocumentHandler(fDocumentHandler);
498                if(fDocumentHandler != null)
499                {
500                   fDocumentHandler.setDocumentSource(fNonNSDTDValidator);
501                }
502                fLastComponent = fNonNSDTDValidator;
503             }
504             else
505             {
506                fScanner.setDocumentHandler(fDocumentHandler);
507                if(fDocumentHandler != null)
508                {
509                   fDocumentHandler.setDocumentSource(fScanner);
510                }
511                fLastComponent = fScanner;
512             }
513          }
514
515          // setup document pipeline
516
if(fFeatures.get(XMLSCHEMA_VALIDATION) == Boolean.TRUE)
517          {
518             // If schema validator was not in the pipeline insert it.
519
if(fSchemaValidator == null)
520             {
521                fSchemaValidator = new JBossXBSchemaValidator();
522
523                // add schema component
524
fProperties.put(SCHEMA_VALIDATOR, fSchemaValidator);
525                addComponent(fSchemaValidator);
526                // add schema message formatter
527
if(fErrorReporter.getMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN) == null)
528                {
529                   XSMessageFormatter xmft = new XSMessageFormatter();
530                   fErrorReporter.putMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN, xmft);
531                }
532
533             }
534
535             fLastComponent.setDocumentHandler(fSchemaValidator);
536             fSchemaValidator.setDocumentSource(fLastComponent);
537             fSchemaValidator.setDocumentHandler(fDocumentHandler);
538             if(fDocumentHandler != null)
539             {
540                fDocumentHandler.setDocumentSource(fSchemaValidator);
541             }
542             fLastComponent = fSchemaValidator;
543          }
544       }
545    }
546
547    private static class SAXAttributes
548       implements org.xml.sax.Attributes JavaDoc
549    {
550       private XMLAttributes attrs;
551
552       public void setAttrs(XMLAttributes attrs)
553       {
554          this.attrs = attrs;
555       }
556
557       public int getLength()
558       {
559          return attrs.getLength();
560       }
561
562       public String JavaDoc getLocalName(int index)
563       {
564          return attrs.getLocalName(index);
565       }
566
567       public String JavaDoc getQName(int index)
568       {
569          return attrs.getQName(index);
570       }
571
572       public String JavaDoc getType(int index)
573       {
574          return attrs.getType(index);
575       }
576
577       public String JavaDoc getURI(int index)
578       {
579          return attrs.getURI(index);
580       }
581
582       public String JavaDoc getValue(int index)
583       {
584          return attrs.getValue(index);
585       }
586
587       public int getIndex(String JavaDoc qName)
588       {
589          return attrs.getIndex(qName);
590       }
591
592       public String JavaDoc getType(String JavaDoc qName)
593       {
594          return attrs.getType(qName);
595       }
596
597       public String JavaDoc getValue(String JavaDoc qName)
598       {
599          return attrs.getValue(qName);
600       }
601
602       public int getIndex(String JavaDoc uri, String JavaDoc localName)
603       {
604          return attrs.getIndex(uri, localName);
605       }
606
607       public String JavaDoc getType(String JavaDoc uri, String JavaDoc localName)
608       {
609          return attrs.getType(uri, localName);
610       }
611
612       public String JavaDoc getValue(String JavaDoc uri, String JavaDoc localName)
613       {
614          return attrs.getValue(uri, localName);
615       }
616       
617       public String JavaDoc toString()
618       {
619          StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
620          buffer.append('(');
621          for (int i = 0; i < getLength(); ++i)
622          {
623             buffer.append(getLocalName(i));
624             buffer.append('=');
625             buffer.append(getValue(i));
626             if (i < getLength()-1)
627                buffer.append(", ");
628          }
629          buffer.append(')');
630          return buffer.toString();
631       }
632    }
633 }
634
Popular Tags