001: /*
002: * Distributed as part of c3p0 v.0.9.1.2
003: *
004: * Copyright (C) 2005 Machinery For Change, Inc.
005: *
006: * Author: Steve Waldman <swaldman@mchange.com>
007: *
008: * This library is free software; you can redistribute it and/or modify
009: * it under the terms of the GNU Lesser General Public License version 2.1, as
010: * published by the Free Software Foundation.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public License
018: * along with this software; see the file LICENSE. If not, write to the
019: * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020: * Boston, MA 02111-1307, USA.
021: */
022:
023: package com.mchange.v2.codegen.intfc;
024:
025: import java.io.*;
026: import java.util.*;
027: import java.lang.reflect.*;
028: import com.mchange.v2.codegen.*;
029: import com.mchange.v1.lang.ClassUtils;
030:
031: public class DelegatorGenerator {
032: int class_modifiers = Modifier.PUBLIC | Modifier.ABSTRACT;
033: int method_modifiers = Modifier.PUBLIC;
034: int wrapping_ctor_modifiers = Modifier.PUBLIC;
035: int default_ctor_modifiers = Modifier.PUBLIC;
036: boolean wrapping_constructor = true;
037: boolean default_constructor = true;
038: boolean inner_getter = true;
039: boolean inner_setter = true;
040:
041: Class super class = null;
042: Class[] extraInterfaces = null;
043:
044: final static Comparator classComp = new Comparator() {
045: public int compare(Object a, Object b) {
046: return ((Class) a).getName().compareTo(
047: ((Class) b).getName());
048: }
049: };
050:
051: public void setGenerateInnerSetter(boolean b) {
052: this .inner_setter = b;
053: }
054:
055: public boolean isGenerateInnerSetter() {
056: return inner_setter;
057: }
058:
059: public void setGenerateInnerGetter(boolean b) {
060: this .inner_getter = b;
061: }
062:
063: public boolean isGenerateInnerGetter() {
064: return inner_getter;
065: }
066:
067: public void setGenerateNoArgConstructor(boolean b) {
068: this .default_constructor = b;
069: }
070:
071: public boolean isGenerateNoArgConstructor() {
072: return default_constructor;
073: }
074:
075: public void setGenerateWrappingConstructor(boolean b) {
076: this .wrapping_constructor = b;
077: }
078:
079: public boolean isGenerateWrappingConstructor() {
080: return wrapping_constructor;
081: }
082:
083: public void setWrappingConstructorModifiers(int modifiers) {
084: this .wrapping_ctor_modifiers = modifiers;
085: }
086:
087: public int getWrappingConstructorModifiers() {
088: return wrapping_ctor_modifiers;
089: }
090:
091: public void setNoArgConstructorModifiers(int modifiers) {
092: this .default_ctor_modifiers = modifiers;
093: }
094:
095: public int getNoArgConstructorModifiers() {
096: return default_ctor_modifiers;
097: }
098:
099: public void setMethodModifiers(int modifiers) {
100: this .method_modifiers = modifiers;
101: }
102:
103: public int getMethodModifiers() {
104: return method_modifiers;
105: }
106:
107: public void setClassModifiers(int modifiers) {
108: this .class_modifiers = modifiers;
109: }
110:
111: public int getClassModifiers() {
112: return class_modifiers;
113: }
114:
115: public void setSuperclass(Class super class) {
116: this .super class = super class;
117: }
118:
119: public Class getSuperclass() {
120: return super class;
121: }
122:
123: public void setExtraInterfaces(Class[] extraInterfaces) {
124: this .extraInterfaces = extraInterfaces;
125: }
126:
127: public Class[] getExtraInterfaces() {
128: return extraInterfaces;
129: }
130:
131: public void writeDelegator(Class intfcl, String genclass, Writer w)
132: throws IOException {
133: IndentedWriter iw = CodegenUtils.toIndentedWriter(w);
134:
135: String pkg = genclass.substring(0, genclass.lastIndexOf('.'));
136: String sgc = CodegenUtils.fqcnLastElement(genclass);
137: String scn = (super class != null ? ClassUtils
138: .simpleClassName(super class) : null);
139: String sin = ClassUtils.simpleClassName(intfcl);
140: String[] eins = null;
141: if (extraInterfaces != null) {
142: eins = new String[extraInterfaces.length];
143: for (int i = 0, len = extraInterfaces.length; i < len; ++i)
144: eins[i] = ClassUtils
145: .simpleClassName(extraInterfaces[i]);
146: }
147:
148: Set imports = new TreeSet(classComp);
149:
150: Method[] methods = intfcl.getMethods();
151:
152: //TODO: don't add array classes!
153: //build import set
154: if (!CodegenUtils.inSamePackage(intfcl.getName(), genclass))
155: imports.add(intfcl);
156: if (super class != null
157: && !CodegenUtils.inSamePackage(super class.getName(),
158: genclass))
159: imports.add(super class);
160: if (extraInterfaces != null) {
161: for (int i = 0, len = extraInterfaces.length; i < len; ++i) {
162: Class checkMe = extraInterfaces[i];
163: if (!CodegenUtils.inSamePackage(checkMe.getName(),
164: genclass))
165: imports.add(checkMe);
166: }
167: }
168: for (int i = 0, len = methods.length; i < len; ++i) {
169: Class[] args = methods[i].getParameterTypes();
170: for (int j = 0, jlen = args.length; j < jlen; ++j) {
171: if (!CodegenUtils.inSamePackage(args[j].getName(),
172: genclass))
173: imports.add(CodegenUtils.unarrayClass(args[j]));
174: }
175: Class[] excClasses = methods[i].getExceptionTypes();
176: for (int j = 0, jlen = excClasses.length; j < jlen; ++j) {
177: if (!CodegenUtils.inSamePackage(
178: excClasses[j].getName(), genclass)) {
179: //System.err.println("Adding exception type: " + excClasses[j]);
180: imports.add(CodegenUtils
181: .unarrayClass(excClasses[j]));
182: }
183: }
184: if (!CodegenUtils.inSamePackage(methods[i].getReturnType()
185: .getName(), genclass))
186: imports.add(CodegenUtils.unarrayClass(methods[i]
187: .getReturnType()));
188: }
189: generateBannerComment(iw);
190: iw.println("package " + pkg + ';');
191: iw.println();
192: for (Iterator ii = imports.iterator(); ii.hasNext();)
193: iw.println("import " + ((Class) ii.next()).getName() + ';');
194: generateExtraImports(iw);
195: iw.println();
196: iw.print(CodegenUtils.getModifierString(class_modifiers)
197: + " class " + sgc);
198: if (super class != null)
199: iw.print(" extends " + scn);
200: iw.print(" implements " + sin);
201: if (eins != null)
202: for (int i = 0, len = eins.length; i < len; ++i)
203: iw.print(", " + eins[i]);
204: iw.println();
205: iw.println("{");
206: iw.upIndent();
207:
208: iw.println("protected " + sin + " inner;");
209: iw.println();
210:
211: if (wrapping_constructor) {
212: iw.println("public" + ' ' + sgc + '(' + sin + " inner)");
213: iw.println("{ this.inner = inner; }");
214: }
215:
216: if (default_constructor) {
217: iw.println();
218: iw.println("public" + ' ' + sgc + "()");
219: iw.println("{}");
220: }
221:
222: if (inner_setter) {
223: iw.println();
224: iw.println(CodegenUtils.getModifierString(method_modifiers)
225: + " void setInner( " + sin + " inner )");
226: iw.println("{ this.inner = inner; }");
227: }
228: if (inner_getter) {
229: iw.println();
230: iw.println(CodegenUtils.getModifierString(method_modifiers)
231: + ' ' + sin + " getInner()");
232: iw.println("{ return inner; }");
233: }
234: iw.println();
235: for (int i = 0, len = methods.length; i < len; ++i) {
236: Method method = methods[i];
237: Class retType = method.getReturnType();
238:
239: if (i != 0)
240: iw.println();
241: iw.println(CodegenUtils.methodSignature(method_modifiers,
242: method, null));
243: iw.println("{");
244: iw.upIndent();
245:
246: generatePreDelegateCode(intfcl, genclass, method, iw);
247: generateDelegateCode(intfcl, genclass, method, iw);
248: generatePostDelegateCode(intfcl, genclass, method, iw);
249:
250: iw.downIndent();
251: iw.println("}");
252: }
253:
254: iw.println();
255: generateExtraDeclarations(intfcl, genclass, iw);
256:
257: iw.downIndent();
258: iw.println("}");
259: }
260:
261: protected void generateDelegateCode(Class intfcl, String genclass,
262: Method method, IndentedWriter iw) throws IOException {
263: Class retType = method.getReturnType();
264:
265: iw.println((retType == void.class ? "" : "return ") + "inner."
266: + CodegenUtils.methodCall(method) + ";");
267: }
268:
269: protected void generateBannerComment(IndentedWriter iw)
270: throws IOException {
271: iw.println("/*");
272: iw.println(" * This class generated by "
273: + this .getClass().getName());
274: iw.println(" * " + new Date());
275: iw.println(" * DO NOT HAND EDIT!!!!");
276: iw.println(" */");
277: }
278:
279: protected void generateExtraImports(IndentedWriter iw)
280: throws IOException {
281: }
282:
283: protected void generatePreDelegateCode(Class intfcl,
284: String genclass, Method method, IndentedWriter iw)
285: throws IOException {
286: }
287:
288: protected void generatePostDelegateCode(Class intfcl,
289: String genclass, Method method, IndentedWriter iw)
290: throws IOException {
291: }
292:
293: protected void generateExtraDeclarations(Class intfcl,
294: String genclass, IndentedWriter iw) throws IOException {
295: }
296: }
|