KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > google > gwt > user > rebind > AbstractGeneratorClassCreator


1 /*
2  * Copyright 2006 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * 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, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */

16 package com.google.gwt.user.rebind;
17
18 import com.google.gwt.core.ext.TreeLogger;
19 import com.google.gwt.core.ext.UnableToCompleteException;
20 import com.google.gwt.core.ext.typeinfo.JClassType;
21 import com.google.gwt.core.ext.typeinfo.JMethod;
22 import com.google.gwt.core.ext.typeinfo.JParameter;
23 import com.google.gwt.core.ext.typeinfo.JType;
24
25 import java.util.HashMap JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.Map JavaDoc;
28
29 /**
30  * Abstract functionality needed to create classes needed to supply generators.
31  */

32 public abstract class AbstractGeneratorClassCreator extends
33     AbstractSourceCreator {
34
35   /**
36    * Returns all interface methods associated with the given type.
37    *
38    * @param type associated type
39    * @return interface methods.
40    */

41   public static JMethod[] getAllInterfaceMethods(JClassType type) {
42     Map JavaDoc methods = new HashMap JavaDoc();
43     getAllInterfaceMethodsAux(type, methods);
44     return (JMethod[]) methods.values().toArray(new JMethod[methods.size()]);
45   }
46
47   private static void getAllInterfaceMethodsAux(JClassType type, Map JavaDoc m) {
48     if (type.isInterface() != null) {
49       JMethod[] methods = type.getMethods();
50       for (int i = 0; i < methods.length; i++) {
51         String JavaDoc s = uniqueMethodKey(methods[i]);
52         if (m.get(s) == null) {
53           m.put(s, methods[i]);
54         }
55       }
56       JClassType[] supers = type.getImplementedInterfaces();
57       for (int i = 0; i < supers.length; i++) {
58         getAllInterfaceMethodsAux(supers[i], m);
59       }
60     }
61   }
62
63   private static String JavaDoc uniqueMethodKey(JMethod method) {
64     String JavaDoc name = method.getName();
65     name += "(";
66     JParameter[] m = method.getParameters();
67     for (int i = 0; i < m.length; i++) {
68       name += m[i].getType() + " ";
69     }
70     name += ")";
71     return name;
72   }
73
74   /**
75    * List of registered method factories associated with <code>Constant</code>
76    * method implementations.
77    */

78   protected Map JavaDoc methodFactories = new HashMap JavaDoc();
79
80   /**
81    * The interface the generator is conforming to.
82    */

83   JClassType targetClass;
84
85   private final SourceWriter writer;
86
87   /**
88    * Creates a new class creator, supplies a place to write the class, the
89    * interface to conform to, and the new name.
90    *
91    * @param writer writer
92    * @param targetClass class name
93    */

94   public AbstractGeneratorClassCreator(SourceWriter writer,
95       JClassType targetClass) {
96     this.targetClass = targetClass;
97     this.writer = writer;
98   }
99
100   /**
101    * Emits the new class.
102    *
103    * @param logger
104    * @throws UnableToCompleteException
105    */

106   public void emitClass(TreeLogger logger) throws UnableToCompleteException {
107     logger = branch(logger, branchMessage());
108     classPrologue();
109     emitMethods(logger, targetClass);
110     classEpilog();
111     getWriter().println("}");
112   }
113
114   public JClassType getTarget() {
115     return targetClass;
116   }
117
118   /**
119    * Registers a method creator.
120    *
121    * @param returnType return type that this creator handles.
122    * @param creator creator to register
123    */

124   public void register(JType returnType, AbstractMethodCreator creator) {
125     methodFactories.put(returnType, creator);
126   }
127
128   /**
129    * Returns the standard message when constructing a branch.
130    *
131    * @return branch message
132    */

133   protected String JavaDoc branchMessage() {
134     return "Constructing " + targetClass;
135   }
136
137   /**
138    * Entry point for subclass cleanup code.
139    */

140   protected void classEpilog() {
141   }
142
143   /**
144    * Entry point for subclass setup code.
145    */

146   protected void classPrologue() {
147   }
148
149   /**
150    * Emit method body, arguments are arg1...argN.
151    *
152    * @param logger TODO
153    * @param method method to generate
154    * @throws UnableToCompleteException
155    */

156   protected abstract void emitMethodBody(TreeLogger logger, JMethod method)
157       throws UnableToCompleteException;
158
159   /**
160    * Gets the method creator associated with the return type of the method.
161    *
162    * @param logger
163    * @param method method to create
164    * @return the method creator
165    * @throws UnableToCompleteException
166    */

167   protected AbstractMethodCreator getMethodCreator(TreeLogger logger,
168       JMethod method) throws UnableToCompleteException {
169     JType type = method.getReturnType();
170     AbstractMethodCreator methodCreator = (AbstractMethodCreator) methodFactories.get(type);
171     if (methodCreator == null) {
172       String JavaDoc msg = "No current method creator exists for " + method
173           + " only methods with return types of ";
174       Iterator JavaDoc iter = this.methodFactories.keySet().iterator();
175       while (iter.hasNext()) {
176         msg += ((JType) iter.next()).getSimpleSourceName();
177         if (iter.hasNext()) {
178           msg += ", ";
179         }
180       }
181       msg += " can be created";
182       throw error(logger, msg);
183     }
184     return methodCreator;
185   }
186
187   /**
188    * Gets the associated writer.
189    *
190    * @return writer
191    */

192   protected SourceWriter getWriter() {
193     return writer;
194   }
195
196   private void emitMethods(TreeLogger logger, JClassType cur)
197       throws UnableToCompleteException {
198     JMethod[] x = getAllInterfaceMethods(cur);
199     for (int i = 0; i < x.length; i++) {
200       genMethod(logger, x[i]);
201       getWriter().println();
202     }
203   }
204
205   /**
206    * Generates a method declaration for the given method.
207    *
208    * @param method method to generate
209    * @throws UnableToCompleteException
210    */

211   private void genMethod(TreeLogger logger, JMethod method)
212       throws UnableToCompleteException {
213     String JavaDoc name = method.getName();
214     String JavaDoc returnType = method.getReturnType().getQualifiedSourceName();
215     getWriter().print("public " + returnType + " " + name + "(");
216     JParameter[] params = method.getParameters();
217     for (int i = 0; i < params.length; i++) {
218       if (i != 0) {
219         getWriter().print(",");
220       }
221       getWriter().print(
222           params[i].getType().getParameterizedQualifiedSourceName() + " arg"
223               + (i));
224     }
225     getWriter().println(") {");
226     getWriter().indent();
227     String JavaDoc methodName = method.getName();
228     TreeLogger branch = branch(logger, "Generating method body for "
229         + methodName + "()");
230     emitMethodBody(branch, method);
231     getWriter().outdent();
232     getWriter().println("}");
233   }
234 }
235
Popular Tags