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