KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ws > jaxme > js > pattern > ChainGenerator


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

17 package org.apache.ws.jaxme.js.pattern;
18
19 import java.io.File JavaDoc;
20 import java.io.IOException JavaDoc;
21 import java.net.URL JavaDoc;
22 import java.util.ArrayList JavaDoc;
23 import java.util.HashSet JavaDoc;
24 import java.util.List JavaDoc;
25 import java.util.Set JavaDoc;
26
27 import org.apache.ws.jaxme.js.JavaConstructor;
28 import org.apache.ws.jaxme.js.JavaField;
29 import org.apache.ws.jaxme.js.JavaMethod;
30 import org.apache.ws.jaxme.js.JavaQName;
31 import org.apache.ws.jaxme.js.JavaQNameImpl;
32 import org.apache.ws.jaxme.js.JavaSource;
33 import org.apache.ws.jaxme.js.JavaSourceFactory;
34 import org.apache.ws.jaxme.js.Parameter;
35
36 import antlr.RecognitionException;
37 import antlr.TokenStreamException;
38
39
40 /** <p>This class generates so-called event chains. A chain is an
41  * interface and an object implementing the interface. Internally
42  * the implementation is using a list of chained objects, which
43  * you can assume to implement the same interface.</p>
44  * <p>Any event is passed to the first object in the list. The object
45  * may decide to resolve the event immediately and return. It may
46  * also call pass the event to the next object, take the returned
47  * value, possibly modify it and return the result. Finally, the
48  * chained object may decide to emit another event (which is passed
49  * along the same chain), and use the returned value.</p>
50  *
51  * @author <a HREF="mailto:joe@ispsoft.de">Jochen Wiedmann</a>
52  */

