/*****************************************************************************
* Copyright (C) Codehaus.org. All rights reserved. *
* ------------------------------------------------------------------------- *
* The software in this package is published under the terms of the BSD *
* style license a copy of which has been included with this distribution in *
* the LICENSE.txt file. *
*****************************************************************************/
/*
* Created on Apr 5, 2005
*
* Author Ben Yu
* ZBS
*/
package jfun.yan;
import jfun.util.Misc;
import jfun.util.StringUtils;
import jfun.yan.factory.Factory;
import jfun.yan.util.ReflectionUtil;
/**
* Codehaus.org.
*
* @author Ben Yu
*
*/
final class ProxyComponent extends DelegatingComponent {
private final Class[] itfs;
private final ClassLoader cl;
private transient Class proxyType;
ProxyComponent(Component cc, final Class[] itfs,
final ClassLoader cl) {
super(cc);
this.itfs = itfs;
this.cl = cl;
this.proxyType = InstanceProxy.getProxyClass(cl, itfs);
}
private void readObject(java.io.ObjectInputStream in)
throws java.io.IOException, ClassNotFoundException{
in.defaultReadObject();
this.proxyType = InstanceProxy.getProxyClass(this.cl, this.itfs);
}
public boolean isConcrete(){
return true;
}
public Class getType(){
return proxyType;
}
public String toString(){
return "proxy <" + getDelegateTarget() +">";
}
public Object create(final Dependency dep){
return InstanceProxy.instance(cl, itfs, new Factory(){
public Object create(){
return getDelegateTarget().create(dep);
}
});
}
public Class verify(final Dependency dep){
//laziness requires that the verification cannot be cascaded.
//otherwise, circular dependency can still cause problem.
return getType();
}
public Component singleton(){
return Components.singleton(this);
/*
return new Component(){
private Object cached = null;
public Class getType() {
return proxyType;
}
public synchronized Object create(final Dependency dep){
if(cached!=null){
InstanceProxy.clear(cached);
}
else{
cached = ProxyComponent.this.creat(dep);
}
return cached;
}
public boolean isConcrete() {
return true;
}
public boolean isSingleton() {
return true;
}
public Component singleton(){
return this;
}
public Class verify(Dependency dep) throws IrresolveableArgumentException, ParameterTypeMismatchException, AmbiguousComponentResolutionException, YanException {
getDelegateTarget().verify(dep);
return proxyType;
}
public String toString(){
return ProxyComponent.this.toString();
}
};*/
}
/*
public Component singleton(final Pool scope){
//return Components.singleton(this);
return new Component(){
public Class getType() {
return proxyType;
}
public Object create(final Dependency dep){
final boolean[] evaluated ={false};
final Object proxy = scope.getInstance(new ObjectReference(){
public Object get(){
evaluated[0] = true;
return ProxyComponent.this.create(dep);
}
});
if(!evaluated[0]){
InstanceProxy.clear(proxy);
}
return proxy;
}
public boolean isConcrete() {
return true;
}
public boolean isSingleton() {
return false;
}
public Class verify(Dependency dep) throws IrresolveableArgumentException, ParameterTypeMismatchException, AmbiguousComponentResolutionException, YanException {
getDelegateTarget().verify(dep);
return proxyType;
}
public String toString(){
return ProxyComponent.this.toString();
}
};
}*/
/*
protected Component decorate(final Component c){
return Components.proxy(c, itfs);
}*/
public Component proxy(){
return this;
}
public Component proxy(Class itf){
return proxy(new Class[]{itf});
}
public Component proxy(Class[] itfs2){
boolean act = false;
for(int i=0; i<itfs2.length; i++){
final Class itf2 = itfs2[i];
final int among = contains(itfs, itf2);
if(among < 0){//mismatch
throw new IllegalArgumentException("type "
+ Misc.getTypeName(itf2)
+ " is not a super type of any of "
+ StringUtils.listString("[", ",", "]", itfs));
}
if(among > 0) //if any one is a super type, proxy is needed.
act = true;
}
//x.proxy(A.class).proxy(A.class) is equivalent to x.proxy(A.class)
return act?Components.proxy(this, itfs2): this;
}
private int contains(Class[] types, Class type){
for(int i=0; i<types.length; i++){
if(type.equals(types[i])){
return 0;
}
if(ReflectionUtil.isAssignableFrom(type, types[i])){
return 1;
}
}
return -1;
}
}