com.sun.msv.reader.trex.ng.comp.RELAXNGCompReader Maven / Gradle / Ivy
/*
* Copyright (c) 2001-2013 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - 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.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS 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 COPYRIGHT OWNER OR
* 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.
*/
package com.sun.msv.reader.trex.ng.comp;
import java.text.MessageFormat;
import java.util.Map;
import java.util.ResourceBundle;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import com.sun.msv.grammar.AttributeExp;
import com.sun.msv.grammar.ExpressionPool;
import com.sun.msv.grammar.relaxng.RELAXNGGrammar;
import com.sun.msv.grammar.trex.TREXGrammar;
import com.sun.msv.reader.GrammarReaderController;
import com.sun.msv.reader.State;
import com.sun.msv.reader.trex.ng.RELAXNGReader;
import com.sun.msv.util.LightStack;
import com.sun.msv.util.StartTagInfo;
/**
* reads RELAX NG grammar with DTD compatibility annotation
* and constructs abstract grammar model.
*
* @author Kohsuke KAWAGUCHI
*/
public class RELAXNGCompReader extends RELAXNGReader {
/** loads RELAX NG pattern.
*
* @return
* it always returns {@link RELAXNGGrammar}, but due to the
* restriction imposed by Java language, I cannot change the
* signature of this method.
*/
public static TREXGrammar parse( String grammarURL, GrammarReaderController controller )
{
RELAXNGCompReader reader = new RELAXNGCompReader(controller);
reader.parse(grammarURL);
return reader.getResult();
}
/** loads RELAX NG pattern.
*
* @return
* it always returns {@link RELAXNGGrammar}, but due to the
* restriction imposed by Java language, I cannot change the
* signature of this method.
*/
public static TREXGrammar parse( InputSource grammar, GrammarReaderController controller )
{
RELAXNGCompReader reader = new RELAXNGCompReader(controller);
reader.parse(grammar);
return reader.getResult();
}
/** easy-to-use constructor. */
public RELAXNGCompReader( GrammarReaderController controller ) {
this(controller,createParserFactory(),new ExpressionPool());
}
/** easy-to-use constructor. */
public RELAXNGCompReader(
GrammarReaderController controller,
SAXParserFactory parserFactory,
ExpressionPool pool ) {
this(controller,parserFactory,new StateFactory(),pool);
}
/** full constructor */
public RELAXNGCompReader(
GrammarReaderController controller,
SAXParserFactory parserFactory,
StateFactory stateFactory,
ExpressionPool pool ) {
super( controller, parserFactory, stateFactory, pool );
lastRNGElement.push(null);
}
private final Map defaultedAttributes = new java.util.HashMap();
/**
* note that the specified expression is marked with the default value.
* this method is called when a:defaultValue is found.
*/
protected final void addDefaultValue( AttributeExp exp, String value ) {
// record the location where this attribute is declared.
setDeclaredLocationOf(exp);
if(defaultedAttributes.put(exp,value)!=null)
throw new Error(); // it is not possible for one AttributeExp to be processed twice.
}
protected TREXGrammar getGrammar() {
return grammar;
}
protected String localizeMessage( String propertyName, Object[] args ) {
String format;
try {
format = ResourceBundle.getBundle("com.sun.msv.reader.trex.ng.comp.Messages").getString(propertyName);
} catch( Exception e ) {
return super.localizeMessage(propertyName,args);
}
return MessageFormat.format(format, args );
}
/** Namespace URI of RELAX NG DTD compatibility annotation */
public static final String AnnotationNamespace =
"http://relaxng.org/ns/compatibility/annotations/1.0";
/**
* creates various State object, which in turn parses grammar.
* parsing behavior can be customized by implementing custom StateFactory.
*/
public static class StateFactory extends RELAXNGReader.StateFactory {
public State attribute ( State parent, StartTagInfo tag ) { return new CompAttributeState(); }
public TREXGrammar createGrammar( ExpressionPool pool, TREXGrammar parent ) {
return new RELAXNGGrammar(pool,parent);
}
}
// protected StateFactory getStateFactory() {
// return (StateFactory)super.sfactory;
// }
public void wrapUp() {
super.wrapUp();
if(!controller.hadError()) {
// do not check the compatibilities if some errors
// are already reported.
new DefAttCompatibilityChecker(this,defaultedAttributes).test();
new IDCompatibilityChecker(this).test();
}
}
/**
* pair of an element name and an attribute name.
*/
/* private final static class ElemAttrNamePair {
public final StringPair element;
public final StringPair attribute;
public int hashCode() {
return element.hashCode()^attribute.hashCode();
}
public boolean equals( Object o ) {
if(!(o instanceof ElemAttrNamePair)) return false;
ElemAttrNamePair rhs = (ElemAttrNamePair)o;
return element.equals(rhs.element) && attribute.equals(rhs.attribute);
}
public ElemAttrNamePair( StringPair e, StringPair a ) {
element=e; attribute=a;
}
public ElemAttrNamePair( String e_uri, String e_local, String a_uri, String a_local ) {
this( new StringPair(e_uri,e_local), new StringPair(a_uri,a_local) );
}
public ElemAttrNamePair( SimpleNameClass e, SimpleNameClass a ) {
this( e.namespaceURI, e.localName, a.namespaceURI, a.localName );
}
}
*/
/**
* The local name of the preceding RELAX NG element sibling.
*/
private final LightStack lastRNGElement = new LightStack();
private boolean inAnnotation = false;
public void startElement( String uri, String local, String qname, Attributes atts ) throws SAXException {
super.startElement(uri,local,qname,atts);
if(inAnnotation) {
// we found a child element for a:annotation.
// this is not OK.
reportWarning( CERR_ANN_CHILD_ELEMENT, null, new Locator[]{getLocator()} );
((RELAXNGGrammar)grammar).isAnnotationCompatible = false;
}
if(uri.equals(AnnotationNamespace) && local.equals("annotation")) {
// check the compatibility with the annotation feature.
for( int i=0; i
© 2015 - 2025 Weber Informatics LLC | Privacy Policy