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.camel.builder.xml;
018    
019    import java.util.HashMap;
020    import java.util.Map;
021    
022    import org.w3c.dom.Attr;
023    import org.w3c.dom.Element;
024    import org.w3c.dom.NamedNodeMap;
025    import org.w3c.dom.Node;
026    
027    import org.apache.camel.model.language.VtdXmlExpression;
028    import org.apache.camel.model.language.XPathExpression;
029    import org.apache.camel.model.language.XQueryExpression;
030    import org.apache.camel.spi.NamespaceAware;
031    import org.apache.camel.util.ObjectHelper;
032    
033    /**
034     * A helper class for working with namespaces or creating namespace based expressions
035     *
036     * @version 
037     */
038    public class Namespaces {
039        public static final String DEFAULT_NAMESPACE = "http://camel.apache.org/schema/spring";
040        public static final String IN_NAMESPACE = "http://camel.apache.org/xml/in/";
041        public static final String OUT_NAMESPACE = "http://camel.apache.org/xml/out/";
042        public static final String FUNCTION_NAMESPACE = "http://camel.apache.org/xml/function/";
043        public static final String SYSTEM_PROPERTIES_NAMESPACE = "http://camel.apache.org/xml/variables/system-properties";
044        public static final String ENVIRONMENT_VARIABLES = "http://camel.apache.org/xml/variables/environment-variables";
045        public static final String EXCHANGE_PROPERTY = "http://camel.apache.org/xml/variables/exchange-property";
046    
047        private Map<String, String> namespaces = new HashMap<String, String>();
048    
049        /**
050         * Creates a namespaces object from the given XML element
051         *
052         * @param element the XML element representing the XPath namespace context
053         */
054        public Namespaces(Element element) {
055            add(element);
056        }
057    
058        /**
059         * Creates a namespace context with a single prefix and URI
060         */
061        public Namespaces(String prefix, String uri) {
062            add(prefix, uri);
063        }
064    
065        /**
066         * Returns true if the given namespaceURI is empty or if it matches the
067         * given expected namespace
068         */
069        public static boolean isMatchingNamespaceOrEmptyNamespace(String namespaceURI, String expectedNamespace) {
070            return ObjectHelper.isEmpty(namespaceURI) || namespaceURI.equals(expectedNamespace);
071        }
072    
073        public Namespaces add(String prefix, String uri) {
074            namespaces.put(prefix, uri);
075            return this;
076        }
077    
078        public Namespaces add(Element element) {
079            // let's set the parent first in case we overload a prefix here
080            Node parentNode = element.getParentNode();
081            if (parentNode instanceof org.w3c.dom.Element) {
082                add((Element) parentNode);
083            }
084            NamedNodeMap attributes = element.getAttributes();
085            int size = attributes.getLength();
086            for (int i = 0; i < size; i++) {
087                Attr node = (Attr) attributes.item(i);
088                String name = node.getName();
089                if (name.startsWith("xmlns:")) {
090                    String prefix = name.substring("xmlns:".length());
091                    String uri = node.getValue();
092                    add(prefix, uri);
093                }
094            }
095            return this;
096        }
097    
098        /**
099         * Creates the XPath expression using the VTD-XML library using the current namespace context
100         */
101        public VtdXmlExpression vtdxml(String expression) {
102            VtdXmlExpression answer = new VtdXmlExpression(expression);
103            configure(answer);
104            return answer;
105        }
106    
107        /**
108         * Creates the XPath expression using the current namespace context
109         */
110        public XPathExpression xpath(String expression) {
111            XPathExpression answer = new XPathExpression(expression);
112            configure(answer);
113            return answer;
114        }
115    
116        /**
117         * Creates the XPath expression using the current namespace context
118         */
119        public XPathExpression xpath(String expression, Class<?> resultType) {
120            XPathExpression answer = xpath(expression);
121            answer.setResultType(resultType);
122            return answer;
123        }
124    
125        /**
126         * Creates the XQuery expression using the current namespace context
127         */
128        public XQueryExpression xquery(String expression) {
129            XQueryExpression answer = new XQueryExpression(expression);
130            configure(answer);
131            return answer;
132        }
133    
134        /**
135         * Creates the XQuery expression using the current namespace context
136         * and the given expected return type
137         */
138        public XQueryExpression xquery(String expression, Class<?> resultType) {
139            XQueryExpression answer = new XQueryExpression(expression);
140            answer.setResultType(resultType);
141            configure(answer);
142            return answer;
143        }
144    
145        public Map<String, String> getNamespaces() {
146            return namespaces;
147        }
148    
149        /**
150         * Configures the namespace aware object
151         */
152        public void configure(NamespaceAware namespaceAware) {
153            namespaceAware.setNamespaces(getNamespaces());
154        }
155    }