package org.xpect.registry; import org.xpect.util.ExtensionFactoryUtil; import org.xpect.util.ExtensionFactoryUtil.NameAndClass; import com.google.common.base.Function; import com.google.common.base.Objects; public class LazyClass<T> { public static <T> LazyClass<T> create(Class<T> expectedType, IExtensionInfo trace, String attributeName) { String className = trace.getAttributeValue(attributeName); if (className != null) return new LazyClass<T>(expectedType, className, trace.getClassLoader(), trace); return null; } public static <T> LazyClass<T> create(Class<T> expectedType, String name, Function<String, Class<?>> loader) { if (name != null) return new LazyClass<T>(expectedType, name, loader, null); return null; } public static <T> LazyClass<T> create(Class<T> expectedType, String name, IExtensionInfo trace) { if (name != null) return new LazyClass<T>(expectedType, name, trace.getClassLoader(), trace); return null; } private final Class<T> expectedType; private final String factory; private final Function<String, Class<?>> loader; private final String name; private final IExtensionInfo trace; protected LazyClass(Class<T> expectedType, String name, Function<String, Class<?>> loader, IExtensionInfo trace) { super(); NameAndClass nameAndClass = ExtensionFactoryUtil.parseExtensionFactory(name); this.expectedType = expectedType; this.name = nameAndClass.getClazz(); this.factory = nameAndClass.getUiLangName(); this.loader = loader; this.trace = trace; } @Override public boolean equals(Object obj) { if (obj == null || getClass() != obj.getClass()) return false; LazyClass<?> other = (LazyClass<?>) obj; return Objects.equal(name, other.name); } public Class<T> getExpectedType() { return expectedType; } public String getFactory() { return factory; } public Function<String, Class<?>> getLoader() { return loader; } public String getName() { return name; } public IExtensionInfo getTrace() { return trace; } @Override public int hashCode() { return name.hashCode(); } @SuppressWarnings("unchecked") public Class<T> load() { Class<?> clazz = loader.apply(name); if (expectedType.isAssignableFrom(clazz)) return (Class<T>) clazz; throw new ClassCastException("Class " + clazz.getName() + " is not a subtype of " + expectedType.getName()); } public boolean needsInjection() { return this.factory != null; } @Override public String toString() { return name; } }