View Javadoc

1   package org.apache.torque.generator.qname;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.util.ArrayList;
23  import java.util.Arrays;
24  import java.util.Iterator;
25  import java.util.List;
26  
27  import org.apache.commons.lang.StringUtils;
28  
29  /**
30   * An instance of this class represents a hierarchical namespace. The hierarchy
31   * parts are separated by dots.
32   *
33   * A namespace is in another namespace if it starts with all the components
34   * of the the other namespace (it may contain other components afterwards).
35   * For example, the namespace "org.apache.torque" is in the namespace
36   * "org.apache".
37   *
38   * Note that the components and their order need to be equal, it does not
39   * suffice if a namespace starts with another namespace. For example,
40   * the namespace "org.apache.torque" is not in the namespace
41   * "org.ap".
42   *
43   * Instances of this class are immutable. To guard against mutable subclasses,
44   * this class is final.
45   */
46  public final class Namespace
47  {
48      /**
49       * The separator between the hierachical parts of a namespace.
50       */
51      public static final char SEPARATOR = '.';
52  
53      /**
54       * The root namespace.
55       */
56      public static final Namespace ROOT_NAMESPACE
57              = new Namespace(StringUtils.EMPTY);
58  
59      /**
60       * The String representation of the namespace. Is never null.
61       */
62      private String namespace;
63  
64      /**
65       * Constructs a namespace from its string representation.
66       * @param namespace teh string representation of the namespace.
67       *        May not be null, and may not contain colons(:).
68       *
69       * @throws NullPointerException if namespace is null.
70       * @throws IllegalArgumentException if namespace contains colons.
71       */
72      public Namespace(String namespace)
73      {
74          if (namespace == null)
75          {
76              throw new NullPointerException("namespace must not be null");
77          }
78          this.namespace = namespace;
79      }
80  
81      /**
82       * Copy-Contructor.
83       *
84       * @param toCopy the namespace to copy, not null.
85       * @throws NullPointerException if toCopy is null.
86       */
87      public Namespace(Namespace toCopy)
88      {
89          if (toCopy == null)
90          {
91              throw new NullPointerException("toCopy must not be null");
92          }
93          this.namespace = toCopy.namespace;
94      }
95  
96      /**
97       * Creates a namespace from a hierarchical List of namespace parts.
98       *
99       * @param namespaceParts the parts of the namespace.
100      */
101     public Namespace(List<String> namespaceParts)
102     {
103         if (namespaceParts == null)
104         {
105             throw new NullPointerException("namespaceParts must not be null");
106         }
107         StringBuffer assembledNamespace = new StringBuffer();
108         for (Iterator<String> partIt
109                 = namespaceParts.iterator(); partIt.hasNext();)
110         {
111             String part = partIt.next();
112 
113             assembledNamespace.append(part);
114             if (partIt.hasNext())
115             {
116                 assembledNamespace.append(SEPARATOR);
117             }
118         }
119         this.namespace = assembledNamespace.toString();
120     }
121 
122 
123     /**
124      * Returns the parts of the namespace in hierachical order.
125      * The most significant part, i.e the leftmost side, is returned first.
126      *
127      * @return the parts of the namespace, never null. An empty list
128      *         is returned for the root namespace.
129      */
130     public List<String> getParts()
131     {
132         if (StringUtils.EMPTY.equals(namespace))
133         {
134             return new ArrayList<String>();
135         }
136         String[] partArray
137                 = namespace.split("\\" + SEPARATOR);
138         return Arrays.asList(partArray);
139     }
140 
141     /**
142      * Returns the parent of the given namespace. If this namespace's
143      * parent namespace is the root namespace, or this namespace is the root
144      * namespace, the root namespace is returned.
145      *
146      * @return the parent namespace of the namespace, never null
147      */
148     public Namespace getParent()
149     {
150         int separatorPos = namespace.lastIndexOf(SEPARATOR);
151         if (separatorPos == -1)
152         {
153             return ROOT_NAMESPACE;
154         }
155 
156         String parentNamespace = namespace.substring(0, separatorPos);
157         return new Namespace(parentNamespace);
158     }
159 
160     /**
161      * Returns if this namespace is visible to another namespace.
162      * This is true if this namespace is a "child" of the other namespace
163      * or equal to the other namespace.
164      * Note that for being a child, all the parts of the namespace separated
165      * by a dot must be equal.
166      * For example, &quot;org.apache.torque&quot; is visible to the namespace
167      * quot;org.apache&quot; and &quot;org&quot; but not to
168      * &quot;org.ap&quot;, as the second parts, &quot;apache&quot; and
169      * &quot;ap&quot; are not equal.
170      *
171      * @param otherNamespace the namespace against this namespace
172      *        should be checked, not null.
173      * @return true if this namespace is visible to the given namespace,
174      *         false otherwise.
175      * @throws NullPointerException if otherNamespace is null.
176      */
177     public boolean isVisibleTo(Namespace otherNamespace)
178     {
179         if (otherNamespace == null)
180         {
181             throw new NullPointerException("otherNamespace must not be null");
182         }
183         // All namespaces are in the root namespace.
184         if (ROOT_NAMESPACE.equals(otherNamespace))
185         {
186             return true;
187         }
188 
189         // The root namespace is not contained in an non-root namespace.
190         if (ROOT_NAMESPACE.equals(this))
191         {
192             return false;
193         }
194 
195         if (!this.namespace.startsWith(otherNamespace.namespace))
196         {
197             return false;
198         }
199 
200         if (this.namespace.equals(otherNamespace.namespace))
201         {
202             return true;
203         }
204 
205         if (this.namespace.charAt(otherNamespace.namespace.length())
206                 == SEPARATOR)
207         {
208             return true;
209         }
210 
211         return false;
212     }
213 
214     /**
215      * Returns if this namespace is visible from another namespace.
216      * This is true if the other namespace is a "child" of this namespace.
217      * Note that for being a child, all the parts of the namespace separated
218      * by a dot must be equal.
219      * For example, &quot;org.apache.torque&quot; is visible from the namespace
220      * quot;org.apache.torque.generator&quot;, but not from
221      * &quot;org.apache&quot.
222      *
223      * @param otherNamespace the namespace against this namespace
224      *        should be checked, not null.
225      * @return true if this namespace is visible from the other namespace,
226      *         false otherwise.
227      * @throws NullPointerException if otherNamespace is null.
228      */
229     public boolean isVisibleFrom(Namespace otherNamespace)
230     {
231         if (otherNamespace == null)
232         {
233             throw new NullPointerException("otherNamespace is null "
234                     + "(this namespace is " + this + ")");
235         }
236         return otherNamespace.isVisibleTo(this);
237     }
238 
239     /**
240      * Returns whether this namespace is the root namespace.
241      *
242      * @return true if this namespace is the root namespace, false otherwise.
243      */
244     public boolean isRoot()
245     {
246         return ROOT_NAMESPACE.namespace.equals(namespace);
247     }
248 
249     /**
250      * Returns if this object is equal to another object.
251      * This is true if and only if the other object is a namespace, and their
252      * string representations are equal.
253      *
254      * @param o the object to check equality.
255      * @return true if the object is equal to this namespace, false otherwise.
256      *
257      * @see java.lang.Object#equals(Object)
258      */
259     @Override
260     public boolean equals(Object o)
261     {
262         if (!(o instanceof Namespace))
263         {
264             return false;
265         }
266 
267         Namespace otherNamespace = (Namespace) o;
268         return otherNamespace.namespace.equals(this.namespace);
269     }
270 
271     /**
272      * Returns a hash code for this namespace. The hash code is consistent
273      * with <code>equals()</code>.
274      *
275      * @return a hach code for this object.
276      *
277      * @see java.lang.Object#hashCode()
278      */
279     @Override
280     public int hashCode()
281     {
282         return namespace.hashCode();
283     }
284 
285     /**
286      * Returns a String representation of this namespace.
287      *
288      * @return a String representation of this namespace.
289      *
290      * @see java.lang.Object#toString()
291      */
292     @Override
293     public String toString()
294     {
295         return namespace;
296     }
297 }