/**
* Copyright 2011 meltmedia
*
* 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.
*/
package org.xchain.framework.digester;
import org.apache.commons.digester.Digester;
import org.apache.commons.digester.RuleSet;
import org.apache.commons.digester.RuleSetBase;
import org.apache.commons.digester.Rule;
import java.net.URL;
import java.util.Enumeration;
import java.io.IOException;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xchain.framework.net.UrlSourceUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Christian Trimble
* @author Devon Tackett
* @author Jason Rose
* @author Josh Kennedy
*/
public class RuleSetRegistryConfigurator
{
public static Logger log = LoggerFactory.getLogger(RuleSetRegistryConfigurator.class);
public static String RULE_SET_REGISTRATION_RESOURCE = "org/xchain/digester/rule-set-registry.xml";
public static String RULE_SET_REGISTRATION_NAMESPACE_URI = "http://xchain.org/rule-set-registry/1.0";
public void configure()
throws Exception
{
// get all of the config files for the registry.
Enumeration<URL> registrationUrlEnumeration = getConfigurationUrlEnumeration(RULE_SET_REGISTRATION_RESOURCE);
// for each registration document, register the configured rule sets.
while( registrationUrlEnumeration.hasMoreElements() ) {
URL registrationUrl = registrationUrlEnumeration.nextElement();
if( log.isDebugEnabled() ) {
log.debug("Loading registration file for url '"+registrationUrl.toExternalForm()+"'.");
}
// process the registrations defined in this registration url.
processRegistrationUrl( registrationUrl );
if( log.isDebugEnabled() ) {
log.debug("Done loading registration file for url '"+registrationUrl.toExternalForm()+"'.");
}
}
}
public Enumeration<URL> getConfigurationUrlEnumeration( String resourceName )
throws IOException
{
// get the enumeration of all the matching resources.
return Thread.currentThread().getContextClassLoader().getResources( resourceName );
}
public void processRegistrationUrl( URL registrationUrl )
throws Exception
{
// create a digester to parse the registration url.
Digester digester = new Digester();
digester.addRuleSet(new RegistrationRuleSet());
// create a source for the url.
InputSource registrationUrlSource = UrlSourceUtil.createSaxInputSource(registrationUrl);
// parse the registration url.
digester.parse(registrationUrlSource);
}
public static class RegistrationRuleSet
extends RuleSetBase
{
public static String REGISTRY_ELEMENT = "registry";
public static String RULE_SET_ELEMENT = "rule-set";
public static String CLASS_NAME_ATTRIBUTE = "class-name";
public RegistrationRuleSet()
{
this.namespaceURI = RULE_SET_REGISTRATION_NAMESPACE_URI;
}
public void addRuleInstances( Digester digester )
{
digester.setNamespaceAware(true);
digester.setRuleNamespaceURI(getNamespaceURI());
digester.addRule(REGISTRY_ELEMENT, new LoadRuleSetRegistryRule() );
String ruleSetPath = REGISTRY_ELEMENT+"/"+RULE_SET_ELEMENT;
digester.addRule(ruleSetPath, new RegisterRuleSetRule());
}
public static class LoadRuleSetRegistryRule
extends Rule
{
public void begin( String namespace, String name, Attributes attributes )
throws Exception
{
RuleSetRegistry registry = RuleSetRegistry.getInstance();
// push the registry on the top of the stack.
digester.push(registry);
}
}
public static class RegisterRuleSetRule
extends Rule
{
public void begin( String namespace, String name, Attributes attributes )
throws Exception
{
String className = getValue( attributes, "", CLASS_NAME_ATTRIBUTE );
if( className == null ) {
throw new Exception("The class name is a required attribute for rule-set tags.");
}
// create an instance of the class specified for the rule set.
Object object = Thread.currentThread().getContextClassLoader().loadClass(className).newInstance();
// verify that the class is an instance of RuleSet.
if( !( object instanceof RuleSet ) ) {
throw new Exception("The class-name attribute of rule-set must specify a subclass of org.apache.commons.digester.RuleSet.");
}
// cast the created class to a rule set.
RuleSet ruleSet = (RuleSet)object;
// get the rule set registry from the digester.
RuleSetRegistry registry = (RuleSetRegistry)digester.peek();
// add the rule set to the registry.
registry.addRuleSet(ruleSet);
}
}
}
public static String getValue( Attributes attributes, String namespace, String name )
{
String value = null;
int index = attributes.getIndex( namespace, name );
if( index >= 0 ) {
value = attributes.getValue(index);
}
return value;
}
}