Java tutorial
/** * Copyright 2011 Caleb Richardson * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.outerspacecat.util; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableCollection; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMultimap; import java.util.Iterator; import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.ThreadSafe; import javax.xml.XMLConstants; import javax.xml.namespace.NamespaceContext; /** * An implementation of {@link NamespaceContext}, * * @author Caleb Richardson */ @Immutable @ThreadSafe public final class ConcurrentNamespaceContext implements NamespaceContext { private final ImmutableMap<String, String> prefixMap; private final ImmutableMultimap<String, String> namespaceMap; private ConcurrentNamespaceContext(final ImmutableMap<String, String> prefixMap, final ImmutableMultimap<String, String> namespaceMap) { this.prefixMap = ImmutableMap.copyOf(prefixMap); this.namespaceMap = ImmutableMultimap.copyOf(namespaceMap); } @Override public String getNamespaceURI(final String prefix) { Preconditions.checkArgument(prefix != null, "prefix required"); String ret = prefixMap.get(prefix); if (ret == null) ret = XMLConstants.NULL_NS_URI; return ret; } @Override public String getPrefix(final String namespaceURI) { Preconditions.checkArgument(namespaceURI != null, "namespaceURI required"); ImmutableCollection<String> prefixes = namespaceMap.get(namespaceURI); if (prefixes.isEmpty()) return XMLConstants.NULL_NS_URI; return prefixes.iterator().next(); } @Override public Iterator<?> getPrefixes(final String namespaceURI) { Preconditions.checkArgument(namespaceURI != null, "namespaceURI required"); return namespaceMap.get(namespaceURI).iterator(); } /** * A builder for instances of {@link ConcurrentNamespaceContext}. */ public final static class Builder { private final ImmutableMap.Builder<String, String> prefixBuilder = ImmutableMap.builder(); private final ImmutableMultimap.Builder<String, String> namespaceBuilder = ImmutableMultimap.builder(); /** * Adds a new mapping. Calling this method more than once with the same * value for {@code prefix} will cause {@link #build()} to throw an * exception. * * @param prefix the prefix. Must be non {@code null}. * @param namespaceURI the namespace URI. Must be non {@code null}. * @return this builder. Never {@code null}. */ public Builder add(final String prefix, final String namespaceURI) { Preconditions.checkNotNull(prefix, "prefix required"); Preconditions.checkNotNull(namespaceURI, "namespaceURI required"); prefixBuilder.put(prefix, namespaceURI); namespaceBuilder.put(namespaceURI, prefix); return this; } /** * Returns a new concurrent namespace context. * * @return a new concurrent namespace context. Never {@code null}. */ public ConcurrentNamespaceContext build() { prefixBuilder.put(XMLConstants.DEFAULT_NS_PREFIX, XMLConstants.NULL_NS_URI); prefixBuilder.put(XMLConstants.XML_NS_PREFIX, XMLConstants.XML_NS_URI); prefixBuilder.put(XMLConstants.XMLNS_ATTRIBUTE, XMLConstants.XMLNS_ATTRIBUTE_NS_URI); namespaceBuilder.put(XMLConstants.NULL_NS_URI, XMLConstants.DEFAULT_NS_PREFIX); namespaceBuilder.put(XMLConstants.XML_NS_URI, XMLConstants.XML_NS_PREFIX); namespaceBuilder.put(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, XMLConstants.XMLNS_ATTRIBUTE); return new ConcurrentNamespaceContext(prefixBuilder.build(), namespaceBuilder.build()); } } }