📄 xmlpackagereader.java
字号:
package org.drools.xml;
/*
* Copyright 2005 JBoss Inc
*
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* 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.
*/
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.net.URL;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.drools.lang.descr.PackageDescr;
import org.drools.lang.descr.RuleDescr;
import org.xml.sax.Attributes;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
/**
* <code>RuleSet</code> loader.
*
* Note you can override the default entity resolver by setting the System property of:
* <code>org.drools.io.EntityResolve</code> to your own custom entity resolver.
* This can be done using -Dorg.drools.io.EntityResolver=YourClassHere on the command line, for instance.
*
* @author <a href="mailto:bob@werken.com">bob mcwhirter </a>
*/
public class XmlPackageReader extends DefaultHandler {
// ----------------------------------------------------------------------
// Constants
// ----------------------------------------------------------------------
public static final String ENTITY_RESOLVER_PROPERTY_NAME = "org.drools.io.EntityResolver";
/** Namespace URI for the general tags. */
public static final String RULES_NAMESPACE_URI = "http://drools.org/rules";
private static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
private static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
// ----------------------------------------------------------------------
// Instance members
// ----------------------------------------------------------------------
/** SAX parser. */
private SAXParser parser;
/** isValidating */
private boolean isValidating = true;
/** Locator for errors. */
private Locator locator;
// private Map repo;
/** Stack of configurations. */
private LinkedList configurationStack;
/** Current configuration text. */
private StringBuffer characters;
private Map handlers;
private boolean lastWasEndElement;
private LinkedList parents;
private Object peer;
private Object current;
private PackageDescr packageDescr;
private boolean inHandledRuleSubElement;
private final MessageFormat message = new MessageFormat( "({0}: {1}, {2}): {3}" );
private final Map namespaces = new HashMap();
EntityResolver entityResolver;
// ----------------------------------------------------------------------
// Constructors
// ----------------------------------------------------------------------
/**
* Construct.
*
* <p>
* Uses the default JAXP SAX parser and the default classpath-based
* <code>DefaultSemanticModule</code>.
* </p>
*/
public XmlPackageReader() {
// init
this.configurationStack = new LinkedList();
this.parents = new LinkedList();
this.handlers = new HashMap();
this.handlers.put( "package",
new PackageHandler( this ) );
this.handlers.put( "rule",
new RuleHandler( this ) );
this.handlers.put( "query",
new QueryHandler( this ) );
this.handlers.put( "attribute",
null );
this.handlers.put( "function",
new FunctionHandler( this ) );
// Conditional Elements
this.handlers.put( "lhs",
new AndHandler( this ) );
this.handlers.put( "and",
new AndHandler( this ) );
this.handlers.put( "or",
new OrHandler( this ) );
this.handlers.put( "not",
new NotHandler( this ) );
this.handlers.put( "exists",
new ExistsHandler( this ) );
this.handlers.put( "eval",
new EvalHandler( this ) );
this.handlers.put( "column",
new ColumnHandler( this ) );
// Field Constraints
this.handlers.put( "literal",
new LiteralHandler( this ) );
this.handlers.put( "predicate",
new PredicateHandler( this ) );
this.handlers.put( "return-value",
new ReturnValueHandler( this ) );
this.handlers.put( "field-binding",
new FieldBindingHandler( this ) );
this.handlers.put( "bound-variable",
new BoundVariableHandler( this ) );
initEntityResolver();
}
/**
* Construct.
*
* <p>
* Uses the default classpath-based <code>DefaultSemanticModule</code>.
* </p>
*
* @param parser
* The SAX parser.
*/
public XmlPackageReader(final SAXParser parser) {
this.parser = parser;
}
// ----------------------------------------------------------------------
// Instance methods
// ----------------------------------------------------------------------
/**
* Read a <code>RuleSet</code> from a <code>Reader</code>.
*
* @param reader
* The reader containing the rule-set.
*
* @return The rule-set.
*/
public PackageDescr read(final Reader reader) throws SAXException,
IOException {
return read( new InputSource( reader ) );
}
/**
* Read a <code>RuleSet</code> from an <code>InputStream</code>.
*
* @param inputStream
* The input-stream containing the rule-set.
*
* @return The rule-set.
*/
public PackageDescr read(final InputStream inputStream) throws SAXException,
IOException {
return read( new InputSource( inputStream ) );
}
/**
* Read a <code>RuleSet</code> from an <code>InputSource</code>.
*
* @param in
* The rule-set input-source.
*
* @return The rule-set.
*/
public PackageDescr read(final InputSource in) throws SAXException,
IOException {
SAXParser localParser = null;
if ( this.parser == null ) {
final SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware( true );
final String isValidatingString = System.getProperty( "drools.schema.validating" );
if ( System.getProperty( "drools.schema.validating" ) != null ) {
this.isValidating = Boolean.getBoolean( "drools.schema.validating" );
}
if ( this.isValidating == true ) {
factory.setValidating( true );
try {
localParser = factory.newSAXParser();
} catch ( final ParserConfigurationException e ) {
throw new RuntimeException( e.getMessage() );
}
try {
localParser.setProperty( XmlPackageReader.JAXP_SCHEMA_LANGUAGE,
XmlPackageReader.W3C_XML_SCHEMA );
} catch ( final SAXNotRecognizedException e ) {
boolean hideWarnings = Boolean.getBoolean( "drools.schema.hidewarnings" );
if ( !hideWarnings ) {
System.err.println( "Your SAX parser is not JAXP 1.2 compliant - turning off validation." );
}
localParser = null;
}
}
if ( localParser == null ) {
// not jaxp1.2 compliant so turn off validation
try {
this.isValidating = false;
factory.setValidating( this.isValidating );
localParser = factory.newSAXParser();
} catch ( final ParserConfigurationException e ) {
throw new RuntimeException( e.getMessage() );
}
}
} else {
localParser = this.parser;
}
if ( !localParser.isNamespaceAware() ) {
throw new RuntimeException( "parser must be namespace-aware" );
}
localParser.parse( in,
this );
return this.packageDescr;
}
void setPackageDescr(final PackageDescr packageDescr) {
this.packageDescr = packageDescr;
}
public PackageDescr getPackageDescr() {
return this.packageDescr;
}
/**
* @see org.xml.sax.ContentHandler
*/
public void setDocumentLocator(final Locator locator) {
this.locator = locator;
}
/**
* Get the <code>Locator</code>.
*
* @return The locator.
*/
public Locator getLocator() {
return this.locator;
}
public void startDocument() {
this.isValidating = true;
this.packageDescr = null;
this.current = null;
this.peer = null;
this.lastWasEndElement = false;
this.parents.clear();
this.characters = null;
this.configurationStack.clear();
this.namespaces.clear();
}
/**
* @param uri
* @param localName
* @param qname
* @param attrs
* @throws SAXException
* @see org.xml.sax.ContentHandler
*
* @todo: better way to manage unhandled elements
*/
public void startElement(final String uri,
final String localName,
final String qname,
final Attributes attrs) throws SAXException {
// going down so no peer
if ( !this.lastWasEndElement ) {
this.peer = null;
}
final Handler handler = getHandler( localName );
if ( (handler != null) && (!this.parents.isEmpty() && this.parents.getLast() instanceof RuleDescr) ) {
this.inHandledRuleSubElement = true;
}
if ( handler == null ) {
// if ( ((this.inHandledRuleSubElement == false) && (this.parents.getLast() instanceof RuleDescr)) || (this.parents.getLast() instanceof PackageDescr) ) {
// throw new SAXParseException( "unknown tag '" + localName + "' in namespace '" + uri + "'",
// getLocator() );
// }
// no handler so build up the configuration
startConfiguration( localName,
attrs );
return;
}
validate( uri,
localName,
handler );
final Object node = handler.start( uri,
localName,
attrs );
if ( node != null ) {
this.parents.add( node );
this.current = node;
}
this.lastWasEndElement = false;
}
/**
* @param uri
* @param localName
* @param qname
* @throws SAXException
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -