com.outerspacecat.util.ConcurrentNamespaceContext.java Source code

Java tutorial

Introduction

Here is the source code for com.outerspacecat.util.ConcurrentNamespaceContext.java

Source

/**
 * 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());
        }
    }
}