src.java.com.ctc.wstx.msv.RelaxNGSchemaFactory Maven / Gradle / Ivy
/* Woodstox XML processor
*
* Copyright (c) 2004- Tatu Saloranta, [email protected]
*
* Licensed under the License specified in the file LICENSE which is
* included with the source code.
* You may not use this file except in compliance with the License.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.ctc.wstx.msv;
import java.io.*;
import java.net.URL;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.stream.*;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.codehaus.stax2.*;
import org.codehaus.stax2.validation.*;
import com.sun.msv.grammar.trex.TREXGrammar;
import com.sun.msv.reader.GrammarReaderController;
import com.sun.msv.reader.trex.ng.RELAXNGReader;
import com.sun.msv.verifier.regexp.REDocumentDeclaration;
import com.ctc.wstx.api.ValidatorConfig;
import com.ctc.wstx.exc.WstxIOException;
import com.ctc.wstx.util.URLUtil;
/**
* This is a StAX2 schema factory that can parse and create schema instances
* for creating validators that validate documents to check their validity
* against specific Relax NG specifications. It requires
* Sun Multi-Schema Validator
* (http://www.sun.com/software/xml/developers/multischema/)
* to work, and acts as a quite thin wrapper layer (although not a completely
* trivial one, since MSV only exports SAX API, some adapting is needed)
*/
public class RelaxNGSchemaFactory
extends XMLValidationSchemaFactory
{
protected final SAXParserFactory mSaxFactory;
/**
* Current configurations for this factory
*/
protected final ValidatorConfig mConfig;
/**
* For now, there's no need for fine-grained error/problem reporting
* infrastructure, so let's just use a dummy controller.
*/
protected final GrammarReaderController mDummyController =
new com.sun.msv.reader.util.IgnoreController();
public RelaxNGSchemaFactory()
{
/* Let's get the SAX parser factory, to be used for creating
* SAX parsers that the grammar reader needs
*/
mSaxFactory = SAXParserFactory.newInstance();
mSaxFactory.setNamespaceAware(true);
mConfig = ValidatorConfig.createDefaults();
}
/*
////////////////////////////////////////////////////////////
// Stax2, Configuration methods
////////////////////////////////////////////////////////////
*/
public boolean isPropertySupported(String propName)
{
return mConfig.isPropertySupported(propName);
}
public boolean setProperty(String propName, Object value)
{
return mConfig.setProperty(propName, value);
}
public Object getProperty(String propName)
{
return mConfig.getProperty(propName);
}
/*
////////////////////////////////////////////////////////////
// Stax2, Factory methods
////////////////////////////////////////////////////////////
*/
public XMLValidationSchema createSchema(InputStream in, String encoding,
String publicId, String systemId)
throws XMLStreamException
{
InputSource src = new InputSource(in);
src.setEncoding(encoding);
src.setPublicId(publicId);
src.setSystemId(systemId);
return loadSchema(src, systemId);
}
public XMLValidationSchema createSchema(Reader r, String publicId,
String systemId)
throws XMLStreamException
{
InputSource src = new InputSource(r);
src.setPublicId(publicId);
src.setSystemId(systemId);
return loadSchema(src, systemId);
}
public XMLValidationSchema createSchema(URL url)
throws XMLStreamException
{
try {
InputStream in = URLUtil.optimizedStreamFromURL(url);
InputSource src = new InputSource(in);
src.setSystemId(url.toExternalForm());
return loadSchema(src, url);
} catch (IOException ioe) {
throw new WstxIOException(ioe);
}
}
public XMLValidationSchema createSchema(File f)
throws XMLStreamException
{
try {
return createSchema(f.toURL());
} catch (IOException ioe) {
throw new WstxIOException(ioe);
}
}
/*
////////////////////////////////////////////////////////////
// Non-public methods
////////////////////////////////////////////////////////////
*/
protected XMLValidationSchema loadSchema(InputSource src, Object sysRef)
throws XMLStreamException
{
/* !!! 28-Dec-2005, TSa: Sax factory is not guaranteed to be
* thread-safe... need to figure out suitable locking scheme
* (or just create new instances all the time)
*/
/* Another thing; should we use a controller to get notified about
* errors in parsing?
*/
MyGrammarController ctrl = new MyGrammarController();
TREXGrammar grammar = RELAXNGReader.parse(src, mSaxFactory, ctrl);
if (grammar == null) {
String msg = "Failed to load RelaxNG from '"+sysRef+"'";
String emsg = ctrl.mErrorMsg;
if (emsg != null) {
msg = msg + ": "+emsg;
}
throw new XMLStreamException(msg);
}
return new RelaxNGSchema(grammar);
}
final static class MyGrammarController
extends com.sun.msv.reader.util.IgnoreController
{
public String mErrorMsg = null;
public MyGrammarController() { }
//public void warning(Locator[] locs, String errorMessage) { }
public void error(Locator[] locs, String msg, Exception nestedException )
{
if (mErrorMsg == null) {
mErrorMsg = msg;
} else {
mErrorMsg = mErrorMsg + "; " + msg;
}
}
}
}