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