/*
* JBoss, Home of Professional Open Source
* Copyright 2006, JBoss Inc., and others contributors as indicated
* by the @authors tag. All rights reserved.
* See the copyright.txt in the distribution for a
* full listing of individual contributors.
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License, v. 2.1.
* This program is distributed in the hope that it will be useful, but WITHOUT A
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License,
* v.2.1 along with this distribution; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
* (C) 2005-2006, JBoss Inc.
*/
package org.jboss.soa.esb.actions.cbr;
import org.jboss.internal.soa.esb.util.XMLHelper;
import org.jboss.soa.esb.services.routing.MessageRouterException;
import org.jboss.soa.esb.helpers.ConfigTree;
import org.jboss.soa.esb.util.XPathNamespaceContext;
import org.jboss.soa.esb.ConfigurationException;
import org.milyn.payload.StringSource;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLStreamException;
import javax.xml.xpath.*;
import java.util.*;
import java.io.*;
/**
* XPath Content Based Router implementation.
*
* @author <a href="mailto:tom.fennelly@jboss.com">tom.fennelly@jboss.com</a>
*/
public class XPathRouter extends AbstractPropertyRulesRouter {
private XPathNamespaceContext namespaceContext;
public void setConfigTree(ConfigTree configTree) throws MessageRouterException {
try {
namespaceContext = new NamespaceContext(configTree.getChildren("namespace"));
} catch (ConfigurationException e) {
throw new MessageRouterException("Error loading namespace prefix mappings.", e);
}
super.setConfigTree(configTree);
}
public Map<String, RoutingRule> buildRoutingMap(Properties rules) throws MessageRouterException {
XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xpath = xPathFactory.newXPath();
Map<String, RoutingRule> routingMap = new HashMap<String, RoutingRule>();
xpath.setNamespaceContext(namespaceContext);
Set<Map.Entry<Object, Object>> ruleSet = rules.entrySet();
for(Map.Entry<Object, Object> rule : ruleSet) {
String destinationName = (String) rule.getKey();
String expression = (String) rule.getValue();
try {
routingMap.put(destinationName, new XPathRoutingRule(xpath.compile(expression)));
} catch (XPathExpressionException e) {
throw new MessageRouterException("Error compiling XPath expression '" + expression + "'.", e);
}
}
return routingMap;
}
public javax.xml.namespace.NamespaceContext getNamespaceContext() {
return namespaceContext;
}
private class XPathRoutingRule implements RoutingRule {
private XPathExpression xpathExpression;
private XPathRoutingRule(XPathExpression xpathExpression) {
this.xpathExpression = xpathExpression;
}
public boolean evaluate(Object objectToTest) throws MessageRouterException {
try {
if(objectToTest instanceof String) {
final XMLEventReader reader = XMLHelper.getXMLEventReader(new StringSource((String)objectToTest)) ;
final Document doc = XMLHelper.createDocument(reader) ;
return (Boolean) xpathExpression.evaluate(doc, XPathConstants.BOOLEAN);
} else if(objectToTest instanceof byte[]) {
final XMLEventReader reader = XMLHelper.getXMLEventReader(new ByteArrayInputStream((byte[])objectToTest)) ;
final Document doc = XMLHelper.createDocument(reader) ;
return (Boolean) xpathExpression.evaluate(doc, XPathConstants.BOOLEAN);
} else if(objectToTest instanceof Node || objectToTest instanceof NodeList) {
return (Boolean) xpathExpression.evaluate(objectToTest, XPathConstants.BOOLEAN);
} else if (logger.isDebugEnabled()) {
logger.debug("Unsupported XPath evaluation type '" + objectToTest.getClass().getName() + "'.");
}
} catch (ParserConfigurationException e) {
logger.debug("Error evaluating xpath expression.", e);
} catch (XMLStreamException e) {
logger.debug("Error evaluating xpath expression.", e);
} catch (XPathExpressionException e) {
logger.debug("Error evaluating xpath expression.", e);
}
return false;
}
}
}