001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2010–2011 ApexIdentity Inc. 015 * Portions Copyright 2011-2015 ForgeRock AS. 016 */ 017 018package org.forgerock.http.util; 019 020import java.net.URL; 021import java.util.ArrayList; 022import java.util.HashMap; 023import java.util.List; 024import java.util.Map; 025import java.util.ServiceLoader; 026 027/** 028 * Provides methods for dynamically loading classes. 029 */ 030public final class Loader { 031 032 /** Static methods only. */ 033 private Loader() { 034 } 035 036 /** 037 * Returns the class loader that should be used consistently throughout the application. 038 * 039 * @return the class loader that should be used consistently throughout the application. 040 */ 041 public static ClassLoader getClassLoader() { 042 return Thread.currentThread().getContextClassLoader(); 043 } 044 045 /** 046 * Returns the {@code Class} object associated with the class or interface with the given 047 * name, or {@code null} if the class could not be returned for any reason. 048 * 049 * @param name the fully qualified name of the desired class. 050 * @return the Class object for the class with the specified name. 051 */ 052 public static Class<?> getClass(String name) { 053 try { 054 return Class.forName(name, true, getClassLoader()); 055 } catch (Throwable t) { 056 return null; 057 } 058 } 059 060 /** 061 * Creates a new instance of a named class. The class is instantiated as if by a 062 * {@code new} expression with an empty argument list. If the class cannot be instantiated 063 * for any reason, {@code null} is returned. 064 * 065 * @param name the fully qualified name of the class to instantiate. 066 * @return the newly instantiated object, or {@code null} if it could not be instantiated. 067 */ 068 public static Object newInstance(String name) { 069 try { 070 return getClass(name).newInstance(); 071 } catch (Throwable t) { 072 return null; 073 } 074 } 075 076 /** 077 * Creates a new instance of a named class. The class is instantiated as if by a 078 * {@code new} expression with an empty argument list. If the class cannot be instantiated 079 * for any reason, {@code null} is returned. 080 * 081 * @param name the fully qualified name of the class to instantiate. 082 * @param type the class of the type of object to instantiate. 083 * @param <T> class type 084 * @return the newly instantiated object, or {@code null} if it could not be instantiated. 085 */ 086 @SuppressWarnings("unchecked") 087 public static <T> T newInstance(String name, Class<T> type) { 088 Object object = newInstance(name); 089 if (object != null && !type.isInstance(object)) { 090 object = null; 091 } 092 return (T) object; 093 } 094 095 /** 096 * Loads services of a particular type into a map. Such services implement the 097 * {@link Indexed} interface to provide a key to index the service by in the map. 098 * 099 * @param keyType the class type of the key to be indexed in the map. 100 * @param serviceType the class type of services to load. 101 * @param <K> key type 102 * @param <V> service type 103 * @return a map containing the loaded services, indexed by the services' keys. 104 */ 105 public static <K, V extends Indexed<K>> Map<K, V> loadMap(Class<K> keyType, Class<V> serviceType) { 106 HashMap<K, V> map = new HashMap<>(); 107 for (V v : ServiceLoader.load(serviceType, getClassLoader())) { 108 map.put(v.getKey(), v); 109 } 110 return map; 111 } 112 113 /** 114 * Loads services of a particular type into a list. 115 * 116 * @param serviceType the class type of services to load. 117 * @param <E> service type 118 * @return a list containing the loaded services. 119 */ 120 public static <E> List<E> loadList(Class<E> serviceType) { 121 ArrayList<E> list = new ArrayList<>(); 122 for (E e : ServiceLoader.load(serviceType, getClassLoader())) { 123 list.add(e); 124 } 125 return list; 126 } 127 128 /** 129 * Finds the resource with the given name. 130 * 131 * @param name the resource name. 132 * @return A {@code URL} object for reading the resource, or {@code null} if the resource could not be found. 133 * @see ClassLoader#getResource(java.lang.String) 134 */ 135 public static URL getResource(String name) { 136 return getClassLoader().getResource(name); 137 } 138}