1 /*
2  * reserved comment block
3  * DO NOT REMOVE OR ALTER!
4  */
5 /*
6  * Licensed to the Apache Software Foundation (ASF) under one or more
7  * contributor license agreements.  See the NOTICE file distributed with
8  * this work for additional information regarding copyright ownership.
9  * The ASF licenses this file to You under the Apache License, Version 2.0
10  * (the "License"); you may not use this file except in compliance with
11  * the License.  You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21 
22 package com.sun.org.apache.xerces.internal.util;
23 
24 import com.sun.org.apache.xerces.internal.impl.xs.util.SimpleLocator;
25 import com.sun.org.apache.xerces.internal.jaxp.validation.WrappedSAXException;
26 import com.sun.org.apache.xerces.internal.xni.QName;
27 import com.sun.org.apache.xerces.internal.xni.XMLAttributes;
28 import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler;
29 import com.sun.org.apache.xerces.internal.xni.XMLLocator;
30 import com.sun.org.apache.xerces.internal.xni.XMLString;
31 import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource;
32 import org.xml.sax.Attributes;
33 import org.xml.sax.ContentHandler;
34 import org.xml.sax.Locator;
35 import org.xml.sax.SAXException;
36 
37 /**
38  * Receves SAX {@link ContentHandler} events
39  * and produces the equivalent {@link XMLDocumentHandler} events.
40  *
41  * @author
42  *     Kohsuke Kawaguchi
43  */
44 public class SAX2XNI implements ContentHandler, XMLDocumentSource {
SAX2XNI( XMLDocumentHandler core )45     public SAX2XNI( XMLDocumentHandler core ) {
46         this.fCore = core;
47     }
48 
49     private XMLDocumentHandler fCore;
50 
51     private final NamespaceSupport nsContext = new NamespaceSupport();
52     private final SymbolTable symbolTable = new SymbolTable();
53 
54 
setDocumentHandler(XMLDocumentHandler handler)55     public void setDocumentHandler(XMLDocumentHandler handler) {
56         fCore = handler;
57     }
58 
getDocumentHandler()59     public XMLDocumentHandler getDocumentHandler() {
60         return fCore;
61     }
62 
63 
64     //
65     //
66     // ContentHandler implementation
67     //
68     //
startDocument()69     public void startDocument() throws SAXException {
70         try {
71             nsContext.reset();
72 
73             XMLLocator xmlLocator;
74             if(locator==null)
75                 // some SAX source doesn't provide a locator,
76                 // in which case we assume no line information is available
77                 // and use a dummy locator. With this, downstream components
78                 // can always assume that they will get a non-null Locator.
79                 xmlLocator=new SimpleLocator(null,null,-1,-1);
80             else
81                 xmlLocator=new LocatorWrapper(locator);
82 
83             fCore.startDocument(
84                     xmlLocator,
85                     null,
86                     nsContext,
87                     null);
88         } catch( WrappedSAXException e ) {
89             throw e.exception;
90         }
91     }
92 
endDocument()93     public void endDocument() throws SAXException {
94         try {
95             fCore.endDocument(null);
96         } catch( WrappedSAXException e ) {
97             throw e.exception;
98         }
99     }
100 
startElement( String uri, String local, String qname, Attributes att )101     public void startElement( String uri, String local, String qname, Attributes att ) throws SAXException {
102         try {
103             fCore.startElement(createQName(uri,local,qname),createAttributes(att),null);
104         } catch( WrappedSAXException e ) {
105             throw e.exception;
106         }
107     }
108 
endElement( String uri, String local, String qname )109     public void endElement( String uri, String local, String qname ) throws SAXException {
110         try {
111             fCore.endElement(createQName(uri,local,qname),null);
112         } catch( WrappedSAXException e ) {
113             throw e.exception;
114         }
115     }
116 
characters( char[] buf, int offset, int len )117     public void characters( char[] buf, int offset, int len ) throws SAXException {
118         try {
119             fCore.characters(new XMLString(buf,offset,len),null);
120         } catch( WrappedSAXException e ) {
121             throw e.exception;
122         }
123     }
124 
ignorableWhitespace( char[] buf, int offset, int len )125     public void ignorableWhitespace( char[] buf, int offset, int len ) throws SAXException {
126         try {
127             fCore.ignorableWhitespace(new XMLString(buf,offset,len),null);
128         } catch( WrappedSAXException e ) {
129             throw e.exception;
130         }
131     }
132 
startPrefixMapping( String prefix, String uri )133     public void startPrefixMapping( String prefix, String uri ) {
134         nsContext.pushContext();
135         nsContext.declarePrefix(prefix,uri);
136     }
137 
endPrefixMapping( String prefix )138     public void endPrefixMapping( String prefix ) {
139         nsContext.popContext();
140     }
141 
processingInstruction( String target, String data )142     public void processingInstruction( String target, String data ) throws SAXException {
143         try {
144             fCore.processingInstruction(
145                     symbolize(target),createXMLString(data),null);
146         } catch( WrappedSAXException e ) {
147             throw e.exception;
148         }
149     }
150 
skippedEntity( String name )151     public void skippedEntity( String name ) {
152     }
153 
154     private Locator locator;
setDocumentLocator( Locator _loc )155     public void setDocumentLocator( Locator _loc ) {
156         this.locator = _loc;
157     }
158 
159     /** Creates a QName object. */
createQName(String uri, String local, String raw)160     private QName createQName(String uri, String local, String raw) {
161 
162         int idx = raw.indexOf(':');
163 
164         if( local.length()==0 ) {
165             // if naemspace processing is turned off, local could be "".
166             // in that case, treat everything to be in the no namespace.
167             uri = "";
168             if(idx<0)
169                 local = raw;
170             else
171                 local = raw.substring(idx+1);
172         }
173 
174         String prefix;
175         if (idx < 0)
176             prefix = null;
177         else
178             prefix = raw.substring(0, idx);
179 
180         if (uri != null && uri.length() == 0)
181             uri = null; // XNI uses null whereas SAX uses the empty string
182 
183         return new QName(symbolize(prefix), symbolize(local), symbolize(raw), symbolize(uri));
184     }
185 
186     /** Symbolizes the specified string. */
symbolize(String s)187     private String symbolize(String s) {
188         if (s == null)
189             return null;
190         else
191             return symbolTable.addSymbol(s);
192     }
193 
createXMLString(String str)194     private XMLString createXMLString(String str) {
195         // with my patch
196         // return new XMLString(str);
197 
198         // for now
199         return new XMLString(str.toCharArray(), 0, str.length());
200     }
201 
202 
203     /** only one instance of XMLAttributes is used. */
204     private final XMLAttributes xa = new XMLAttributesImpl();
205 
206     /** Creates an XMLAttributes object. */
createAttributes(Attributes att)207     private XMLAttributes createAttributes(Attributes att) {
208         xa.removeAllAttributes();
209         int len = att.getLength();
210         for (int i = 0; i < len; i++)
211             xa.addAttribute(
212                     createQName(att.getURI(i), att.getLocalName(i), att.getQName(i)),
213                     att.getType(i),
214                     att.getValue(i));
215         return xa;
216     }
217 }
218