View Javadoc

1   /*
2    * Copyright 2006-2016 The JGUIraffe Team.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License")
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package net.sf.jguiraffe.locators;
17  
18  import java.net.URL;
19  
20  import org.apache.commons.lang.ObjectUtils;
21  
22  /**
23   * <p>
24   * A specific {@code Locator} implementation that can obtain resources from
25   * the class path.
26   * </p>
27   * <p>
28   * This class is initialized with a resource name. The {@code getURL()}
29   * method tries to find this resource from the class path (using the
30   * {@link LocatorUtils} class. No caching is performed; each invocation of
31   * {@code getURL()} will look up the resource. Because a lookup might depend
32   * on the context class loader, multiple invocations of {@code getURL()} may
33   * yield different results. In addition, it is possible to specify the
34   * class loader to be used for resource lookup.
35   * </p>
36   * <p>
37   * Instances of this class are created using the {@code getInstance()}
38   * factory method. They are immutable and thus can be shared between multiple
39   * threads.
40   * </p>
41   *
42   * @author Oliver Heger
43   * @version $Id: ClassPathLocator.java 211 2012-07-10 19:49:13Z oheger $
44   */
45  public final class ClassPathLocator extends AbstractLocator
46  {
47      /** Stores the name of the resource. */
48      private final String resourceName;
49  
50      /** The default class loader for the resource lookup. */
51      private final ClassLoader classLoader;
52  
53      /**
54       * Creates a new instance of {@code ClassPathLocator} and sets the name
55       * of the represented resource. To create an instance client code can use
56       * the {@code getInstance()} factory method.
57       *
58       * @param resourceName the resource name
59       * @param cl the default class loader
60       */
61      private ClassPathLocator(String resourceName, ClassLoader cl)
62      {
63          this.resourceName = resourceName;
64          classLoader = cl;
65      }
66  
67      /**
68       * Returns the name of the resource represented by this locator.
69       *
70       * @return the resource's name
71       */
72      public String getResourceName()
73      {
74          return resourceName;
75      }
76  
77      /**
78       * Returns the default class loader used by this locator when looking up the
79       * resource name. This is the class loader passed to the
80       * {@code getInstance()} method. It may be <b>null</b> if no specific class
81       * loader was provided when constructing this object.
82       *
83       * @return the default class loader for resource lookup
84       * @since 1.2
85       */
86      public ClassLoader getClassLoader()
87      {
88          return classLoader;
89      }
90  
91      /**
92       * Returns a {@code ClassPathLocator} instance for the specified
93       * resource name.
94       *
95       * @param resourceName the name of the resource (must not be <b>null</b>)
96       * @return the instance with this resource name
97       * @throws IllegalArgumentException if the resource name is <b>null</b>
98       */
99      public static ClassPathLocator getInstance(String resourceName)
100     {
101         return getInstance(resourceName, null);
102     }
103 
104     /**
105      * Returns a {@code ClassPathLocator} instance which looks up the specified
106      * resource name using the given class loader. If a {@code ClassLoader}
107      * reference is provided, this class loader is tried first when resolving
108      * the resource name. Otherwise, the default order of class loaders is used
109      * as implemented in {@link LocatorUtils}.
110      *
111      * @param resourceName the name of the resource (must not be <b>null</b>)
112      * @param cl an optional class loader to be used for resource lookup
113      * @return the instance with this resource name
114      * @throws IllegalArgumentException if the resource name is <b>null</b>
115      * @since 1.2
116      */
117     public static ClassPathLocator getInstance(String resourceName,
118             ClassLoader cl)
119     {
120         if (resourceName == null)
121         {
122             throw new IllegalArgumentException(
123                     "Resource name must not be null!");
124         }
125 
126         return new ClassPathLocator(resourceName, cl);
127     }
128 
129     /**
130      * Returns the URL for the represented resource. This implementation uses
131      * the {@link LocatorUtils#locateResource(String, ClassLoader)} method to
132      * find the resource on the class path. If this fails, an exception is
133      * thrown.
134      *
135      * @return the URL to the resource
136      * @throws LocatorException if the resource URL cannot be obtained
137      */
138     public URL getURL()
139     {
140         URL result = LocatorUtils.locateResource(getResourceName(), getClassLoader());
141         if (result == null)
142         {
143             throw new LocatorException("Cannot locate resource "
144                     + getResourceName());
145         }
146 
147         return result;
148     }
149 
150     /**
151      * Compares this object with another one. Two instances of this class are
152      * equal if and only if they refer to the same resource name and use the
153      * same default class loader.
154      *
155      * @param obj the object to be compared to
156      * @return a flag whether the objects are equal
157      */
158     @Override
159     public boolean equals(Object obj)
160     {
161         if (this == obj)
162         {
163             return true;
164         }
165         if (!(obj instanceof ClassPathLocator))
166         {
167             return false;
168         }
169 
170         ClassPathLocator c = (ClassPathLocator) obj;
171         return getResourceName().equals(c.getResourceName())
172                 && ObjectUtils.equals(getClassLoader(), c.getClassLoader());
173     }
174 
175     /**
176      * Returns a hash code for this object.
177      *
178      * @return a hash code
179      */
180     @Override
181     public int hashCode()
182     {
183         final int factor = 31;
184         int result = getResourceName().hashCode();
185         if (getClassLoader() != null)
186         {
187             result = factor * result + getClassLoader().hashCode();
188         }
189         return result;
190     }
191 
192     /**
193      * Returns a string representation of this object. This string will at least
194      * contain the resource name used by this locator.
195      *
196      * @return a string for this object
197      */
198     @Override
199     public String toString()
200     {
201         return LocatorUtils.locatorToString(this, "resourceName = "
202                 + getResourceName());
203     }
204 }