001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.servicemix.eip.patterns;
018    
019    import javax.jbi.management.DeploymentException;
020    import javax.xml.namespace.NamespaceContext;
021    import javax.xml.transform.Source;
022    import javax.xml.transform.dom.DOMSource;
023    import javax.xml.xpath.XPathFactory;
024    import javax.xml.xpath.XPathFunctionResolver;
025    
026    import org.w3c.dom.Document;
027    import org.w3c.dom.Node;
028    import org.w3c.dom.NodeList;
029    
030    import org.apache.servicemix.eip.support.AbstractSplitter;
031    import org.apache.servicemix.expression.JAXPNodeSetXPathExpression;
032    import org.apache.servicemix.expression.MessageVariableResolver;
033    import org.apache.servicemix.jbi.jaxp.SourceTransformer;
034    
035    /**
036     * The XPathSplitter component implements the 
037     * <a href="http://www.enterpriseintegrationpatterns.com/Sequencer.html">Splitter</a>
038     * pattern using an xpath expression to split the incoming xml. 
039     * 
040     * @author gnodet
041     * @version $Revision: 376451 $
042     * @org.apache.xbean.XBean element="xpath-splitter"
043     *                  description="An XPath Splitter"
044     */
045    public class XPathSplitter extends AbstractSplitter {
046    
047        /**
048         * The xpath expression to use to split 
049         */
050        private JAXPNodeSetXPathExpression xpathExpression = new JAXPNodeSetXPathExpression();
051        
052        private SourceTransformer sourceTransformer = new SourceTransformer();
053    
054        /* (non-Javadoc)
055         * @see org.apache.servicemix.eip.EIPEndpoint#validate()
056         */
057        public void validate() throws DeploymentException {
058            super.validate();
059            // Check xpath expression
060            try {
061                xpathExpression.afterPropertiesSet();
062            } catch (Exception e) {
063                throw new DeploymentException("Error validating xpath expression", e);
064            }
065        }
066        
067        /* (non-Javadoc)
068         * @see org.apache.servicemix.components.eip.AbstractSplitter#split(javax.xml.transform.Source)
069         */
070        protected Source[] split(Source main) throws Exception {
071            Node doc = sourceTransformer.toDOMNode(main);
072            NodeList nodes = (NodeList) xpathExpression.evaluateXPath(doc);
073            Source[] parts = new Source[nodes.getLength()];
074            for (int i = 0; i < parts.length; i++) {
075                Document part = sourceTransformer.toDOMDocument(nodes.item(i));
076                parts[i] = new DOMSource(part);
077            }
078            return parts;
079        }
080    
081        /* (non-Javadoc)
082         * @see org.apache.servicemix.expression.JAXPXPathExpression#getFactory()
083         */
084        public XPathFactory getFactory() {
085            return xpathExpression.getFactory();
086        }
087    
088        /* (non-Javadoc)
089         * @see org.apache.servicemix.expression.JAXPXPathExpression#getFunctionResolver()
090         */
091        public XPathFunctionResolver getFunctionResolver() {
092            return xpathExpression.getFunctionResolver();
093        }
094    
095        /* (non-Javadoc)
096         * @see org.apache.servicemix.expression.JAXPXPathExpression#getNamespaceContext()
097         */
098        public NamespaceContext getNamespaceContext() {
099            return xpathExpression.getNamespaceContext();
100        }
101    
102        /* (non-Javadoc)
103         * @see org.apache.servicemix.expression.JAXPXPathExpression#getTransformer()
104         */
105        public SourceTransformer getTransformer() {
106            return xpathExpression.getTransformer();
107        }
108    
109        /* (non-Javadoc)
110         * @see org.apache.servicemix.expression.JAXPXPathExpression#getVariableResolver()
111         */
112        public MessageVariableResolver getVariableResolver() {
113            return xpathExpression.getVariableResolver();
114        }
115    
116        /* (non-Javadoc)
117         * @see org.apache.servicemix.expression.JAXPXPathExpression#getXPath()
118         */
119        public String getXPath() {
120            return xpathExpression.getXPath();
121        }
122    
123        /* (non-Javadoc)
124         * @see org.apache.servicemix.expression.JAXPXPathExpression#setFactory(
125         *      javax.xml.xpath.XPathFactory)
126         */
127        public void setFactory(XPathFactory factory) {
128            xpathExpression.setFactory(factory);
129        }
130    
131        /* (non-Javadoc)
132         * @see org.apache.servicemix.expression.JAXPXPathExpression#setFunctionResolver(
133         *      javax.xml.xpath.XPathFunctionResolver)
134         */
135        public void setFunctionResolver(XPathFunctionResolver functionResolver) {
136            xpathExpression.setFunctionResolver(functionResolver);
137        }
138    
139        /* (non-Javadoc)
140         * @see org.apache.servicemix.expression.JAXPXPathExpression#setNamespaceContext(
141         *      javax.xml.namespace.NamespaceContext)
142         */
143        public void setNamespaceContext(NamespaceContext namespaceContext) {
144            xpathExpression.setNamespaceContext(namespaceContext);
145        }
146    
147        /* (non-Javadoc)
148         * @see org.apache.servicemix.expression.JAXPXPathExpression#setTransformer(
149         *      org.apache.servicemix.jbi.jaxp.SourceTransformer)
150         */
151        public void setTransformer(SourceTransformer transformer) {
152            xpathExpression.setTransformer(transformer);
153        }
154    
155        /* (non-Javadoc)
156         * @see org.apache.servicemix.expression.JAXPXPathExpression#setVariableResolver(
157         *      org.apache.servicemix.expression.MessageVariableResolver)
158         */
159        public void setVariableResolver(MessageVariableResolver variableResolver) {
160            xpathExpression.setVariableResolver(variableResolver);
161        }
162    
163        /**
164         * @org.apache.xbean.Property alias="xpath"
165         */
166        public void setXPath(String xpath) {
167            xpathExpression.setXPath(xpath);
168        }
169    
170    }