/* | |
* The Apache Software License, Version 1.1 | |
* | |
* | |
* Copyright (c) 2003 The Apache Software Foundation. All rights | |
* reserved. | |
* | |
* Redistribution and use in source and binary forms, with or without | |
* modification, are permitted provided that the following conditions | |
* are met: | |
* | |
* 1. Redistributions of source code must retain the above copyright | |
* notice, this list of conditions and the following disclaimer. | |
* | |
* 2. Redistributions in binary form must reproduce the above copyright | |
* notice, this list of conditions and the following disclaimer in | |
* the documentation and/or other materials provided with the | |
* distribution. | |
* | |
* 3. The end-user documentation included with the redistribution, | |
* if any, must include the following acknowledgment: | |
* "This product includes software developed by the | |
* Apache Software Foundation (http://www.apache.org/)." | |
* Alternately, this acknowledgment may appear in the software itself, | |
* if and wherever such third-party acknowledgments normally appear. | |
* | |
* 4. The names "Apache" and "Apache Software Foundation" must | |
* not be used to endorse or promote products derived from this | |
* software without prior written permission. For written | |
* permission, please contact apache@apache.org. | |
* | |
* 5. Products derived from this software may not be called "Apache | |
* XMLBeans", nor may "Apache" appear in their name, without prior | |
* written permission of the Apache Software Foundation. | |
* | |
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR | |
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
* SUCH DAMAGE. | |
* ==================================================================== | |
* | |
* This software consists of voluntary contributions made by many | |
* individuals on behalf of the Apache Software Foundation and was | |
* originally based on software copyright (c) 2000-2003 BEA Systems | |
* Inc., <http://www.bea.com/>. For more information on the Apache Software | |
* Foundation, please see <http://www.apache.org/>. | |
*/ | |
package org.apache.xmlbeans.impl.newstore.pub.store; | |
import java.lang.ref.ReferenceQueue; | |
import java.lang.ref.Reference; | |
import java.lang.ref.PhantomReference; | |
import org.w3c.dom.DOMImplementation; | |
import org.w3c.dom.DocumentType; | |
import org.w3c.dom.Document; | |
import org.w3c.dom.Node; | |
import org.w3c.dom.Element; | |
import org.xml.sax.Locator; | |
import org.xml.sax.Attributes; | |
import org.xml.sax.ContentHandler; | |
import org.xml.sax.EntityResolver; | |
import org.xml.sax.ErrorHandler; | |
import org.xml.sax.InputSource; | |
import org.xml.sax.ext.LexicalHandler; | |
import org.xml.sax.SAXParseException; | |
import org.xml.sax.InputSource; | |
import org.xml.sax.XMLReader; | |
import org.xml.sax.SAXException; | |
import javax.xml.parsers.SAXParserFactory; | |
import java.io.InputStream; | |
import java.io.Reader; | |
import java.io.StringReader; | |
import javax.xml.namespace.QName; | |
import org.w3c.dom.DOMImplementation; | |
import org.apache.xmlbeans.impl.newstore.SaajImpl; | |
import org.apache.xmlbeans.impl.newstore.Saaj; | |
import org.apache.xmlbeans.impl.newstore.Saaj.SaajCallback; | |
import org.apache.xmlbeans.impl.newstore.pub.store.Dom.TextNode; | |
import org.apache.xmlbeans.impl.newstore.pub.store.Dom.CdataNode; | |
import org.apache.xmlbeans.impl.newstore.DomImpl; | |
import org.apache.xmlbeans.impl.newstore.DomImpl.SaajTextNode; | |
import org.apache.xmlbeans.impl.newstore.DomImpl.SaajCdataNode; | |
public abstract class Locale implements DOMImplementation, SaajCallback | |
{ | |
public Locale ( ) | |
{ | |
_noSync = true; | |
_tempFrames = new Cur [ 4 ]; | |
} | |
protected abstract Cur newCur ( ); | |
protected abstract LoadContext newLoadContext ( ); | |
public static abstract class LoadContext | |
{ | |
protected abstract void startElement ( QName name ); | |
protected abstract void endElement ( ); | |
protected abstract void xmlns ( String prefix, String uri ); | |
protected abstract void attr ( String local, String uri, String value ); | |
protected abstract void comment ( char[] buff, int off, int cch ); | |
protected abstract void procInst ( String target, String value ); | |
protected abstract void text ( char[] buff, int off, int cch ); | |
protected abstract Cur finish ( ); | |
} | |
public QName makeQName ( String uri, String localPart ) | |
{ | |
assert localPart != null && localPart.length() > 0; | |
// TODO - make sure name is a well formed name? | |
return new QName( uri, localPart ); | |
} | |
public QName makeQName ( String uri, String local, String prefix ) | |
{ | |
return new QName( uri, local, prefix ); | |
} | |
public QName makeQualifiedQName ( String uri, String qname ) | |
{ | |
assert qname != null && qname.length() > 0; | |
int i = qname.indexOf( ':' ); | |
return i < 0 | |
? new QName( uri, qname ) | |
: new QName( uri, qname.substring( i + 1 ), qname.substring( 0, i ) ); | |
} | |
public final boolean noSync ( ) | |
{ | |
return _noSync; | |
} | |
public final void enter ( ) | |
{ | |
if (++_numTempFrames >= _tempFrames.length) | |
{ | |
Cur[] newTempFrames = new Cur [ _tempFrames.length * 2 ]; | |
System.arraycopy( _tempFrames, 0, newTempFrames, 0, _tempFrames.length ); | |
_tempFrames = newTempFrames; | |
} | |
if (++_entryCount > 1000) | |
{ | |
_entryCount = 0; | |
if (_refQueue != null) | |
{ | |
for ( ; ; ) | |
{ | |
Ref ref = (Ref) _refQueue.poll(); | |
if (ref == null) | |
break; | |
ref._cur.release(); | |
} | |
} | |
} | |
} | |
public final void exit ( ) | |
{ | |
assert _numTempFrames > 0; | |
_numTempFrames--; | |
Cur c = _tempFrames[ _numTempFrames ]; | |
_tempFrames[ _numTempFrames ] = null; | |
while ( c != null ) | |
{ | |
assert c._tempFrame == _numTempFrames; | |
Cur next = c._nextTemp; | |
c._nextTemp = null; | |
c._tempFrame = -1; | |
c.release(); | |
c = next; | |
} | |
} | |
public final long version ( ) | |
{ | |
return _versionAll; | |
} | |
public final Cur permCur ( ) | |
{ | |
return getCur( null, Cur.PERM ); | |
} | |
public final Cur tempCur ( ) | |
{ | |
return addTempCur( getCur( null, Cur.TEMP ) ); | |
} | |
public final Cur weakCur ( Object o ) | |
{ | |
assert o != null && !(o instanceof Ref); | |
return getCur( o, Cur.WEAK ); | |
} | |
final static class Ref extends PhantomReference | |
{ | |
Ref ( Cur c, Object obj ) | |
{ | |
super( obj, c._locale().refQueue() ); | |
_cur = c; | |
} | |
final Cur _cur; | |
} | |
final ReferenceQueue refQueue ( ) | |
{ | |
if (_refQueue == null) | |
_refQueue = new ReferenceQueue(); | |
return _refQueue; | |
} | |
private final Cur getCur ( Object obj, int curKind ) | |
{ | |
if (_pool == null) | |
{ | |
Cur c = newCur(); | |
_pool = c.listInsert( _pool, Cur.POOLED ); | |
assert _poolCount == 0; | |
_poolCount++; | |
} | |
Cur c = _pool; | |
_pool = c.listRemove( _pool ); | |
_poolCount--; | |
assert _poolCount >= 0; | |
_unembedded = c.listInsert( _unembedded, Cur.UNEMBEDDED ); | |
assert c._obj == null; | |
if (obj != null) | |
c._obj = new Ref( c, obj ); | |
c._curKind = curKind; | |
return c; | |
} | |
private final Cur addTempCur ( Cur c ) | |
{ | |
int frame = _numTempFrames - 1; | |
assert c != null && frame >= 0; | |
if (c._tempFrame < 0) | |
{ | |
assert frame < _tempFrames.length; | |
c._nextTemp = _tempFrames[ frame ]; | |
c._tempFrame = frame; | |
_tempFrames[ frame ] = c; | |
} | |
return c; | |
} | |
public TextNode createTextNode ( ) | |
{ | |
return _saaj == null ? new TextNode( this ) : new SaajTextNode( this ); | |
} | |
public CdataNode createCdataNode ( ) | |
{ | |
return _saaj == null ? new CdataNode( this ) : new SaajCdataNode( this ); | |
} | |
// | |
// Loading/parsing | |
// | |
private static class SaxLoader | |
implements ContentHandler, LexicalHandler, ErrorHandler, EntityResolver | |
{ | |
SaxLoader ( ) | |
{ | |
try | |
{ | |
_xr = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); | |
_xr.setFeature( "http://xml.org/sax/features/namespace-prefixes", true ); | |
_xr.setFeature( "http://xml.org/sax/features/namespaces", true ); | |
_xr.setFeature( "http://xml.org/sax/features/validation", false ); | |
_xr.setProperty( "http://xml.org/sax/properties/lexical-handler", this ); | |
_xr.setContentHandler( this ); | |
_xr.setErrorHandler( this ); | |
_xr.setEntityResolver( this ); | |
} | |
catch ( Throwable e ) | |
{ | |
throw new RuntimeException( e.getMessage(), e ); | |
} | |
} | |
public Cur load ( Locale l, InputSource is ) | |
{ | |
_locale = l; | |
_context = l.newLoadContext(); | |
try | |
{ | |
_xr.parse( is ); | |
} | |
catch ( Exception e ) | |
{ | |
throw new RuntimeException( e.getMessage(), e ); | |
} | |
return _context.finish(); | |
} | |
public void setDocumentLocator ( Locator locator ) | |
{ | |
// TODO - hook up locator ... | |
} | |
public void startDocument ( ) throws SAXException | |
{ | |
// Do nothing ... start of document is implicit | |
} | |
public void endDocument ( ) throws SAXException | |
{ | |
// Do nothing ... end of document is implicit | |
} | |
public void startElement ( String uri, String local, String qName, Attributes atts ) | |
throws SAXException | |
{ | |
_context.startElement( _locale.makeQualifiedQName( uri, qName ) ); | |
for ( int i = 0, len = atts.getLength() ; i < len ; i++ ) | |
{ | |
String aqn = atts.getQName( i ); | |
if (aqn.equals( "xmlns" )) | |
_context.xmlns( "", atts.getValue( i ) ); | |
else if (aqn.startsWith( "xmlns:" )) | |
_context.xmlns( aqn.substring( 6 ), atts.getValue( i ) ); | |
else | |
{ | |
String attrLocal = atts.getLocalName( i ); | |
if (attrLocal.length() == 0) | |
attrLocal = aqn; | |
_context.attr( attrLocal, atts.getURI( i ), atts.getValue( i ) ); | |
} | |
} | |
} | |
public void endElement ( String namespaceURI, String localName, String qName ) | |
throws SAXException | |
{ | |
_context.endElement(); | |
} | |
public void characters ( char ch[], int start, int length ) throws SAXException | |
{ | |
_context.text( ch, start, length ); | |
} | |
public void ignorableWhitespace ( char ch[], int start, int length ) throws SAXException | |
{ | |
} | |
public void comment ( char ch[], int start, int length ) throws SAXException | |
{ | |
_context.comment( ch, start, length ); | |
} | |
public void processingInstruction ( String target, String data ) throws SAXException | |
{ | |
_context.procInst( target, data ); | |
} | |
public void startDTD ( String name, String publicId, String systemId ) throws SAXException | |
{ | |
} | |
public void endDTD ( ) throws SAXException | |
{ | |
} | |
public void startPrefixMapping ( String prefix, String uri ) throws SAXException | |
{ | |
} | |
public void endPrefixMapping ( String prefix ) throws SAXException | |
{ | |
} | |
public void skippedEntity ( String name ) throws SAXException | |
{ | |
// throw new RuntimeException( "Not impl: skippedEntity" ); | |
} | |
public void startCDATA ( ) throws SAXException | |
{ | |
} | |
public void endCDATA ( ) throws SAXException | |
{ | |
} | |
public void startEntity ( String name ) throws SAXException | |
{ | |
// throw new RuntimeException( "Not impl: startEntity" ); | |
} | |
public void endEntity ( String name ) throws SAXException | |
{ | |
// throw new RuntimeException( "Not impl: endEntity" ); | |
} | |
public void fatalError ( SAXParseException e ) throws SAXException | |
{ | |
throw e; | |
} | |
public void error ( SAXParseException e ) throws SAXException | |
{ | |
throw e; | |
} | |
public void warning ( SAXParseException e ) throws SAXException | |
{ | |
throw e; | |
} | |
public InputSource resolveEntity ( String publicId, String systemId ) | |
{ | |
return new InputSource( new StringReader( "" ) ); | |
} | |
private Locale _locale; | |
private XMLReader _xr; | |
private LoadContext _context; | |
} | |
private Dom load ( InputSource is ) | |
{ | |
return new SaxLoader().load( this, is ).getDom(); | |
} | |
public Dom load ( Reader r ) | |
{ | |
return load( new InputSource( r ) ); | |
} | |
public Dom load ( String s ) | |
{ | |
return load( new InputSource( new StringReader( s ) ) ); | |
} | |
public Dom load ( InputStream in ) | |
{ | |
return load( new InputSource( in ) ); | |
} | |
// | |
// DOMImplementation methods | |
// | |
public Document createDocument ( String uri, String qname, DocumentType doctype ) | |
{ | |
return DomImpl._domImplementation_createDocument( this, uri, qname, doctype ); | |
} | |
public DocumentType createDocumentType ( String qname, String publicId, String systemId ) | |
{ | |
return DomImpl._domImplementation_createDocumentType( this, qname, publicId, systemId ); | |
} | |
public boolean hasFeature ( String feature, String version ) | |
{ | |
return DomImpl._domImplementation_hasFeature( this, feature, version ); | |
} | |
// | |
// SaajCallback methods | |
// | |
public void setSaajData ( Node n, Object o ) | |
{ | |
assert n instanceof Dom; | |
SaajImpl.saajCallback_setSaajData( (Dom) n, o ); | |
} | |
public Object getSaajData ( Node n ) | |
{ | |
assert n instanceof Dom; | |
return SaajImpl.saajCallback_getSaajData( (Dom) n ); | |
} | |
public Element createSoapElement ( QName name, QName parentName ) | |
{ | |
assert _ownerDoc != null; | |
return SaajImpl.saajCallback_createSoapElement( _ownerDoc, name, parentName ); | |
} | |
public Element importSoapElement ( Document doc, Element elem, boolean deep, QName parentName ) | |
{ | |
assert doc instanceof Dom; | |
return SaajImpl.saajCallback_importSoapElement( (Dom) doc, elem, deep, parentName ); | |
} | |
// | |
// | |
// | |
private ReferenceQueue _refQueue; | |
Cur _pool; | |
int _poolCount; | |
public long _versionAll; | |
public long _versionSansText; | |
public Cur _unembedded; | |
private boolean _noSync; | |
private int _entryCount; | |
private Cur[] _tempFrames; | |
private int _numTempFrames; | |
public Dom _ownerDoc; | |
public static Saaj _saaj; | |
} |