KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > hivemind > lib > impl > ServicePropertyFactory


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.lib.impl;
16
17 import java.lang.reflect.Modifier JavaDoc;
18
19 import org.apache.hivemind.ApplicationRuntimeException;
20 import org.apache.hivemind.ServiceImplementationFactory;
21 import org.apache.hivemind.ServiceImplementationFactoryParameters;
22 import org.apache.hivemind.internal.ServicePoint;
23 import org.apache.hivemind.service.BodyBuilder;
24 import org.apache.hivemind.service.ClassFab;
25 import org.apache.hivemind.service.ClassFabUtils;
26 import org.apache.hivemind.service.ClassFactory;
27 import org.apache.hivemind.service.MethodIterator;
28 import org.apache.hivemind.service.MethodSignature;
29 import org.apache.hivemind.util.ConstructorUtils;
30 import org.apache.hivemind.util.PropertyAdaptor;
31 import org.apache.hivemind.util.PropertyUtils;
32
33 /**
34  * Factory that dynamically exposes a property of another service. A proxy is constructed that
35  * accesses the target service and obtains a property from that. The service interface of the
36  * constructed service must match the type of the exposed property.
37  *
38  * @author Howard Lewis Ship
39  */

40 public class ServicePropertyFactory implements ServiceImplementationFactory
41 {
42     private ClassFactory _classFactory;
43
44     public Object JavaDoc createCoreServiceImplementation(
45             ServiceImplementationFactoryParameters factoryParameters)
46     {
47         ServicePropertyFactoryParameter p = (ServicePropertyFactoryParameter) factoryParameters
48                 .getFirstParameter();
49
50         ServicePoint targetServicePoint = p.getServicePoint();
51         final Class JavaDoc targetServiceInterface = targetServicePoint.getServiceInterface();
52         final Object JavaDoc targetService = targetServicePoint.getService( targetServiceInterface );
53         String JavaDoc propertyName = p.getPropertyName();
54
55         PropertyAdaptor pa = PropertyUtils.getPropertyAdaptor(targetService, propertyName);
56
57         String JavaDoc readMethodName = pa.getReadMethodName();
58
59         if (readMethodName == null)
60             throw new ApplicationRuntimeException(ImplMessages.servicePropertyNotReadable(
61                     propertyName,
62                     targetService), null, p.getLocation(), null);
63         Class JavaDoc serviceInterface = factoryParameters.getServiceInterface();
64
65         if (!(serviceInterface.isAssignableFrom(pa.getPropertyType())))
66             throw new ApplicationRuntimeException(ImplMessages.servicePropertyWrongType(
67                     propertyName,
68                     targetService,
69                     pa.getPropertyType(),
70                     serviceInterface), p.getLocation(), null);
71
72         // Now we're good to go.
73

74         String JavaDoc name = ClassFabUtils.generateClassName(serviceInterface);
75
76         ClassFab cf = _classFactory.newClass(name, Object JavaDoc.class);
77
78         addInfrastructure(cf, targetService, serviceInterface, targetServiceInterface, propertyName, readMethodName);
79
80         addMethods(
81                 cf,
82                 factoryParameters.getServiceId(),
83                 serviceInterface,
84                 propertyName,
85                 targetService);
86
87         Class JavaDoc proxyClass = cf.createClass();
88
89         try
90         {
91             return ConstructorUtils.invokeConstructor(proxyClass, new Object JavaDoc[]
92             { targetService });
93         }
94         catch (Throwable JavaDoc ex)
95         {
96             throw new ApplicationRuntimeException(ex.getMessage(), p.getLocation(), ex);
97         }
98     }
99
100     private void addInfrastructure(ClassFab cf, Object JavaDoc targetService, Class JavaDoc serviceInterface, Class JavaDoc targetServiceInterface,
101             String JavaDoc propertyName, String JavaDoc readPropertyMethodName)
102     {
103         cf.addInterface(serviceInterface);
104
105         Class JavaDoc targetServiceClass = ClassFabUtils.getInstanceClass(cf, targetService, targetServiceInterface);
106         
107         cf.addField("_targetService", targetServiceClass);
108
109         cf.addConstructor(new Class JavaDoc[]
110         { targetServiceClass }, null, "{ super(); _targetService = $1; }");
111
112         BodyBuilder b = new BodyBuilder();
113
114         b.begin();
115         b.addln(
116                 "{0} property = _targetService.{1}();",
117                 serviceInterface.getName(),
118                 readPropertyMethodName);
119
120         b.addln("if (property == null)");
121         b.add(" throw new java.lang.NullPointerException(");
122         b.addQuoted(ImplMessages.servicePropertyWasNull(propertyName, targetService));
123         b.addln(");");
124
125         b.addln("return property;");
126
127         b.end();
128
129         MethodSignature sig = new MethodSignature(serviceInterface, "_targetServiceProperty", null,
130                 null);
131         cf.addMethod(Modifier.FINAL | Modifier.PRIVATE, sig, b.toString());
132     }
133
134     private void addMethods(ClassFab cf, String JavaDoc serviceId, Class JavaDoc serviceInterface,
135             String JavaDoc propertyName, Object JavaDoc targetService)
136     {
137         MethodIterator mi = new MethodIterator(serviceInterface);
138
139         while (mi.hasNext())
140         {
141             MethodSignature sig = mi.next();
142
143             String JavaDoc body = "return ($r) _targetServiceProperty()." + sig.getName() + "($$);";
144
145             cf.addMethod(Modifier.PUBLIC, sig, body);
146         }
147
148         if (!mi.getToString())
149             ClassFabUtils.addToStringMethod(cf, ImplMessages.servicePropertyToString(
150                     serviceId,
151                     serviceInterface,
152                     propertyName,
153                     targetService));
154     }
155
156     public void setClassFactory(ClassFactory factory)
157     {
158         _classFactory = factory;
159     }
160 }
Popular Tags