53 public class ChainGenerator {
54     private String JavaDoc controllerInterfaceName;
55     private JavaSource controllerInterface;
56     private JavaQName chainInterface, proxyClass, implClass;
57
58     /** <p>Sets the controller interface name.</p>
59      */

60     public void setControllerInterfaceName(String JavaDoc pInterfaceName) throws ClassNotFoundException JavaDoc {
61         controllerInterfaceName = pInterfaceName;
62     }
63
64     /** Returns the controller interface.
65      */

66     public JavaSource getControllerInterface() {
67         return controllerInterface;
68     }
69
70     private JavaSource loadSource(ClassLoader JavaDoc pClassLoader,
71                                   String JavaDoc pName,
72                                   JavaSourceFactory pFactory)
73             throws RecognitionException, TokenStreamException, IOException JavaDoc {
74         URL JavaDoc url = pClassLoader.getResource(pName.replace('.', '/') + ".java");
75         if (url == null) {
76             return null;
77         } else {
78             return new SourceReflector(url).getJavaSource(pFactory);
79         }
80     }
81
82     private void loadSources(ClassLoader JavaDoc pClassLoader, JavaQName pQName,
83                              JavaSourceFactory pFactory,
84                              List JavaDoc pSources, Set JavaDoc pNames)
85             throws RecognitionException, TokenStreamException, IOException JavaDoc {
86         if (pNames.contains(pQName)) {
87             return;
88         }
89         pNames.add(pQName);
90         JavaSource js = loadSource(Thread.currentThread().getContextClassLoader(),
91                                    pQName.toString(), pFactory);
92         if (js == null) {
93             return;
94         }
95         pSources.add(js);
96         JavaQName[] superInterfaces = js.getExtends();
97         for (int i = 0; i < superInterfaces.length; i++) {
98             loadSources(pClassLoader, superInterfaces[i],
99                         pFactory, pSources, pNames);
100         }
101     }
102
103     private JavaSource[] loadSources(ClassLoader JavaDoc pClassLoader, String JavaDoc pName)
104             throws RecognitionException, TokenStreamException, IOException JavaDoc {
105         JavaSourceFactory jsf = new JavaSourceFactory();
106         List JavaDoc sources = new ArrayList JavaDoc();
107         Set JavaDoc names = new HashSet JavaDoc();
108         loadSources(pClassLoader, JavaQNameImpl.getInstance(pName, true),
109                     jsf, sources, names);
110         if (sources.isEmpty()) {
111             return null;
112         } else {
113             return (JavaSource[]) sources.toArray(new JavaSource[sources.size()]);
114         }
115     }
116
117     /** <p>Initializes the controller interface.</p>
118      * @throws ClassNotFoundException
119      * @throws IOException
120      * @throws TokenStreamException
121      * @throws RecognitionException
122      */

123     protected JavaSource[] initControllerInterface()
124             throws ClassNotFoundException JavaDoc, RecognitionException, TokenStreamException, IOException JavaDoc {
125         ClassLoader JavaDoc cl = Thread.currentThread().getContextClassLoader();
126         JavaSource[] result;
127         try {
128             if (cl == null) {
129                 throw new ClassNotFoundException JavaDoc(controllerInterfaceName);
130             }
131             CompiledClassReflector r = new CompiledClassReflector(controllerInterfaceName, cl);
132             result = new JavaSource[]{r.getJavaSource(new JavaSourceFactory())};
133         } catch (ClassNotFoundException JavaDoc e) {
134             result = loadSources(Thread.currentThread().getContextClassLoader(),
135                                  controllerInterfaceName);
136             if (result == null) {
137                 throw e;
138             }
139         }
140         if (!result[0].isInterface()) {
141             throw new ClassCastException JavaDoc("The controller must be an interface");
142         }
143         return result;
144    }
145
146    /** <p>Sets the interface name being generated for the chain objects.</p>
147     */

148    public void setChainInterfaceName(String JavaDoc pInterfaceName) {
149       JavaQName qName = JavaQNameImpl.getInstance(pInterfaceName, true);
150       setChainInterface(qName);
151    }
152
153    /** <p>Sets the interface being generated for the chain objects.</p>
154     */

155    public void setChainInterface(JavaQName pInterface) {
156       chainInterface = pInterface;
157    }
158
159    /** <p>Returns the interface being generated for the chain objects.</p>
160     */

161    public JavaQName getChainInterface() {
162       return chainInterface;
163    }
164
165    /** <p>Sets the class name being generated for the chain objects.</p>
166     */

167    public void setProxyClassName(String JavaDoc pClassName) {
168       JavaQName qName = JavaQNameImpl.getInstance(pClassName, true);
169       setProxyClass(qName);
170    }
171
172    /** <p>Sets the class being generated for the chain objects.</p>
173     */

174    public void setProxyClass(JavaQName pClassName) {
175       proxyClass = pClassName;
176    }
177
178    /** <p>Returns the class being generated for the chain objects. Defaults
179     * to <code>getChainInterface() + "Impl"</code>.</p>
180     */

181    public JavaQName getProxyClass() {
182       if (proxyClass == null) {
183          JavaQName chainClass = getChainInterface();
184          if (chainClass == null) {
185             return null;
186          } else {
187             return JavaQNameImpl.getInstance(chainClass.getPackageName(),
188                                                              chainClass.getClassName() + "Impl");
189          }
190       } else {
191          return proxyClass;
192       }
193    }
194
195    /** <p>Sets the name of the chain implementation class.</p>
196     */

197    public void setImplementationClassName(String JavaDoc pClassName) {
198       setImplementationClass(JavaQNameImpl.getInstance(pClassName, true));
199    }
200
201    /** <p>Sets the chain implementation class.</p>
202     */

203    public void setImplementationClass(JavaQName pClassName) {
204       implClass = pClassName;
205    }
206
207    /** <p>Returns the chain implementation classes name. Defaults to
208     * <code>getControllerInterface() + "Impl"</code>.</p>
209     */

210    public JavaQName getImplementationClass() {
211       if (implClass == null) {
212          if (controllerInterface == null) {
213             return null;
214          } else {
215             JavaQName controllerClass = controllerInterface.getQName();
216             return JavaQNameImpl.getInstance(controllerClass.getPackageName(),
217                                               controllerClass.getClassName() + "Impl");
218          }
219       } else {
220          return implClass;
221       }
222    }
223
224    /** Validates the input data.
225     */

226    public void finish() {
227       if (controllerInterface == null) {
228          throw new NullPointerException JavaDoc("A controller interface must be given.");
229       }
230       if (chainInterface == null) {
231          throw new NullPointerException JavaDoc("A chain interface must be given.");
232       }
233    }
234
235    private class ProxyInterfaceGenerator extends ProxyGenerator {
236     public JavaMethod getInterfaceMethod(JavaSource pSource, JavaMethod pMethod) {
237         JavaMethod jm = pSource.newJavaMethod(pMethod);
238         Parameter[] parameters = jm.getParams();
239         JavaQName controllerInterfaceQName = getControllerInterface().getQName();
240         jm.clearParams();
241         jm.addParam(controllerInterfaceQName, "pController");
242         for (int i = 0; i < parameters.length; i++) {
243             jm.addParam(parameters[i]);
244         }
245         return jm;
246     }
247     public JavaSource generate(JavaSourceFactory pInterfaceFactory,
248                                JavaQName pTargetClass,
249                                InterfaceDescription[] pDescription) throws Exception JavaDoc {
250         JavaSource result = super.generate(pInterfaceFactory, pTargetClass,
251                 pDescription);
252         result.clearImplements();
253         return result;
254     }
255    }
256
257    private class ProxyImplementationGenerator extends ProxyGenerator {
258     protected JavaField getBackingObjectField(JavaSource pJs, InterfaceDescription[] pInterfaces) {
259         return pJs.newJavaField("backingObject", getChainInterface(), JavaSource.PRIVATE);
260     }
261     protected JavaConstructor getConstructor(JavaSource pJs,
262                                              InterfaceDescription[] pInterfaces) {
263         JavaConstructor jcon = pJs.newJavaConstructor(JavaSource.PROTECTED);
264         jcon.addParam(getChainInterface(), "o");
265         jcon.addIf("o == null");
266         jcon.addThrowNew(NullPointerException JavaDoc.class,
267                 JavaSource.getQuoted("The supplied object must not be null."));
268         jcon.addEndIf();
269         jcon.addLine("backingObject = o;");
270         return jcon;
271     }
272
273     public JavaMethod getInterfaceMethod(JavaSource pSource, JavaMethod pMethod) {
274         JavaMethod jm = pSource.newJavaMethod(pMethod);
275         Parameter[] parameters = jm.getParams();
276         JavaQName controllerInterfaceQName = getControllerInterface().getQName();
277         jm.clearParams();
278         jm.addParam(controllerInterfaceQName, "pController");
279         for (int i = 0; i < parameters.length; i++) {
280             jm.addParam(parameters[i]);
281         }
282         List JavaDoc callParameters = new ArrayList JavaDoc();
283         callParameters.add("pController");
284         for (int i = 0; i < parameters.length; i++) {
285             Parameter parameter = parameters[i];
286             callParameters.add(", ");
287             callParameters.add(parameter.getName());
288         }
289         jm.addLine((JavaQNameImpl.VOID.equals(pMethod.getType()) ? "" : "return "),
290                    "backingObject.",
291                    pMethod.getName(), "(", callParameters, ");");
292         return jm;
293     }
294     public JavaSource generate(JavaSourceFactory pImplementationFactory,
295                                JavaQName pTargetClass,
296                                InterfaceDescription[] pDescription) throws Exception JavaDoc {
297         JavaSource result = super.generate(pImplementationFactory, pTargetClass, pDescription);
298         result.clearImplements();
299         result.addImplements(getChainInterface());
300         return result;
301     }
302    }
303
304    private class ControllerImplementationGenerator extends ProxyGenerator {
305     protected JavaField getBackingObjectField(JavaSource pJs, InterfaceDescription[] pInterfaces) {
306         return pJs.newJavaField("backingObject", getChainInterface(), JavaSource.PRIVATE);
307     }
308     protected JavaConstructor getConstructor(JavaSource pJs,
309                                              InterfaceDescription[] pInterfaces) {
310         JavaConstructor jcon = pJs.newJavaConstructor(JavaSource.PUBLIC);
311         jcon.addParam(getChainInterface(), "o");
312         jcon.addIf("o == null");
313         jcon.addThrowNew(NullPointerException JavaDoc.class,
314                 JavaSource.getQuoted("The supplied object must not be null."));
315         jcon.addEndIf();
316         jcon.addLine("backingObject = o;");
317         return jcon;
318     }
319     public JavaMethod getInterfaceMethod(JavaSource pSource,
320                                          JavaMethod pMethod) {
321         JavaMethod jm = pSource.newJavaMethod(pMethod);
322         Parameter[] parameters = jm.getParams();
323         List JavaDoc callParameters = new ArrayList JavaDoc();
324         callParameters.add("this");
325         for (int i = 0; i < parameters.length; i++) {
326             Parameter parameter = parameters[i];
327             callParameters.add(", ");
328             callParameters.add(parameter.getName());
329         }
330         jm.addLine((JavaQNameImpl.VOID.equals(pMethod.getType()) ? "" : "return "),
331                 "backingObject.",
332                 pMethod.getName(), "(", callParameters, ");");
333         return jm;
334     }
335     protected JavaMethod getGetHeadOfChainMethod(JavaSource pSource) {
336         JavaMethod jm = pSource.newJavaMethod("getHeadOfChain",
337                 getChainInterface(),
338                 JavaSource.PUBLIC);
339         jm.addLine("return backingObject;");
340         return jm;
341     }
342     public JavaSource generate(JavaSourceFactory pImplementationFactory,
343                                JavaQName pTargetClass,
344                                InterfaceDescription[] pDescription) throws Exception JavaDoc {
345         JavaSource result = super.generate(pImplementationFactory, pTargetClass, pDescription);
346         getGetHeadOfChainMethod(result);
347         return result;
348     }
349    }
350
351    /** Performs the actual work by generating classes using
352     * the given <code>pFactory</code>.
353     */

354    public JavaSource[] generate(JavaSourceFactory pFactory) throws Exception JavaDoc {
355
356       JavaSource[] sources = initControllerInterface();
357       controllerInterface = sources[0];
358       InterfaceDescription[] interfaces = new InterfaceDescription[sources.length];
359       for (int i = 0; i < interfaces.length; i++) {
360          InterfaceDescription controllerDescription = new InterfaceDescription();
361          controllerDescription.setInterface(sources[i].getQName().toString());
362          controllerDescription.setMandatory(true);
363          interfaces[i] = controllerDescription;
364       }
365
366       ProxyGenerator proxyInterfaceGenerator = new ProxyInterfaceGenerator();
367       JavaSource proxyInterface = proxyInterfaceGenerator.generate(pFactory, getChainInterface(), interfaces);
368       proxyInterface.setType(JavaSource.INTERFACE);
369
370       ProxyGenerator proxyImpGenerator = new ProxyImplementationGenerator();
371       JavaSource proxyImplementation = proxyImpGenerator.generate(pFactory, getProxyClass(), interfaces);
372
373       ProxyGenerator controllerImplementationGenerator = new ControllerImplementationGenerator();
374       JavaSource controllerImplementation = controllerImplementationGenerator.generate(pFactory, getImplementationClass(), interfaces);
375
376       return new JavaSource[]{controllerImplementation, proxyInterface, proxyImplementation};
377    }
378
379    public static void main(String JavaDoc[] args) throws Exception JavaDoc {
380        ChainGenerator cg = new ChainGenerator();
381        cg.setChainInterfaceName("org.apache.ws.jaxme.generator.sg.ComplexTypeSGChain");
382        cg.setControllerInterfaceName("org.apache.ws.jaxme.generator.sg.ComplexTypeSG");
383        cg.setImplementationClassName("org.apache.ws.jaxme.generator.sg.ComplexTypeSGImpl");
384        cg.setProxyClassName("org.apache.ws.jaxme.generator.sg.ComplexTypeSGChainImpl");
385        JavaSourceFactory f = new JavaSourceFactory();
386        cg.generate(f);
387        f.write(new File JavaDoc("/tmp/qName"));
388    }
389 }
390
Popular Tags