KickJava   Java API By Example, From Geeks To Geeks.

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


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.lang.reflect.Constructor JavaDoc;
18 import java.lang.reflect.Modifier JavaDoc;
19
20 import org.apache.hivemind.ApplicationRuntimeException;
21 import org.apache.hivemind.events.RegistryShutdownListener;
22 import org.apache.hivemind.internal.ServiceModel;
23 import org.apache.hivemind.internal.ServicePoint;
24 import org.apache.hivemind.service.BodyBuilder;
25 import org.apache.hivemind.service.ClassFab;
26 import org.apache.hivemind.service.ClassFabUtils;
27 import org.apache.hivemind.service.MethodSignature;
28 import org.apache.hivemind.util.ConstructorUtils;
29
30 /**
31  * Contains some common code used to create proxies that defer to a service model method for thier
32  * service.
33  *
34  * @author Howard Lewis Ship
35  */

36 public final class ProxyUtils
37 {
38     public static final String JavaDoc SERVICE_ACCESSOR_METHOD_NAME = "_service";
39
40     public static final String JavaDoc DELEGATE_ACCESSOR_METHOD_NAME = "_delegate";
41
42     private ProxyUtils()
43     {
44         // Prevent instantiation
45
}
46
47     /**
48      * Creates a class that implements the service interface. Implements a private synchronized
49      * method, _service(), that constructs the service as needed, and has each service interface
50      * method re-invoke on _service(). Adds a toString() method if the service interface does not
51      * define toString().
52      */

53     public static Object JavaDoc createDelegatingProxy(String JavaDoc type, ServiceModel serviceModel,
54             String JavaDoc delegationMethodName, ServicePoint servicePoint)
55     {
56         ProxyBuilder builder = new ProxyBuilder(type, servicePoint.getModule(),
57                 servicePoint.getServiceInterface(), servicePoint.getDeclaredInterface(), false);
58
59         ClassFab classFab = builder.getClassFab();
60
61         addConstructor(classFab, serviceModel);
62
63         addServiceAccessor(classFab, delegationMethodName, servicePoint);
64
65         builder.addServiceMethods(SERVICE_ACCESSOR_METHOD_NAME + "()");
66
67         Class JavaDoc proxyClass = classFab.createClass();
68
69         try
70         {
71             Constructor JavaDoc c = proxyClass.getConstructor(new Class JavaDoc[]
72             { String JavaDoc.class, serviceModel.getClass() });
73
74             return c.newInstance(new Object JavaDoc[]
75             { servicePoint.getExtensionPointId(), serviceModel });
76         }
77         catch (Exception JavaDoc ex)
78         {
79             throw new ApplicationRuntimeException(ex);
80         }
81     }
82
83     /**
84      * Constructs an outer proxy (for the threaded or pooled service). The outer proxy listens to
85      * the shutdown coordinator, and delegates from the declared interface (which may in fact be a
86      * bean) to the service interface.
87      * <p>
88      * The outer proxy is a {@link RegistryShutdownListener}; it can be registered for
89      * notifications and will respond by throwing an exception when service methods are invoked.
90      *
91      * @param delegate
92      * An object, implementing the service interface, that the proxy should delegate to.
93      * @param servicePoint
94      * for which the proxy is being constructed
95      * @since 1.1
96      */

97
98     public static RegistryShutdownListener createOuterProxy(Object JavaDoc delegate,
99             ServicePoint servicePoint)
100     {
101         ProxyBuilder builder = new ProxyBuilder("OuterProxy", servicePoint.getModule(),
102                 servicePoint.getServiceInterface(), servicePoint.getDeclaredInterface(), true);
103
104         ClassFab classFab = builder.getClassFab();
105
106         addDelegateAccessor(classFab, servicePoint, delegate);
107
108         builder.addServiceMethods(DELEGATE_ACCESSOR_METHOD_NAME + "()");
109
110         Class JavaDoc proxyClass = classFab.createClass();
111
112         try
113         {
114             return (RegistryShutdownListener) ConstructorUtils.invokeConstructor(
115                     proxyClass,
116                     new Object JavaDoc[]
117                     { servicePoint.getExtensionPointId(), delegate });
118         }
119         catch (Exception JavaDoc ex)
120         {
121             throw new ApplicationRuntimeException(ex);
122         }
123     }
124
125     /** @since 1.1 */
126
127     private static void addDelegateAccessor(ClassFab classFab, ServicePoint servicePoint,
128             Object JavaDoc delegate)
129     {
130         classFab.addField("_shutdown", boolean.class);
131
132         Class JavaDoc delegateClass = ClassFabUtils.getInstanceClass(classFab, delegate, servicePoint
133                 .getServiceInterface());
134
135         classFab.addField("_delegate", delegateClass);
136
137         classFab.addConstructor(new Class JavaDoc[]
138         { String JavaDoc.class, delegateClass }, null, "{ this($1); _delegate = $2; }");
139
140         classFab.addInterface(RegistryShutdownListener.class);
141         if( RegistryShutdownListener.class.isAssignableFrom( delegateClass ) )
142         {
143             classFab.addMethod(Modifier.PUBLIC | Modifier.FINAL, new MethodSignature(void.class,
144                     "registryDidShutdown", null, null), "{ _delegate.registryDidShutdown(); _delegate = null; _shutdown = true; }");
145         }
146         else
147         {
148             classFab.addMethod(Modifier.PUBLIC | Modifier.FINAL, new MethodSignature(void.class,
149                     "registryDidShutdown", null, null), "{ _delegate = null; _shutdown = true; }");
150         }
151         BodyBuilder builder = new BodyBuilder();
152
153         builder.begin();
154
155         builder.addln("if (_shutdown)");
156         builder.addln(" throw org.apache.hivemind.HiveMind#createRegistryShutdownException();");
157
158         builder.add("return _delegate;");
159
160         builder.end();
161
162         classFab.addMethod(Modifier.FINAL | Modifier.PRIVATE, new MethodSignature(delegateClass,
163                 DELEGATE_ACCESSOR_METHOD_NAME, null, null), builder.toString());
164     }
165
166     /**
167      * Adds a field, _serviceExtensionPoint, whose type matches this class, and a constructor which
168      * sets the field.
169      */

170     private static void addConstructor(ClassFab classFab, ServiceModel model)
171     {
172         Class JavaDoc modelClass = model.getClass();
173
174         classFab.addField("_serviceModel", modelClass);
175
176         classFab.addConstructor(new Class JavaDoc[]
177         { String JavaDoc.class, modelClass }, null, "{ this($1); _serviceModel = $2; }");
178     }
179
180     /**
181      * We construct a method that always goes through this service model's
182      * {@link #getServiceImplementationForCurrentThread()} method.
183      */

184     private static void addServiceAccessor(ClassFab classFab, String JavaDoc serviceModelMethodName,
185             ServicePoint servicePoint)
186     {
187         Class JavaDoc serviceInterface = servicePoint.getServiceInterface();
188
189         classFab.addField(SERVICE_ACCESSOR_METHOD_NAME, serviceInterface);
190
191         BodyBuilder builder = new BodyBuilder();
192         builder.begin();
193
194         builder.add("return (");
195         builder.add(serviceInterface.getName());
196         builder.add(") _serviceModel.");
197         builder.add(serviceModelMethodName);
198         builder.add("();");
199
200         builder.end();
201
202         classFab.addMethod(Modifier.PRIVATE | Modifier.FINAL, new MethodSignature(serviceInterface,
203                 SERVICE_ACCESSOR_METHOD_NAME, null, null), builder.toString());
204     }
205 }
Popular Tags