KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jfun > yan > InstanceProxy


1 /*****************************************************************************
2  * Copyright (C) Codehaus.org. All rights reserved. *
3  * ------------------------------------------------------------------------- *
4  * The software in this package is published under the terms of the BSD *
5  * style license a copy of which has been included with this distribution in *
6  * the LICENSE.txt file. *
7  *****************************************************************************/

8 /*
9  * Created on Mar 8, 2005
10  *
11  * Author Ben Yu
12  * ZBS
13  */

14 package jfun.yan;
15
16 import java.lang.reflect.InvocationHandler JavaDoc;
17 import java.lang.reflect.Method JavaDoc;
18 import java.lang.reflect.Proxy JavaDoc;
19
20 import jfun.util.Misc;
21 import jfun.yan.factory.Factory;
22
23 /**
24  * Codehaus.org.
25  *
26  * @author Ben Yu
27  *
28  */

29 final class InstanceProxy
30 implements java.lang.reflect.InvocationHandler JavaDoc, Factory{
31   private final Class JavaDoc[] itfs;
32   private final ClassLoader JavaDoc loader;
33   private volatile Object JavaDoc v;
34   private final Factory factory;
35   private void set(Object JavaDoc obj){
36     v = obj;
37   }
38   /**
39    * @param cc
40    */

41   private InstanceProxy(Factory factory, Class JavaDoc[] itfs, ClassLoader JavaDoc cl,
42       Object JavaDoc v) {
43     this.factory = factory;
44     this.itfs = itfs;
45     this.loader = cl;
46     this.v = v ;
47   }
48   public synchronized Object JavaDoc create(){
49     if(v==null){
50       v = factory.create();
51     }
52     return v;
53   }
54   public synchronized void clear(){
55     v = null;
56   }
57   public synchronized Object JavaDoc invoke(Object JavaDoc proxy, Method JavaDoc mtd, Object JavaDoc[] args)
58       throws Throwable JavaDoc {
59     try{
60       if(Object JavaDoc.class.equals(mtd.getDeclaringClass())){
61         return mtd.invoke(this, args);
62       }
63       else{
64         return mtd.invoke(create(), args);
65       }
66     }
67     catch(java.lang.reflect.InvocationTargetException JavaDoc e){
68       throw e.getTargetException();
69     }
70   }
71   static Object JavaDoc instance(ClassLoader JavaDoc cl, Class JavaDoc[] itfs, Factory factory){
72     final Class JavaDoc[] myitfs = copy(itfs);
73     return Proxy.newProxyInstance(cl,
74         myitfs, new InstanceProxy(factory, myitfs, cl, null));
75   }
76   static Class JavaDoc getProxyClass(ClassLoader JavaDoc cl, Class JavaDoc[] itfs){
77     return Proxy.getProxyClass(cl, itfs);
78   }
79   private Object JavaDoc getComparisonTarget(Object JavaDoc other){
80     if(other instanceof InstanceProxy){
81       final InstanceProxy p2 = (InstanceProxy)other;
82       return p2.create();
83     }
84     if(other instanceof Proxy JavaDoc){
85       return getComparisonTarget(Proxy.getInvocationHandler(other));
86     }
87     return other;
88   }
89   public boolean equals(Object JavaDoc other) {
90     final Object JavaDoc v1 = create();
91     final Object JavaDoc v2 = getComparisonTarget(other);
92     return v1==null?(v2==null):v1.equals(v2);
93   }
94   public int hashCode() {
95     final Object JavaDoc v1 = create();
96     return v1==null?0:v1.hashCode();
97   }
98   public String JavaDoc toString() {
99     return ""+create();
100   }
101   static boolean setImplementation(Object JavaDoc proxy, Object JavaDoc obj){
102     if(!Proxy.isProxyClass(proxy.getClass())) return false;
103     final InvocationHandler JavaDoc ih = Proxy.getInvocationHandler(proxy);
104     if(ih instanceof InstanceProxy){
105       final InstanceProxy ip = (InstanceProxy)ih;
106       checkTypes(ip.itfs, obj);
107       ip.set(obj);
108       return true;
109     }
110     else return false;
111   }
112   static void clear(Object JavaDoc proxy){
113     if(!Proxy.isProxyClass(proxy.getClass())) return;
114     final InvocationHandler JavaDoc ih = Proxy.getInvocationHandler(proxy);
115     if(ih instanceof InstanceProxy){
116       final InstanceProxy ip = (InstanceProxy)ih;
117       ip.clear();
118     }
119   }
120   private static Class JavaDoc[] copy(Class JavaDoc[] types){
121     final Class JavaDoc[] ret = new Class JavaDoc[types.length];
122     for(int i=0; i<types.length; i++){
123       ret[i] = types[i];
124     }
125     return ret;
126   }
127   private static void checkTypes(Class JavaDoc[] types, Object JavaDoc obj){
128     for(int i=0; i<types.length; i++){
129       final Class JavaDoc type = types[i];
130       if(!type.isInstance(obj)){
131         throw new IllegalArgumentException JavaDoc("object of type "
132             + Misc.getTypeName(Utils.getObjType(obj))
133             + " is not an instance of " + Misc.getTypeName(type));
134       }
135     }
136   }
137 }
138
Popular Tags