package com.sun.msv.schematron.reader;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.InputSource;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.NamespaceSupport;
import com.sun.msv.grammar.ExpressionPool;
import com.sun.msv.grammar.trex.TREXGrammar;
import com.sun.msv.reader.GrammarReaderController;
import com.sun.msv.reader.State;
import com.sun.msv.reader.relax.core.RELAXCoreReader;
import com.sun.msv.reader.trex.ng.RELAXNGReader;
import com.sun.msv.reader.trex.ng.IncludeMergeState;
import com.sun.msv.util.StartTagInfo;
public class SRELAXNGReader extends RELAXNGReader {
public static final String SchematronURI = "http://www.ascc.net/xml/schematron";
public static final String RNG_PLUS_SCHEMATRON_URI =
RELAXNGReader.RELAXNGNamespace + "+" + SchematronURI;
/** loads RELAX NG pattern */
public static TREXGrammar parse( String grammarURL,
SAXParserFactory factory, GrammarReaderController controller )
{
SRELAXNGReader reader = new SRELAXNGReader(controller,factory);
reader.parse(grammarURL);
return reader.getResult();
}
/** loads RELAX NG pattern */
public static TREXGrammar parse( InputSource grammar,
SAXParserFactory factory, GrammarReaderController controller )
{
SRELAXNGReader reader = new SRELAXNGReader(controller,factory);
reader.parse(grammar);
return reader.getResult();
}
/** easy-to-use constructor. */
public SRELAXNGReader( GrammarReaderController controller, SAXParserFactory parserFactory) {
this( controller, parserFactory, new ExpressionPool() );
}
/** full constructor */
public SRELAXNGReader( GrammarReaderController controller,
SAXParserFactory parserFactory, ExpressionPool pool ) {
super( controller, parserFactory, new SStateFactory(), pool );
}
// this reader overrides ElementState.
static private class SStateFactory extends StateFactory {
public State element ( State parent, StartTagInfo tag ) { return new SElementState(); }
public State grammar(State parent, StartTagInfo tag) {
return new SGrammarState();
}
public State includedGrammar() {
return new SRootMergedGrammarState();
}
}
protected boolean isGrammarElement( StartTagInfo tag ) {
if( tag.namespaceURI.equals(SchematronURI) ) {
// let <s:ns> appear anywhere
return !tag.localName.equals("ns");
}
return super.isGrammarElement(tag);
}
/**
* Schematron namespace declared via <s:ns>
*
* This is the namespace context we use to resolve prefixes in the XPath expression.
*/
/*package*/ final NamespaceSupport schematronNs = new NamespaceSupport();
public void startElement(String nsUri, String localName, String qname, Attributes atts) throws SAXException {
if(nsUri.equals(SchematronURI) && localName.equals("ns")) {
// allow <s:ns> to appear anywhere in the document
String prefix = atts.getValue("prefix");
String uri = atts.getValue("uri");
if(prefix==null)
reportError( RELAXCoreReader.ERR_MISSING_ATTRIBUTE, "prefix", "ns" );
else
if(uri==null)
reportError( RELAXCoreReader.ERR_MISSING_ATTRIBUTE, "uri", "ns" );
else {
schematronNs.declarePrefix(prefix,uri);
}
} else {
schematronNs.pushContext();
}
super.startElement(nsUri,localName,qname,atts);
}
public void endElement(String nsUri, String localName, String qname) throws SAXException {
super.endElement(nsUri, localName, qname);
if(nsUri.equals(SchematronURI) && localName.equals("ns")) {
;
} else {
schematronNs.popContext();
}
}
//
// error message handling
//
protected String localizeMessage( String propertyName, Object[] args ) {
String format;
try {
format = java.util.ResourceBundle.getBundle(
"com.sun.msv.schematron.reader.Messages").getString(propertyName);
} catch( Exception e ) {
return super.localizeMessage(propertyName,args);
}
return java.text.MessageFormat.format(format, args );
}
public static final String ERR_INVALID_XPATH = // arg:2
"SRELAXNGReader.InvalidXPath";
}