![JAR search and dependency download from the Maven repository](/logo.png)
com.jdon.container.pico.JdonConstructorInjectionComponentAdapter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jdonframework Show documentation
Show all versions of jdonframework Show documentation
JdonFramework is a java framework that you can use to build your Domain Driven Design + CQRS + EventSource applications with asynchronous concurrency and higher throughput.
/*
* Copyright 2003-2009 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 com.jdon.container.pico;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.picocontainer.ComponentMonitor;
import org.picocontainer.Parameter;
import org.picocontainer.PicoContainer;
import org.picocontainer.PicoInitializationException;
import org.picocontainer.PicoIntrospectionException;
import org.picocontainer.defaults.AmbiguousComponentResolutionException;
import org.picocontainer.defaults.AssignabilityRegistrationException;
import org.picocontainer.defaults.NotConcreteRegistrationException;
import org.picocontainer.defaults.PicoInvocationTargetInitializationException;
import org.picocontainer.defaults.TooManySatisfiableConstructorsException;
import org.picocontainer.defaults.UnsatisfiableDependenciesException;
import com.jdon.container.ContainerWrapper;
import com.jdon.domain.advsior.ComponentAdvsior;
/**
* Customized ConstructorInjectionComponentAdapter
*
* modify the method getComponentInstance of DefaultPicoContainer of
* picocontainer
*
* @author banq
*
*/
public class JdonConstructorInjectionComponentAdapter extends JdonInstantiatingComponentAdapter {
/**
*
*/
private static final long serialVersionUID = 1L;
protected transient List sortedMatchingConstructors;
protected transient Guard instantiationGuard;
private static abstract class Guard extends JdonThreadLocalCyclicDependencyGuard {
protected PicoContainer guardedContainer;
private void setArguments(PicoContainer container) {
this.guardedContainer = container;
}
}
private ConfigInfo configInfo;
public JdonConstructorInjectionComponentAdapter(Object componentKey, Class componentImplementation, Parameter parameters[],
boolean allowNonPublicClasses, ConfigInfo configInfo) throws AssignabilityRegistrationException, NotConcreteRegistrationException {
super(componentKey, componentImplementation, parameters, allowNonPublicClasses);
this.configInfo = configInfo;
}
public JdonConstructorInjectionComponentAdapter(Object componentKey, Class componentImplementation, Parameter parameters[], ConfigInfo configInfo) {
this(componentKey, componentImplementation, parameters, false, configInfo);
}
public JdonConstructorInjectionComponentAdapter(Object componentKey, Class componentImplementation, ConfigInfo configInf)
throws AssignabilityRegistrationException, NotConcreteRegistrationException {
this(componentKey, componentImplementation, null, configInf);
}
/**
* difference with picocontainer
*/
public Object getComponentInstance(PicoContainer container) throws PicoInitializationException, PicoIntrospectionException,
AssignabilityRegistrationException, NotConcreteRegistrationException {
if (instantiationGuard == null) {
instantiationGuard = new Guard() {
public Object run() {
final Constructor constructor;
try {
constructor = getGreediestSatisfiableConstructor(guardedContainer);
} catch (AmbiguousComponentResolutionException e) {
e.setComponent(getComponentImplementation());
throw e;
}
ComponentMonitor componentMonitor = currentMonitor();
try {
Object[] parameters = getConstructorArguments(guardedContainer, constructor);
componentMonitor.instantiating(constructor);
long startTime = System.currentTimeMillis();
Object inst = newInstance(constructor, parameters);
componentMonitor.instantiated(constructor, System.currentTimeMillis() - startTime);
return inst;
} catch (InvocationTargetException e) {
componentMonitor.instantiationFailed(constructor, e);
if (e.getTargetException() instanceof RuntimeException) {
throw (RuntimeException) e.getTargetException();
} else if (e.getTargetException() instanceof Error) {
throw (Error) e.getTargetException();
}
throw new PicoInvocationTargetInitializationException(e.getTargetException());
} catch (InstantiationException e) {
// can't get here because checkConcrete() will catch it
// earlier, but see PICO-191
// /CLOVER:OFF
componentMonitor.instantiationFailed(constructor, e);
throw new PicoInitializationException("Should never get here");
// /CLOVER:ON
} catch (IllegalAccessException e) {
// can't get here because either filtered or access mode
// set
// /CLOVER:OFF
componentMonitor.instantiationFailed(constructor, e);
throw new PicoInitializationException(e);
// /CLOVER:ON
}
}
};
}
instantiationGuard.setArguments(container);
Object result = instantiationGuard.observe(getComponentImplementation());
instantiationGuard.clear();
return result;
}
// overide InstantiatingComponentAdapter 's newInstance
protected Object newInstance(Constructor constructor, Object[] parameters) throws InstantiationException, IllegalAccessException,
InvocationTargetException {
if (allowNonPublicClasses) {
constructor.setAccessible(true);
}
Object o = constructor.newInstance(parameters);
ComponentAdvsior componentAdvsior = (ComponentAdvsior) configInfo.getContainerWrapper().lookup(ComponentAdvsior.NAME);
Object proxy = null;
if (componentAdvsior != null)
proxy = componentAdvsior.createProxy(o);
if (!proxy.getClass().isInstance(o)) {
Map orignals = getContainerOrignals(configInfo.getContainerWrapper());
orignals.put((String) this.getComponentKey(), o);
}
return proxy;
}
public Map getContainerOrignals(ContainerWrapper containerWrapper) {
Map orignals = (Map) containerWrapper.lookup(ContainerWrapper.OrignalKey);
if (orignals == null) {
orignals = new HashMap();
containerWrapper.register(ContainerWrapper.OrignalKey, orignals);
}
return orignals;
}
public void clear() {
super.clear();
if (instantiationGuard != null) {
instantiationGuard.clear();
}
}
protected Constructor getGreediestSatisfiableConstructor(PicoContainer container) throws PicoIntrospectionException,
UnsatisfiableDependenciesException, AmbiguousComponentResolutionException, AssignabilityRegistrationException,
NotConcreteRegistrationException {
final Set conflicts = new HashSet();
final Set unsatisfiableDependencyTypes = new HashSet();
if (sortedMatchingConstructors == null) {
sortedMatchingConstructors = getSortedMatchingConstructors();
}
Constructor greediestConstructor = null;
int lastSatisfiableConstructorSize = -1;
Class unsatisfiedDependencyType = null;
for (int i = 0; i < sortedMatchingConstructors.size(); i++) {
boolean failedDependency = false;
Constructor constructor = (Constructor) sortedMatchingConstructors.get(i);
Class[] parameterTypes = constructor.getParameterTypes();
Parameter[] currentParameters = parameters != null ? parameters : createDefaultParameters(parameterTypes);
// remember: all constructors with less arguments than the given
// parameters are filtered out already
for (int j = 0; j < currentParameters.length; j++) {
// check wether this constructor is statisfiable
if (currentParameters[j].isResolvable(container, this, parameterTypes[j])) {
continue;
}
unsatisfiableDependencyTypes.add(Arrays.asList(parameterTypes));
unsatisfiedDependencyType = parameterTypes[j];
failedDependency = true;
break;
}
if (greediestConstructor != null && parameterTypes.length != lastSatisfiableConstructorSize) {
if (conflicts.isEmpty()) {
// we found our match [aka. greedy and satisfied]
return greediestConstructor;
} else {
// fits although not greedy
conflicts.add(constructor);
}
} else if (!failedDependency && lastSatisfiableConstructorSize == parameterTypes.length) {
// satisfied and same size as previous one?
conflicts.add(constructor);
conflicts.add(greediestConstructor);
} else if (!failedDependency) {
greediestConstructor = constructor;
lastSatisfiableConstructorSize = parameterTypes.length;
}
}
if (!conflicts.isEmpty()) {
throw new TooManySatisfiableConstructorsException(getComponentImplementation(), conflicts);
} else if (greediestConstructor == null && !unsatisfiableDependencyTypes.isEmpty()) {
throw new UnsatisfiableDependenciesException(this, unsatisfiedDependencyType, unsatisfiableDependencyTypes, container);
} else if (greediestConstructor == null) {
// be nice to the user, show all constructors that were filtered out
final Set nonMatching = new HashSet();
final Constructor[] constructors = getConstructors();
for (int i = 0; i < constructors.length; i++) {
nonMatching.add(constructors[i]);
}
throw new PicoInitializationException("Either do the specified parameters not match any of the following constructors: "
+ nonMatching.toString() + " or the constructors were not accessible for '" + getComponentImplementation() + "'");
}
return greediestConstructor;
}
protected Object[] getConstructorArguments(PicoContainer container, Constructor ctor) {
Class[] parameterTypes = ctor.getParameterTypes();
Object[] result = new Object[parameterTypes.length];
Parameter[] currentParameters = parameters != null ? parameters : createDefaultParameters(parameterTypes);
for (int i = 0; i < currentParameters.length; i++) {
result[i] = currentParameters[i].resolveInstance(container, this, parameterTypes[i]);
}
return result;
}
private List getSortedMatchingConstructors() {
List matchingConstructors = new ArrayList();
Constructor[] allConstructors = getConstructors();
// filter out all constructors that will definately not match
for (int i = 0; i < allConstructors.length; i++) {
Constructor constructor = allConstructors[i];
if ((parameters == null || constructor.getParameterTypes().length == parameters.length)
&& (allowNonPublicClasses || (constructor.getModifiers() & Modifier.PUBLIC) != 0)) {
matchingConstructors.add(constructor);
}
}
// optimize list of constructors moving the longest at the beginning
if (parameters == null) {
Collections.sort(matchingConstructors, new Comparator() {
public int compare(Object arg0, Object arg1) {
return ((Constructor) arg1).getParameterTypes().length - ((Constructor) arg0).getParameterTypes().length;
}
});
}
return matchingConstructors;
}
private Constructor[] getConstructors() {
return (Constructor[]) AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return getComponentImplementation().getDeclaredConstructors();
}
});
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy