X-Git-Url: http://wamblee.org/gitweb/?a=blobdiff_plain;f=system%2Fgeneral%2Fsrc%2Fmain%2Fjava%2Forg%2Fwamblee%2Fsystem%2Fadapters%2FConstructorConfiguration.java;h=4e22bc5ff3249ffd1d349f78f2e393d5d130a66c;hb=8de36ff0206c996baf3ee4adc3e2293b12ff5f39;hp=9050b9557fcb4a5428a836f98a227b6fb2e56e3c;hpb=0d8d8f24656e585ee75558cfd6a4c661f8f14985;p=utils diff --git a/system/general/src/main/java/org/wamblee/system/adapters/ConstructorConfiguration.java b/system/general/src/main/java/org/wamblee/system/adapters/ConstructorConfiguration.java index 9050b955..4e22bc5f 100644 --- a/system/general/src/main/java/org/wamblee/system/adapters/ConstructorConfiguration.java +++ b/system/general/src/main/java/org/wamblee/system/adapters/ConstructorConfiguration.java @@ -1,179 +1,205 @@ /* * Copyright 2008 the original author or authors. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - */ + */ package org.wamblee.system.adapters; -import java.lang.reflect.Constructor; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - import org.wamblee.collections.CollectionFilter; + import org.wamblee.conditions.Condition; + import org.wamblee.system.core.RequiredInterface; import org.wamblee.system.core.Scope; import org.wamblee.system.core.SystemAssemblyException; +import java.lang.reflect.Constructor; +import java.lang.reflect.Modifier; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + /** - * Class that allows configuration of the constructor to use. - * - * In particular, it provides: + * Class that allows configuration of the constructor to use. In particular, it + * provides: * */ public class ConstructorConfiguration { - private Class clazz; - private Constructor constructor; - private ParameterValues values; - private boolean publicOnly; - - /** - * Constructs the configuration. By default the public constructor with the - * most arguments will be used. - * @param aClass Class to construct. - */ - public ConstructorConfiguration(Class aClass) { - clazz = aClass; - constructor = null; - publicOnly = true; - } - - /** - * Sets whether or no non public constructors are also considered. - * Reset the choice of a constructor to its default. - * @param aNonPublic - * @return - */ - public ConstructorConfiguration setNonPublic(boolean aNonPublic) { - publicOnly = !aNonPublic; - constructor = null; - values = null; - return this; - } - - /** - * Selects an explicit constructor. - * @param aTypes Arguments of the constructor. - * @return Return the injector to allow call chaining. - */ - public ConstructorConfiguration select(Class... aTypes) { - try { - constructor = clazz.getDeclaredConstructor(aTypes); - } catch (Exception e) { - throw new SystemAssemblyException(e.getMessage(), e); - } - resetValues(); - return this; - } - - /** - * Selects the greediest constructor. - * @return The injector to allow call chaining. - * @throws SystemAssemblyException if the greediest constructor cannot be uniquely - * identified. - */ - public ConstructorConfiguration greedy() { - Constructor[] declared = clazz.getDeclaredConstructors(); - if (declared.length == 0) { - throw new SystemAssemblyException("Class '" + clazz - + " is an interface, primitive type, or array"); - } - int max = -1; - List> checked = new ArrayList>(); - CollectionFilter.filter(Arrays.asList(declared), checked, - new Condition>() { - @Override - public boolean matches(Constructor aObject) { - if ( !publicOnly ) { - return true; - } else { - return Modifier.isPublic(aObject.getModifiers()); - } - } - }); - for (Constructor ctor : checked) { - if (ctor.getParameterTypes().length > max) { - max = ctor.getParameterTypes().length; - } - } - final int max2 = max; - List> ctors = checked; - List> longest = new ArrayList>(); - CollectionFilter.filter(ctors, longest, - new Condition>() { - @Override - public boolean matches(Constructor aObject) { - return aObject.getParameterTypes().length == max2; - } - }); - if (longest.size() > 1) { - throw new SystemAssemblyException( - "Greediest constructor cannot be uniquely determined"); - } - constructor = longest.get(0); - resetValues(); - return this; - } - - public ParameterValues getParameters() { - getConstructor(); // initialize constructor if needed. - return values; - } - - /** - * Resets the values. - */ - private void resetValues() { - constructor.setAccessible(true); - values = new ParameterValues(constructor.getParameterTypes()); - } - - /** - * Creates the object in the given scope. - * @param aScope Scope containing required interfaces for this object. - * @return object. - */ - public Object create(Scope aScope) { - Object[] valueArray = values.values(aScope); - try { - return getConstructor().newInstance(valueArray); - } catch (Exception e) { - throw new SystemAssemblyException("Could not construct object " - + getConstructor() + " " + Arrays.asList(valueArray), e); - } - } - - public List getRequiredInterfaces() { - getConstructor(); // initialize constructor if needed. - return values.getRequiredInterfaces(); - } - - private Constructor getConstructor() { - if (constructor == null ) { - greedy(); - } - return constructor; - } + private Class clazz; + + private Constructor constructor; + + private ParameterValues values; + + private boolean publicOnly; + + /** + * Constructs the configuration. By default the public constructor with the + * most arguments will be used. + * + * @param aClass + * Class to construct. + */ + public ConstructorConfiguration(Class aClass) { + clazz = aClass; + constructor = null; + publicOnly = true; + } + + /** + * Sets whether or no non public constructors are also considered. Reset the + * choice of a constructor to its default. + * + * @param aNonPublic + * + * @return + */ + public ConstructorConfiguration setNonPublic(boolean aNonPublic) { + publicOnly = !aNonPublic; + constructor = null; + values = null; + + return this; + } + + /** + * Selects an explicit constructor. + * + * @return Return the injector to allow call chaining. + * + */ + public ConstructorConfiguration select(Class... aTypes) { + try { + constructor = clazz.getDeclaredConstructor(aTypes); + } catch (Exception e) { + throw new SystemAssemblyException(e.getMessage(), e); + } + + resetValues(); + + return this; + } + + /** + * Selects the greediest constructor. + * + * @return The injector to allow call chaining. + * + * @throws SystemAssemblyException + * if the greediest constructor cannot be uniquely identified. + */ + public ConstructorConfiguration greedy() { + Constructor[] declared = clazz.getDeclaredConstructors(); + + if (declared.length == 0) { + throw new SystemAssemblyException("Class '" + clazz + + " is an interface, primitive type, or array"); + } + + int max = -1; + List> checked = new ArrayList>(); + CollectionFilter.filter(Arrays.asList(declared), checked, + new Condition>() { + @Override + public boolean matches(Constructor aObject) { + if (!publicOnly) { + return true; + } else { + return Modifier.isPublic(aObject.getModifiers()); + } + } + }); + + for (Constructor ctor : checked) { + if (ctor.getParameterTypes().length > max) { + max = ctor.getParameterTypes().length; + } + } + + final int max2 = max; + List> ctors = checked; + List> longest = new ArrayList>(); + CollectionFilter.filter(ctors, longest, + new Condition>() { + @Override + public boolean matches(Constructor aObject) { + return aObject.getParameterTypes().length == max2; + } + }); + + if (longest.size() > 1) { + throw new SystemAssemblyException( + "Greediest constructor cannot be uniquely determined"); + } + + constructor = longest.get(0); + resetValues(); + + return this; + } + + public ParameterValues getParameters() { + getConstructor(); // initialize constructor if needed. + + return values; + } + + /** + * Resets the values. + */ + private void resetValues() { + constructor.setAccessible(true); + values = new ParameterValues(constructor.getParameterTypes()); + } + + /** + * Creates the object in the given scope. + * + * @param aScope + * Scope containing required interfaces for this object. + * + * @return object. + * + */ + public Object create(Scope aScope) { + Object[] valueArray = values.values(aScope); + + try { + return getConstructor().newInstance(valueArray); + } catch (Exception e) { + throw new SystemAssemblyException("Could not construct object " + + getConstructor() + " " + Arrays.asList(valueArray), e); + } + } + + public List getRequiredInterfaces() { + getConstructor(); // initialize constructor if needed. + + return values.getRequiredInterfaces(); + } + + private Constructor getConstructor() { + if (constructor == null) { + greedy(); + } + + return constructor; + } }