/** * $Id: $ * $Date: $ * */ package org.xmlsh.schema; // import org.w3c.dom.DOMImplementationRegistry; import java.util.Stack; import org.apache.xerces.xs.XSComplexTypeDefinition; import org.apache.xerces.xs.XSConstants; import org.apache.xerces.xs.XSElementDeclaration; import org.apache.xerces.xs.XSImplementation; import org.apache.xerces.xs.XSLoader; import org.apache.xerces.xs.XSModel; import org.apache.xerces.xs.XSModelGroup; import org.apache.xerces.xs.XSObject; import org.apache.xerces.xs.XSObjectList; import org.apache.xerces.xs.XSParticle; import org.apache.xerces.xs.XSTerm; import org.apache.xerces.xs.XSTypeDefinition; import org.w3c.dom.bootstrap.DOMImplementationRegistry; import org.xmlsh.util.Util; public class Schema { private XSModel mModel; private Stack<XSElementDeclaration> mScopeStack = new Stack<XSElementDeclaration>(); public Schema( String schema ) throws ClassCastException, ClassNotFoundException, InstantiationException, IllegalAccessException { // Get DOM Implementation using DOM Registry System.setProperty(DOMImplementationRegistry.PROPERTY, "org.apache.xerces.dom.DOMXSImplementationSourceImpl"); DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance(); XSImplementation impl = (XSImplementation) registry.getDOMImplementation("XS-Loader"); XSLoader schemaLoader = impl.createXSLoader(null); mModel = schemaLoader.loadURI(schema); } public XSElementDeclaration pushElement( String namespace , String localname ) { XSElementDeclaration elem = null; /* * Look for scoped element first */ if( ! mScopeStack.isEmpty() ){ XSElementDeclaration root = mScopeStack.peek(); XSTypeDefinition type = root.getTypeDefinition(); if( type.getTypeCategory() != XSTypeDefinition.COMPLEX_TYPE ) return null ; XSComplexTypeDefinition ctype = (XSComplexTypeDefinition) type ; XSParticle particle = ctype.getParticle(); if( particle == null ) return null ; XSTerm term = particle.getTerm() ; if( term == null ) return null; elem = findElement( term , namespace , localname ); } // try a global element if( elem == null && mScopeStack.isEmpty() ){ elem = mModel.getElementDeclaration(localname, namespace ); if( elem == null ) return null ; // SNH } if( elem != null ) mScopeStack.push(elem); return elem ; } private XSElementDeclaration findElement(XSTerm term, String namespace, String localname) { switch( term.getType() ){ case XSConstants.ELEMENT_DECLARATION : { XSElementDeclaration elem = (XSElementDeclaration) term ; if( Util.isEqual(elem.getNamespace() , namespace ) && Util.isEqual(term.getName(), localname) ) return elem ; /* * Try substitution group */ XSObjectList groups = mModel.getSubstitutionGroup(elem); if( groups != null ) { for( int i = 0 ; i < groups.getLength() ; i++ ){ XSObject obj = groups.item(i); if( obj.getType() == XSConstants.ELEMENT_DECLARATION && Util.isEqual(obj.getNamespace() , namespace ) && Util.isEqual(obj.getName(), localname) ) return (XSElementDeclaration)obj ; } } return null ; } case XSConstants.MODEL_GROUP : ; { XSModelGroup group = (XSModelGroup) term ; XSObjectList particles = group.getParticles(); for( int i = 0 ; i < particles.getLength() ; i++ ){ XSParticle particle = (XSParticle) particles.item(i); XSTerm pterm = particle.getTerm(); if( pterm != null ){ XSElementDeclaration elem = findElement( pterm , namespace , localname ); if( elem != null ) return elem ; } } return null ; } case XSConstants.WILDCARD : return null ; } return null ; } /** * @return the model */ public XSModel getModel() { return mModel; } public void popElement() { if( !mScopeStack.isEmpty() ) mScopeStack.pop(); } public XSObjectList getAnnotations() { return mModel.getAnnotations(); } } // // //Copyright (C) 2008-2014 David A. Lee. // //The contents of this file are subject to the "Simplified BSD License" (the "License"); //you may not use this file except in compliance with the License. You may obtain a copy of the //License at http://www.opensource.org/licenses/bsd-license.php // //Software distributed under the License is distributed on an "AS IS" basis, //WITHOUT WARRANTY OF ANY KIND, either express or implied. //See the License for the specific language governing rights and limitations under the License. // //The Original Code is: all this file. // //The Initial Developer of the Original Code is David A. Lee // //Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved. // //Contributor(s): none. //