001 /** 002 * 003 * Licensed to the Apache Software Foundation (ASF) under one or more 004 * contributor license agreements. See the NOTICE file distributed with 005 * this work for additional information regarding copyright ownership. 006 * The ASF licenses this file to You under the Apache License, Version 2.0 007 * (the "License"); you may not use this file except in compliance with 008 * the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 package org.apache.camel.builder.xml; 019 020 import org.w3c.dom.Element; 021 import org.w3c.dom.NamedNodeMap; 022 import org.w3c.dom.Node; 023 import org.w3c.dom.Attr; 024 025 import javax.xml.namespace.NamespaceContext; 026 import javax.xml.xpath.XPathFactory; 027 import java.util.HashMap; 028 import java.util.HashSet; 029 import java.util.Iterator; 030 import java.util.Map; 031 import java.util.Set; 032 033 /** 034 * An implementation of {@link NamespaceContext} which uses a simple Map where 035 * the keys are the prefixes and the values are the URIs 036 * 037 * @version $Revision: $ 038 */ 039 public class DefaultNamespaceContext implements NamespaceContext { 040 041 private final Map map; 042 private final NamespaceContext parent; 043 044 public DefaultNamespaceContext() { 045 this(XPathFactory.newInstance()); 046 } 047 048 public DefaultNamespaceContext(XPathFactory factory) { 049 this.parent = factory.newXPath().getNamespaceContext(); 050 this.map = new HashMap(); 051 } 052 053 public DefaultNamespaceContext(NamespaceContext parent, Map map) { 054 this.parent = parent; 055 this.map = map; 056 } 057 058 /** 059 * A helper method to make it easy to create newly populated instances 060 */ 061 public DefaultNamespaceContext add(String prefix, String uri) { 062 map.put(prefix, uri); 063 return this; 064 } 065 066 public String getNamespaceURI(String prefix) { 067 String answer = (String) map.get(prefix); 068 if (answer == null && parent != null) { 069 return parent.getNamespaceURI(prefix); 070 } 071 return answer; 072 } 073 074 public String getPrefix(String namespaceURI) { 075 for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) { 076 Map.Entry entry = (Map.Entry) iter.next(); 077 if (namespaceURI.equals(entry.getValue())) { 078 return (String) entry.getKey(); 079 } 080 } 081 if (parent != null) { 082 return parent.getPrefix(namespaceURI); 083 } 084 return null; 085 } 086 087 public Iterator getPrefixes(String namespaceURI) { 088 Set set = new HashSet(); 089 for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) { 090 Map.Entry entry = (Map.Entry) iter.next(); 091 if (namespaceURI.equals(entry.getValue())) { 092 set.add(entry.getKey()); 093 } 094 } 095 if (parent != null) { 096 Iterator iter = parent.getPrefixes(namespaceURI); 097 while (iter.hasNext()) { 098 set.add(iter.next()); 099 } 100 } 101 return set.iterator(); 102 } 103 104 public void setNamespacesFromDom(Element element) { 105 // lets set the parent first in case we overload a prefix here 106 Node parentNode = element.getParentNode(); 107 if (parentNode instanceof Element) { 108 setNamespacesFromDom((Element) parentNode); 109 } 110 NamedNodeMap attributes = element.getAttributes(); 111 for (int i = 0, size = attributes.getLength(); i < size; i++) { 112 Attr node = (Attr) attributes.item(i); 113 String name = node.getName(); 114 if (name.startsWith("xmlns:")) { 115 String prefix = name.substring("xmlns:".length()); 116 String uri = node.getValue(); 117 add(prefix, uri); 118 } 119 } 120 } 121 }