View Javadoc

1   /*
2    * Copyright 2012-2013 smartics, Kronseder & Reiner GmbH
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 de.smartics.properties.spi.core.util;
17  
18  import java.net.URL;
19  
20  import de.smartics.util.lang.classpath.ClassPathContext;
21  
22  /**
23   * Utilities dealing with class loaders.
24   */
25  public final class ClassLoaderUtils
26  {
27    // ********************************* Fields *********************************
28  
29    // --- constants ------------------------------------------------------------
30  
31    // --- members --------------------------------------------------------------
32  
33    // ****************************** Initializer *******************************
34  
35    // ****************************** Constructors ******************************
36  
37    private ClassLoaderUtils()
38    {
39    }
40  
41    // ****************************** Inner Classes *****************************
42  
43    // ********************************* Methods ********************************
44  
45    // --- init -----------------------------------------------------------------
46  
47    // --- get&set --------------------------------------------------------------
48  
49    // --- business -------------------------------------------------------------
50  
51    /**
52     * Determines the path to the class loader root that contains the given
53     * {@code type}.
54     *
55     * @param type the type whose class loader root is requested.
56     * @return the class loader root.
57     * @throws NullPointerException if {@code type} is <code>null</code>.
58     */
59    public static String calcArchivePath(final Class<?> type)
60      throws NullPointerException
61    {
62      final ClassLoader loader = type.getClassLoader();
63      final String resource = type.getName().replace('.', '/') + ".class";
64      final String path = calcFirstArchivePath(loader, resource);
65      return path;
66    }
67  
68    /**
69     * Determines the path to the class loader root that contains the given
70     * {@code resource}. The first matching path is returned. This call does not
71     * check if there is more than one path that serves the given {@code resource}
72     * .
73     *
74     * @param loader the loader to load the resource.
75     * @param resource the resource whose class loader root is requested.
76     * @return the class loader root for the given {@code resource}.
77     * @throws NullPointerException if {@code loader} or {@code resource} is
78     *           <code>null</code>.
79     * @throws IllegalArgumentException if the resource cannot be found by the
80     *           given class loader.
81     */
82    public static String calcFirstArchivePath(final ClassLoader loader,
83        final String resource) throws NullPointerException,
84      IllegalArgumentException
85    {
86      final URL url = loader.getResource(resource);
87      if (url == null)
88      {
89        throw new IllegalArgumentException(
90            "The resource '" + resource
91                + "' cannot be found by the given class loader.");
92      }
93      final String urlString = url.toExternalForm();
94      final int endIndex = urlString.length() - resource.length();
95      final String path = urlString.substring(0, endIndex);
96      return path;
97    }
98  
99    /**
100    * Creates the class path context for the given class loader and its derived
101    * context root. The first matching path is used to calculate the class path
102    * root. This call does not check if there is more than one path that serves
103    * the given {@code resource}.
104    *
105    * @param classLoader the class loader to access resources.
106    * @param resource the resource whose class loader root is requested.
107    * @return the class path context.
108    */
109   public static ClassPathContext createClassPathContext(
110       final ClassLoader classLoader, final String resource)
111   {
112     final String root = calcFirstArchivePath(classLoader, resource);
113     return new ClassPathContext(classLoader, root);
114   }
115 
116   // --- object basics --------------------------------------------------------
117 
118 }