// Copyright (c) 2003-present, Jodd Team (http://jodd.org) // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. package jodd.petite; import jodd.introspector.PropertyDescriptor; import jodd.paramo.MethodParameter; import jodd.paramo.Paramo; import jodd.util.StringUtil; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Constructor; import java.lang.reflect.Method; /** * Factory for injection points. Responsible also for * resolving default references when none specified. */ public class InjectionPointFactory { protected final PetiteConfig petiteConfig; public InjectionPointFactory(PetiteConfig petiteConfig) { this.petiteConfig = petiteConfig; } /** * Creates new ctor injection point. */ public CtorInjectionPoint createCtorInjectionPoint(Constructor constructor, String[][] references) { if (references == null || references.length == 0) { references = methodOrCtorDefaultReferences(constructor, constructor.getParameterTypes()); } if (constructor.getParameterTypes().length != references.length) { throw new PetiteException( "Different number of constructor parameters and references for: " + constructor.getName()); } removeDuplicateNames(references); return new CtorInjectionPoint(constructor, references); } /** * Creates new method injection point. */ public MethodInjectionPoint createMethodInjectionPoint(Method method, String[][] references) { if (references == null || references.length == 0) { references = methodOrCtorDefaultReferences(method, method.getParameterTypes()); } if (method.getParameterTypes().length != references.length) { throw new PetiteException("Different number of method parameters and references for: " + method.getDeclaringClass().getName() + '#' + method.getName()); } removeDuplicateNames(references); return new MethodInjectionPoint(method, references); } /** * Creates new property injection point. */ public PropertyInjectionPoint createPropertyInjectionPoint(PropertyDescriptor propertyDescriptor, String[] references) { if (references == null || references.length == 0) { references = fieldDefaultReferences(propertyDescriptor); } removeDuplicateNames(references); return new PropertyInjectionPoint(propertyDescriptor, references); } /** * Creates new set injection point. */ public SetInjectionPoint createSetInjectionPoint(PropertyDescriptor propertyDescriptor) { return new SetInjectionPoint(propertyDescriptor); } // ---------------------------------------------------------------- utils /** * Builds default field references. */ protected String[] fieldDefaultReferences(PropertyDescriptor propertyDescriptor) { PetiteReference[] lookupReferences = petiteConfig.getLookupReferences(); String[] references = new String[lookupReferences.length]; for (int i = 0; i < references.length; i++) { switch (lookupReferences[i]) { case NAME: references[i] = propertyDescriptor.getName(); break; case TYPE_SHORT_NAME: references[i] = StringUtil.uncapitalize(propertyDescriptor.getType().getSimpleName()); break; case TYPE_FULL_NAME: references[i] = propertyDescriptor.getType().getName(); break; } } return references; } /** * Builds default method references. */ protected String[][] methodOrCtorDefaultReferences(AccessibleObject accobj, Class[] paramTypes) { PetiteReference[] lookupReferences = petiteConfig.getLookupReferences(); MethodParameter[] methodParameters = null; if (petiteConfig.getUseParamo()) { methodParameters = Paramo.resolveParameters(accobj); } String[][] references = new String[paramTypes.length][]; for (int j = 0; j < paramTypes.length; j++) { String[] ref = new String[lookupReferences.length]; references[j] = ref; for (int i = 0; i < ref.length; i++) { switch (lookupReferences[i]) { case NAME: ref[i] = methodParameters != null ? methodParameters[j].getName() : null; break; case TYPE_SHORT_NAME: ref[i] = StringUtil.uncapitalize(paramTypes[j].getSimpleName()); break; case TYPE_FULL_NAME: ref[i] = paramTypes[j].getName(); break; } } } return references; } protected void removeDuplicateNames(String[][] referencesArr) { for (String[] references : referencesArr) { removeDuplicateNames(references); } } /** * Removes later duplicated references. */ protected void removeDuplicateNames(String[] references) { if (references.length < 2) { return; } for (int i = 1; i < references.length; i++) { String thisRef = references[i]; if (thisRef == null) { continue; } for (int j = 0; j < i; j++) { if (references[j] == null) { continue; } if (thisRef.equals(references[j])) { references[i] = null; break; } } } } }