📄 rulesetreader.java
字号:
* @param url
* The rule-set URL.
*
* @return The rule-set.
*/
public RuleSet read(String url) throws SAXException,
IOException
{
return read( new InputSource( url ) );
}
/**
* Read a <code>RuleSet</code> from an <code>InputSource</code>.
*
* @param in
* The rule-set input-source.
*
* @return The rule-set.
*/
public RuleSet read(InputSource in) throws SAXException,
IOException
{
SAXParser localParser = null;
if ( this.parser == null )
{
SAXParserFactory factory = SAXParserFactory.newInstance( );
factory.setNamespaceAware( true );
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 ( ParserConfigurationException e )
{
throw new RuntimeException( e.getMessage( ) );
}
try
{
localParser.setProperty( JAXP_SCHEMA_LANGUAGE,
W3C_XML_SCHEMA );
}
catch ( 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 ( ParserConfigurationException e )
{
throw new RuntimeException( e.getMessage( ) );
}
}
}
else
{
localParser = this.parser;
}
if ( !localParser.isNamespaceAware( ) )
{
throw new RuntimeException( "parser must be namespace-aware" );
}
if ( this.repo == null )
{
try
{
this.repo = DefaultSemanticsRepository.getInstance( );
}
catch ( Exception e )
{
throw new SAXException( "Unable to reference a Semantics Repository:\n" + e.getMessage() );
}
}
localParser.parse( in,
this );
return this.ruleSet;
}
public SemanticsRepository getSemanticsRepository()
{
return this.repo;
}
void setRuleSet(RuleSet ruleSet)
{
this.ruleSet = ruleSet;
}
public RuleSet getRuleSet()
{
return this.ruleSet;
}
public RuleBaseContext getFactoryContext()
{
return this.factoryContext;
}
/**
* @see org.xml.sax.ContentHandler
*/
public void setDocumentLocator(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.ruleSet = null;
this.current = null;
this.peer = null;
this.lastWasEndElement = false;
this.parents.clear( );
this.characters = null;
this.configurationStack.clear( );
this.namespaces.clear( );
if ( this.factoryContext == null )
{
this.factoryContext = new RuleBaseContext( );
}
// now assign the smf classloader so smf implementations can access it
ClassLoader classLoader = (ClassLoader) this.factoryContext.get( "smf-classLoader" );
if ( classLoader == null )
{
this.factoryContext.put( "smf-classLoader",
repo.getSemanticModuleClassLoader( ) );
}
}
/**
* @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(String uri,
String localName,
String qname,
Attributes attrs) throws SAXException
{
// going down so no peer
if ( !this.lastWasEndElement )
{
this.peer = null;
}
Handler handler = getHandler( uri,
localName );
if ( ( handler != null ) && ( !this.parents.isEmpty() && this.parents.getLast() instanceof Rule ) )
{
this.inHandledRuleSubElement = true;
}
if ( handler == null )
{
if ( ( ( this.inHandledRuleSubElement == false) && ( this.parents.getLast( ) instanceof Rule ) )
|| ( this.parents.getLast( ) instanceof RuleSet ) )
{
/* see if the uri is registered */
try
{
this.repo.lookupSemanticModule( uri );
/* uri is registered, but the element is not mapped correctly to a handler */
throw new SAXParseException( "unknown tag '" + localName + "' in namespace '" + uri + "'",
getLocator( ) );
}
catch ( NoSuchSemanticModuleException e )
{
/* uri is not registered, so incorrect uri, missing drools.conf or classloader issues*/
throw new SAXParseException( "no semantic module for namespace '" + uri + "' (" + localName + ")",
getLocator() );
}
}
// no handler so build up the configuration
startConfiguration( localName,
attrs );
return;
}
validate( uri,
localName,
handler );
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
* @see org.xml.sax.ContentHandler
*/
public void endElement(String uri,
String localName,
String qname) throws SAXException
{
Handler handler = getHandler( uri,
localName );
if ( ( handler != null ) && ( !this.parents.isEmpty() && this.parents.getLast() instanceof Rule ) )
{
this.inHandledRuleSubElement = false;
}
if ( handler == null )
{
if ( this.configurationStack.size( ) >= 1 )
{
endConfiguration( );
}
return;
}
this.current = getParent( handler.generateNodeFor( ) );
Object node = handler.end( uri,
localName );
// next
if ( node != null && !this.lastWasEndElement )
{
this.peer = node;
}
// up or no children
else if ( this.lastWasEndElement || (this.parents.getLast( )).getClass( ).isInstance( this.current ) )
{
this.peer = this.parents.removeLast( );
}
this.lastWasEndElement = true;
}
private void validate(String uri,
String localName,
Handler handler) throws SAXParseException
{
boolean validParent = false;
boolean validPeer = false;
boolean invalidNesting = false;
Set validParents = handler.getValidParents( );
Set validPeers = handler.getValidPeers( );
boolean allowNesting = handler.allowNesting( );
// get parent
Object parent;
if ( this.parents.size( ) != 0 )
{
parent = this.parents.getLast( );
}
else
{
parent = null;
}
// check valid parents
// null parent means localname is rule-set
// dont process if elements are the same
// instead check for allowed nesting
Class nodeClass = getHandler( uri,
localName ).generateNodeFor( );
if ( !nodeClass.isInstance( parent ) )
{
Object allowedParent;
Iterator it = validParents.iterator( );
while ( !validParent && it.hasNext( ) )
{
allowedParent = it.next( );
if ( parent == null && allowedParent == null )
{
validParent = true;
}
else if ( allowedParent != null && ((Class) allowedParent).isInstance( parent ) )
{
validParent = true;
}
}
if ( !validParent )
{
throw new SAXParseException( "<" + localName + "> has an invalid parent element",
getLocator( ) );
}
}
// check valid peers
// null peer means localname is rule-set
Object peer = this.peer;
Object allowedPeer;
Iterator it = validPeers.iterator( );
while ( !validPeer && it.hasNext( ) )
{
allowedPeer = it.next( );
if ( peer == null && allowedPeer == null )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -