KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > hivemind > impl > ProxyBuilder


1 // Copyright 2004, 2005 The Apache Software Foundation
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15 package org.apache.hivemind.impl;
16
17 import java.io.Serializable JavaDoc;
18 import java.lang.reflect.Modifier JavaDoc;
19
20 import org.apache.hivemind.internal.Module;
21 import org.apache.hivemind.internal.ser.ServiceSerializationHelper;
22 import org.apache.hivemind.service.BodyBuilder;
23 import org.apache.hivemind.service.ClassFab;
24 import org.apache.hivemind.service.ClassFabUtils;
25 import org.apache.hivemind.service.ClassFactory;
26 import org.apache.hivemind.service.MethodIterator;
27 import org.apache.hivemind.service.MethodSignature;
28
29 /**
30  * Class used to assist extension points in creating proxies.
31  *
32  * @author Howard Lewis Ship
33  */

34 public final class ProxyBuilder
35 {
36     private Class JavaDoc _serviceInterface;
37
38     private ClassFab _classFab;
39
40     private String JavaDoc _type;
41
42     /**
43      * Constructs a new builder. The type will be incorporated into value returned by the
44      * <code>toString()</code> method.
45      * The generated proxy has an constructor that expects the extension point id as single parameter.
46      *
47      * @param type
48      * used as part of the <code>toString()</code> method's return value
49      * @param module
50      * the module that constructs the proxy
51      * @param serviceInterface
52      * the interface of the proxied class.
53      * @param declaredInterface
54      * the interface of the proxied class or the class itself if the proxied class is actually a POJO.
55      * @param outerProxy
56      * if false, then the proxy can extend the configuration points service interface always.
57      * If true and the declared interface is actually a bean class (not
58      * an interface), then the proxy will be a subclass of that bean.
59      */

60     public ProxyBuilder(String JavaDoc type, Module module, Class JavaDoc serviceInterface, Class JavaDoc declaredInterface, boolean outerProxy)
61     {
62         _type = type;
63         _serviceInterface = serviceInterface;
64
65         ClassFactory factory = (ClassFactory) module.getService(
66                 "hivemind.ClassFactory",
67                 ClassFactory.class);
68
69         boolean extendBeanClass = outerProxy && !declaredInterface.isInterface();
70         Class JavaDoc baseClass = extendBeanClass ? declaredInterface : Object JavaDoc.class;
71
72         _classFab = factory.newClass(ClassFabUtils.generateClassName(_serviceInterface), baseClass);
73
74         _classFab.addField("_extensionPointId", String JavaDoc.class);
75         
76         _classFab.addConstructor(new Class JavaDoc[] { String JavaDoc.class }, null, "{ _extensionPointId = $1; }");
77         
78         if (!extendBeanClass)
79             _classFab.addInterface(_serviceInterface);
80
81         // Not exactly certain this will work with non-interface beans that already
82
// are serializable!
83

84         if (outerProxy)
85             addSerializable();
86     }
87
88     /** @since 1.1 */
89     private void addSerializable()
90     {
91         _classFab.addInterface(Serializable JavaDoc.class);
92
93         BodyBuilder bb = new BodyBuilder();
94
95         bb.add(
96                 "return {0}.getServiceSerializationSupport().getServiceTokenForService(_extensionPointId);",
97                 ServiceSerializationHelper.class.getName());
98
99         MethodSignature sig = new MethodSignature(Object JavaDoc.class, "writeReplace", null, null);
100
101         _classFab.addMethod(Modifier.PRIVATE, sig, bb.toString());
102     }
103
104     public ClassFab getClassFab()
105     {
106         return _classFab;
107     }
108     
109     /**
110      * @see #addServiceMethods(String, boolean)
111      */

112     public void addServiceMethods(String JavaDoc indirection)
113     {
114         addServiceMethods(indirection, true);
115     }
116
117     /**
118      * Creates the service methods for the class.
119      *
120      * @param indirection
121      * the name of a variable, or a method invocation snippet, used to redirect the
122      * invocation on the proxy to the actual service implementation.
123      * @param addToString if true, a implementation of the toString method is generated that
124      * returns some info about the proxy
125      */

126     public void addServiceMethods(String JavaDoc indirection, boolean addToString)
127     {
128         BodyBuilder builder = new BodyBuilder();
129
130         MethodIterator mi = new MethodIterator(_serviceInterface);
131         while (mi.hasNext())
132         {
133             MethodSignature m = mi.next();
134             if( !_classFab.containsMethod( m ) )
135             {
136                 builder.clear();
137                 builder.begin();
138                 builder.add("return ($r) ");
139                 builder.add(indirection);
140                 builder.add(".");
141                 builder.add(m.getName());
142                 builder.addln("($$);");
143                 builder.end();
144                 _classFab.addMethod(Modifier.PUBLIC, m, builder.toString());
145             }
146         }
147
148         if (!mi.getToString() && addToString)
149             ClassFabUtils.addToStringMethod(_classFab, "<" + _type + " for \" + _extensionPointId + \""
150                     + "(" + _serviceInterface.getName() + ")>");
151     }
152 }
Popular Tags