001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019 020package org.apache.isis.core.commons.factory; 021 022import org.apache.isis.core.commons.ensure.Assert; 023import org.apache.isis.core.commons.lang.ObjectExtensions; 024 025public final class InstanceUtil { 026 027 private InstanceUtil() { 028 } 029 030 public static Object createInstance(final String className) { 031 return createInstance(className, (Class<?>) null, null); 032 } 033 034 public static Object createInstance(final Class<?> cls) { 035 return createInstance(cls, (Class<?>) null, null); 036 } 037 038 public static <T> T createInstance(final String className, final Class<T> requiredClass) { 039 return createInstance(className, (Class<T>) null, requiredClass); 040 } 041 042 public static <T> T createInstance(final Class<?> cls, final Class<T> requiredClass) { 043 return createInstance(cls, (Class<T>) null, requiredClass); 044 } 045 046 public static <T> T createInstance(final String className, final String defaultTypeName, final Class<T> requiredType) { 047 Class<? extends T> defaultType = null; 048 if (defaultTypeName != null) { 049 try { 050 defaultType = ObjectExtensions.asT(Thread.currentThread().getContextClassLoader().loadClass(defaultTypeName)); 051 if (defaultType == null) { 052 throw new InstanceCreationClassException("Failed to load default type '" + defaultTypeName + "'"); 053 } 054 } catch (final ClassNotFoundException e) { 055 throw new UnavailableClassException("The default type '" + defaultTypeName + "' cannot be found"); 056 } catch (final NoClassDefFoundError e) { 057 throw new InstanceCreationClassException("Default type '" + defaultTypeName + "' found, but is missing a dependent class: " + e.getMessage(), e); 058 } 059 } 060 return createInstance(className, defaultType, requiredType); 061 } 062 063 public static <T> T createInstance(final Class<?> cls, final String defaultTypeName, final Class<T> requiredType) { 064 Class<? extends T> defaultType = null; 065 if (defaultTypeName != null) { 066 defaultType = loadClass(defaultTypeName, requiredType); 067 try { 068 defaultType = ObjectExtensions.asT(Thread.currentThread().getContextClassLoader().loadClass(defaultTypeName)); 069 if (defaultType == null) { 070 throw new InstanceCreationClassException("Failed to load default type '" + defaultTypeName + "'"); 071 } 072 } catch (final ClassNotFoundException e) { 073 throw new UnavailableClassException("The default type '" + defaultTypeName + "' cannot be found"); 074 } catch (final NoClassDefFoundError e) { 075 throw new InstanceCreationClassException("Default type '" + defaultTypeName + "' found, but is missing a dependent class: " + e.getMessage(), e); 076 } 077 } 078 return createInstance(cls, defaultType, requiredType); 079 } 080 081 public static <T> T createInstance(final String className, final Class<? extends T> defaultType, final Class<T> requiredType) { 082 Assert.assertNotNull("Class to instantiate must be specified", className); 083 Class<?> cls = null; 084 try { 085 cls = Thread.currentThread().getContextClassLoader().loadClass(className); 086 if (cls == null) { 087 throw new InstanceCreationClassException("Failed to load class '" + className + "'"); 088 } 089 return createInstance(cls, defaultType, requiredType); 090 } catch (final ClassNotFoundException e) { 091 if (className.indexOf('.') == -1) { 092 throw new UnavailableClassException("The component '" + className + "' cannot be found"); 093 } 094 throw new UnavailableClassException("The class '" + className + "' cannot be found"); 095 } catch (final NoClassDefFoundError e) { 096 throw new InstanceCreationClassException("Class '" + className + "' found , but is missing a dependent class: " + e.getMessage(), e); 097 } 098 } 099 100 public static <T> T createInstance(final Class<?> cls, final Class<? extends T> defaultType, final Class<T> requiredType) { 101 Assert.assertNotNull("Class to instantiate must be specified", cls); 102 try { 103 if (requiredType == null || requiredType.isAssignableFrom(cls)) { 104 final Class<T> tClass = ObjectExtensions.asT(cls); 105 return tClass.newInstance(); 106 } else { 107 throw new InstanceCreationClassException("Class '" + cls.getName() + "' is not of type '" + requiredType + "'"); 108 } 109 } catch (final NoClassDefFoundError e) { 110 throw new InstanceCreationClassException("Class '" + cls + "'found , but is missing a dependent class: " + e.getMessage(), e); 111 } catch (final InstantiationException e) { 112 throw new InstanceCreationException("Could not instantiate an object of class '" + cls.getName() + "'; " + e.getMessage()); 113 } catch (final IllegalAccessException e) { 114 throw new InstanceCreationException("Could not access the class '" + cls.getName() + "'; " + e.getMessage()); 115 } 116 } 117 118 public static Class<?> loadClass(final String className) { 119 Assert.assertNotNull("Class to instantiate must be specified", className); 120 try { 121 return Thread.currentThread().getContextClassLoader().loadClass(className); 122 } catch (final ClassNotFoundException e) { 123 throw new UnavailableClassException("The default type '" + className + "' cannot be found"); 124 } catch (final NoClassDefFoundError e) { 125 throw new InstanceCreationClassException("Default type '" + className + "' found, but is missing a dependent class: " + e.getMessage(), e); 126 } 127 } 128 129 public static <R, T extends R> Class<T> loadClass(final String className, final Class<R> requiredType) { 130 Assert.assertNotNull("Class to instantiate must be specified", className); 131 try { 132 final Class<?> loadedClass = loadClass(className); 133 if (requiredType != null && !requiredType.isAssignableFrom(loadedClass)) { 134 throw new InstanceCreationClassException("Class '" + className + "' is not of type '" + requiredType + "'"); 135 } 136 return ObjectExtensions.asT(loadedClass); 137 } catch (final NoClassDefFoundError e) { 138 throw new InstanceCreationClassException("Default type '" + className + "' found, but is missing a dependent class: " + e.getMessage(), e); 139 } 140 } 141 142}