View Javadoc

1   /*
2    * JBoss DNA (http://www.jboss.org/dna)
3    * See the COPYRIGHT.txt file distributed with this work for information
4    * regarding copyright ownership.  Some portions may be licensed
5    * to Red Hat, Inc. under one or more contributor license agreements.
6    * See the AUTHORS.txt file in the distribution for a full listing of 
7    * individual contributors.
8    *
9    * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
10   * is licensed to you under the terms of the GNU Lesser General Public License as
11   * published by the Free Software Foundation; either version 2.1 of
12   * the License, or (at your option) any later version.
13   * 
14   * JBoss DNA is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17   * Lesser General Public License for more details.
18   *
19   * You should have received a copy of the GNU Lesser General Public
20   * License along with this software; if not, write to the Free
21   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
23   */
24  package org.modeshape.graph.property.basic;
25  
26  import java.util.Collections;
27  import java.util.HashMap;
28  import java.util.Map;
29  import java.util.Set;
30  import org.modeshape.common.i18n.I18n;
31  import org.modeshape.common.util.CheckArg;
32  import org.modeshape.graph.GraphI18n;
33  import org.modeshape.graph.property.NamespaceRegistry;
34  
35  /**
36   * 
37   */
38  public class NamespaceRegistryWithAliases implements NamespaceRegistry {
39  
40      private final NamespaceRegistry delegate;
41      private final Map<String, String> aliaseNamespaceUriByPrefix;
42      private final Map<String, String> namespaceUrisByAlias;
43  
44      /**
45       * Construct a new registry around another delegate registry with a set of aliases for existing namespaces in the delegate
46       * registry. It is possible to supply multiple aliases for a single existing namespace, simply by registering each alias in
47       * <code>aliases</code> and mapping each alias to its existing "real" namespace in <code>namespaceUrisByAliasUri</code>
48       * 
49       * @param delegate the actual delegate registry containing the existing (real) namespaces
50       * @param aliaseNamespaceUriByPrefix the map of alias namespaces keyed by their prefixes
51       * @param namespaceUrisByAliasUri the map of existing namespace URIs keyed by the aliases
52       * @throws IllegalArgumentException if any parameters are null, if there are no aliases, or if the namespaces in the
53       *         <code>aliases</code> registry do not correspond exactly to the mappings in <code>namespaceUrisByAliasUri</code>
54       */
55      public NamespaceRegistryWithAliases( NamespaceRegistry delegate,
56                                           Map<String, String> aliaseNamespaceUriByPrefix,
57                                           Map<String, String> namespaceUrisByAliasUri ) {
58          CheckArg.isNotNull(delegate, "delegate");
59          CheckArg.isNotEmpty(aliaseNamespaceUriByPrefix, "aliases");
60          CheckArg.isNotEmpty(namespaceUrisByAliasUri, "namespaceUrisByAlias");
61          this.delegate = delegate;
62          this.aliaseNamespaceUriByPrefix = aliaseNamespaceUriByPrefix;
63          // Make a copy of the namespaces ...
64          this.namespaceUrisByAlias = Collections.unmodifiableMap(new HashMap<String, String>(namespaceUrisByAliasUri));
65          // Check that the alias map contains exactly the same namespaces as the aliases ...
66          Map<String, String> copyOfNamespaceUrisByAlias = new HashMap<String, String>(namespaceUrisByAlias);
67          for (String aliasedNamespaceUri : this.aliaseNamespaceUriByPrefix.values()) {
68              if (copyOfNamespaceUrisByAlias.remove(aliasedNamespaceUri) == null) {
69                  I18n msg = GraphI18n.namespaceAliasWasNotMappedToRealNamespace;
70                  throw new IllegalArgumentException(msg.text(aliasedNamespaceUri));
71              }
72          }
73          if (!copyOfNamespaceUrisByAlias.isEmpty()) {
74              I18n msg = GraphI18n.aliasesMappedToRealNamespacesButWereNotRegisteredInAliasNamespace;
75              throw new IllegalArgumentException(msg.text(copyOfNamespaceUrisByAlias));
76          }
77      }
78  
79      /**
80       * {@inheritDoc}
81       * 
82       * @see org.modeshape.graph.property.NamespaceRegistry#getDefaultNamespaceUri()
83       */
84      public String getDefaultNamespaceUri() {
85          // Just delegate ...
86          return delegate.getDefaultNamespaceUri();
87      }
88  
89      /**
90       * {@inheritDoc}
91       * 
92       * @see org.modeshape.graph.property.NamespaceRegistry#getNamespaceForPrefix(java.lang.String)
93       */
94      public String getNamespaceForPrefix( String prefix ) {
95          String uri = delegate.getNamespaceForPrefix(prefix);
96          if (uri == null) {
97              // There was no URI registered with that prefix, so check the aliases ...
98              uri = aliaseNamespaceUriByPrefix.get(prefix);
99              if (uri != null) {
100                 // The prefix is for an aliased namespace, so use the original namespace URI instead ...
101                 String originalUri = namespaceUrisByAlias.get(uri);
102                 assert originalUri != null;
103                 uri = originalUri;
104             }
105         } else {
106             // The supplied prefix matched a namespace, but we need to see if the namespace is really an alias
107             // (this can happen if the user re-registers an aliased namespace under a different prefix) ...
108             String originalUri = namespaceUrisByAlias.get(uri);
109             if (originalUri != null) {
110                 // The delegate's prefix matched an aliased namespace URI, so return the original URI ...
111                 uri = originalUri;
112             }
113         }
114         return uri;
115     }
116 
117     /**
118      * {@inheritDoc}
119      * 
120      * @see org.modeshape.graph.property.NamespaceRegistry#getNamespaces()
121      */
122     public Set<Namespace> getNamespaces() {
123         // Do not include the aliases in the namespaces ...
124         return delegate.getNamespaces();
125     }
126 
127     /**
128      * {@inheritDoc}
129      * 
130      * @see org.modeshape.graph.property.NamespaceRegistry#getPrefixForNamespaceUri(java.lang.String, boolean)
131      */
132     public String getPrefixForNamespaceUri( String namespaceUri,
133                                             boolean generateIfMissing ) {
134         // Before we do anything, see if the supplied namespace is an aliased namespace ...
135         String originalNamespaceUri = namespaceUrisByAlias.get(namespaceUri);
136         if (originalNamespaceUri != null) {
137             namespaceUri = originalNamespaceUri;
138         }
139         return delegate.getPrefixForNamespaceUri(namespaceUri, generateIfMissing);
140     }
141 
142     /**
143      * {@inheritDoc}
144      * 
145      * @see org.modeshape.graph.property.NamespaceRegistry#getRegisteredNamespaceUris()
146      */
147     public Set<String> getRegisteredNamespaceUris() {
148         // Do not include the aliases in the namespace URIs ...
149         return delegate.getRegisteredNamespaceUris();
150     }
151 
152     /**
153      * {@inheritDoc}
154      * 
155      * @see org.modeshape.graph.property.NamespaceRegistry#isRegisteredNamespaceUri(java.lang.String)
156      */
157     public boolean isRegisteredNamespaceUri( String namespaceUri ) {
158         return delegate.isRegisteredNamespaceUri(namespaceUri);
159     }
160 
161     /**
162      * {@inheritDoc}
163      * 
164      * @see org.modeshape.graph.property.NamespaceRegistry#register(java.lang.String, java.lang.String)
165      */
166     public String register( String prefix,
167                             String namespaceUri ) {
168         // Let the delegate registry handle this, including cases where an aliased namespace is changed ...
169         return delegate.register(prefix, namespaceUri);
170     }
171 
172     /**
173      * {@inheritDoc}
174      * 
175      * @see org.modeshape.graph.property.NamespaceRegistry#unregister(java.lang.String)
176      */
177     public boolean unregister( String namespaceUri ) {
178         // We cannot unregister an alias, so we only need to try unregistering with the delegate registry ...
179         return delegate.unregister(namespaceUri);
180     }
181 
182 }