001 /*
002 * JBoss, Home of Professional Open Source.
003 * Copyright 2008, Red Hat Middleware LLC, and individual contributors
004 * as indicated by the @author tags. See the copyright.txt file in the
005 * distribution for a full listing of individual contributors.
006 *
007 * This is free software; you can redistribute it and/or modify it
008 * under the terms of the GNU Lesser General Public License as
009 * published by the Free Software Foundation; either version 2.1 of
010 * the License, or (at your option) any later version.
011 *
012 * This software is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * You should have received a copy of the GNU Lesser General Public
018 * License along with this software; if not, write to the Free
019 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021 */
022 package org.jboss.dna.graph.properties.basic;
023
024 import java.util.Collections;
025 import java.util.HashMap;
026 import java.util.HashSet;
027 import java.util.Map;
028 import java.util.Set;
029 import net.jcip.annotations.ThreadSafe;
030 import org.jboss.dna.common.util.CheckArg;
031 import org.jboss.dna.graph.properties.NamespaceRegistry;
032
033 /**
034 * @author Randall Hauch
035 */
036 @ThreadSafe
037 public class LocalNamespaceRegistry extends BasicNamespaceRegistry {
038
039 private final NamespaceRegistry delegate;
040
041 /**
042 * @param delegate the namespace registry that this registry should delegate to if not found locally
043 */
044 public LocalNamespaceRegistry( NamespaceRegistry delegate ) {
045 super();
046 CheckArg.isNotNull(delegate, "delegate");
047 this.delegate = delegate;
048 unregister(DEFAULT_NAMESPACE_URI);
049 }
050
051 /**
052 * @param delegate the namespace registry that this registry should delegate to if not found locally
053 * @param defaultNamespaceUri the namespace URI to use for the default prefix
054 */
055 public LocalNamespaceRegistry( NamespaceRegistry delegate,
056 final String defaultNamespaceUri ) {
057 super();
058 CheckArg.isNotNull(delegate, "delegate");
059 this.delegate = delegate;
060 register("", defaultNamespaceUri);
061 }
062
063 /**
064 * {@inheritDoc}
065 *
066 * @see org.jboss.dna.graph.properties.basic.BasicNamespaceRegistry#getDefaultNamespaceUri()
067 */
068 @Override
069 public String getDefaultNamespaceUri() {
070 String result = super.getDefaultNamespaceUri();
071 if (result == null) result = this.delegate.getDefaultNamespaceUri();
072 return result;
073 }
074
075 /**
076 * {@inheritDoc}
077 *
078 * @see org.jboss.dna.graph.properties.basic.BasicNamespaceRegistry#getNamespaceForPrefix(java.lang.String)
079 */
080 @Override
081 public String getNamespaceForPrefix( String prefix ) {
082 String result = super.getNamespaceForPrefix(prefix);
083 if (result == null) result = this.delegate.getNamespaceForPrefix(prefix);
084 return result;
085 }
086
087 /**
088 * {@inheritDoc}
089 *
090 * @see org.jboss.dna.graph.properties.basic.BasicNamespaceRegistry#getNamespaces()
091 */
092 @Override
093 public Set<Namespace> getNamespaces() {
094 Set<Namespace> delegateNamespaces = this.delegate.getNamespaces();
095 Set<Namespace> localNamespaces = super.getNamespaces();
096
097 // Load the local namespaces first ...
098 Set<Namespace> namespaces = new HashSet<Namespace>(localNamespaces);
099
100 // Now build a map of the local prefixes so we can check for prefixes
101 Map<String, Namespace> localNamespacesByPrefix = new HashMap<String, Namespace>();
102 for (Namespace ns : localNamespaces)
103 localNamespacesByPrefix.put(ns.getPrefix(), ns);
104
105 // Now iterate over the local namespaces, removing any existing namespace with the same prefix
106 for (Namespace ns : delegateNamespaces) {
107 if (localNamespacesByPrefix.get(ns.getPrefix()) != null) continue;
108 // Try to add the delegate namespace, which won't work if a local with the same URI was already added...
109 namespaces.add(ns);
110 }
111 return Collections.unmodifiableSet(namespaces);
112 }
113
114 /**
115 * {@inheritDoc}
116 *
117 * @see org.jboss.dna.graph.properties.basic.BasicNamespaceRegistry#getPrefixForNamespaceUri(java.lang.String, boolean)
118 */
119 @Override
120 public String getPrefixForNamespaceUri( String namespaceUri,
121 boolean generateIfMissing ) {
122 String result = super.getPrefixForNamespaceUri(namespaceUri, false);
123 if (result == null) result = this.delegate.getPrefixForNamespaceUri(namespaceUri, false);
124 if (result == null && generateIfMissing) result = super.getPrefixForNamespaceUri(namespaceUri, true);
125 return result;
126 }
127
128 /**
129 * {@inheritDoc}
130 *
131 * @see org.jboss.dna.graph.properties.basic.BasicNamespaceRegistry#getRegisteredNamespaceUris()
132 */
133 @Override
134 public Set<String> getRegisteredNamespaceUris() {
135 Set<String> uris = new HashSet<String>(this.delegate.getRegisteredNamespaceUris());
136 uris.addAll(super.getRegisteredNamespaceUris());
137 return Collections.unmodifiableSet(uris);
138 }
139
140 /**
141 * {@inheritDoc}
142 *
143 * @see org.jboss.dna.graph.properties.basic.BasicNamespaceRegistry#isRegisteredNamespaceUri(java.lang.String)
144 */
145 @Override
146 public boolean isRegisteredNamespaceUri( String namespaceUri ) {
147 return super.isRegisteredNamespaceUri(namespaceUri) || this.delegate.isRegisteredNamespaceUri(namespaceUri);
148 }
149
150 /**
151 * {@inheritDoc}
152 *
153 * @see org.jboss.dna.graph.properties.basic.BasicNamespaceRegistry#register(java.lang.String, java.lang.String)
154 */
155 @Override
156 public String register( String prefix,
157 String namespaceUri ) {
158 // Just register the namespace locally ...
159 String previous = super.register(prefix, namespaceUri);
160 // But check whether there is a "previous" from the delegate ...
161 if (previous == null && delegate != null) previous = delegate.getPrefixForNamespaceUri(namespaceUri, false);
162 return previous;
163 }
164
165 /**
166 * {@inheritDoc}
167 *
168 * @see org.jboss.dna.graph.properties.basic.BasicNamespaceRegistry#unregister(java.lang.String)
169 */
170 @Override
171 public boolean unregister( String namespaceUri ) {
172 // Unregister locally ...
173 return super.unregister(namespaceUri);
174 }
175
176 }