KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > corext > refactoring > binary > StubCreator


1 /*******************************************************************************
2  * Copyright (c) 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.corext.refactoring.binary;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.List JavaDoc;
15
16 import org.eclipse.core.runtime.Assert;
17 import org.eclipse.core.runtime.IProgressMonitor;
18 import org.eclipse.core.runtime.NullProgressMonitor;
19 import org.eclipse.core.runtime.SubProgressMonitor;
20
21 import org.eclipse.jdt.core.Flags;
22 import org.eclipse.jdt.core.IField;
23 import org.eclipse.jdt.core.IJavaElement;
24 import org.eclipse.jdt.core.IMember;
25 import org.eclipse.jdt.core.IMethod;
26 import org.eclipse.jdt.core.IType;
27 import org.eclipse.jdt.core.ITypeParameter;
28 import org.eclipse.jdt.core.JavaModelException;
29 import org.eclipse.jdt.core.Signature;
30
31 import org.eclipse.jdt.internal.corext.refactoring.Checks;
32 import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
33
34 public class StubCreator {
35
36     /** The internal string buffer */
37     protected StringBuffer JavaDoc fBuffer;
38
39     /** Should stubs for private member be generated as well? */
40     protected final boolean fStubInvisible;
41
42     public StubCreator(final boolean stubInvisible) {
43         fStubInvisible= stubInvisible;
44     }
45
46     protected void appendEnumConstants(final IType type) throws JavaModelException {
47         final IField[] fields= type.getFields();
48         final List JavaDoc list= new ArrayList JavaDoc(fields.length);
49         for (int index= 0; index < fields.length; index++) {
50             final IField field= fields[index];
51             if (Flags.isEnum(field.getFlags()))
52                 list.add(field);
53         }
54         for (int index= 0; index < list.size(); index++) {
55             if (index > 0)
56                 fBuffer.append(","); //$NON-NLS-1$
57
fBuffer.append(((IField) list.get(index)).getElementName());
58         }
59         fBuffer.append(";"); //$NON-NLS-1$
60
}
61
62     protected void appendExpression(final String JavaDoc signature) {
63         switch (signature.charAt(0)) {
64             case Signature.C_BOOLEAN:
65                 fBuffer.append("false"); //$NON-NLS-1$
66
break;
67             case Signature.C_BYTE:
68             case Signature.C_CHAR:
69             case Signature.C_DOUBLE:
70             case Signature.C_FLOAT:
71             case Signature.C_INT:
72             case Signature.C_LONG:
73             case Signature.C_SHORT:
74                 fBuffer.append("0"); //$NON-NLS-1$
75
break;
76             default:
77                 fBuffer.append("("); //$NON-NLS-1$
78
fBuffer.append(Signature.toString(signature));
79                 fBuffer.append(")"); //$NON-NLS-1$
80
fBuffer.append("null"); //$NON-NLS-1$
81
break;
82         }
83     }
84
85     protected void appendFieldDeclaration(final IField field) throws JavaModelException {
86         appendFlags(field);
87         fBuffer.append(" "); //$NON-NLS-1$
88
final String JavaDoc signature= field.getTypeSignature();
89         fBuffer.append(Signature.toString(signature));
90         fBuffer.append(" "); //$NON-NLS-1$
91
fBuffer.append(field.getElementName());
92         if (Flags.isFinal(field.getFlags())) {
93             fBuffer.append("="); //$NON-NLS-1$
94
appendExpression(signature);
95         }
96         fBuffer.append(";"); //$NON-NLS-1$
97
}
98
99     protected void appendFlags(final IMember member) throws JavaModelException {
100         int flags= member.getFlags();
101         final int kind= member.getElementType();
102         if (kind == IJavaElement.TYPE) {
103             flags&= ~Flags.AccSuper;
104             final IType type= (IType) member;
105             if (!type.isMember())
106                 flags&= ~Flags.AccPrivate;
107         }
108         if (Flags.isEnum(flags))
109             flags&= ~Flags.AccFinal;
110         if (kind == IJavaElement.METHOD) {
111             flags&= ~Flags.AccVarargs;
112             flags&= ~Flags.AccBridge;
113         }
114         if (flags != 0)
115             fBuffer.append(Flags.toString(flags));
116     }
117
118     protected void appendMembers(final IType type, final IProgressMonitor monitor) throws JavaModelException {
119         try {
120             monitor.beginTask(RefactoringCoreMessages.StubCreationOperation_creating_type_stubs, 1);
121             final IJavaElement[] children= type.getChildren();
122             for (int index= 0; index < children.length; index++) {
123                 final IMember child= (IMember) children[index];
124                 final int flags= child.getFlags();
125                 final boolean isPrivate= Flags.isPrivate(flags);
126                 final boolean isDefault= !Flags.isPublic(flags) && !Flags.isProtected(flags) && !isPrivate;
127                 final boolean stub= fStubInvisible || (!isPrivate && !isDefault);
128                 if (child instanceof IType) {
129                     if (stub)
130                         appendTypeDeclaration((IType) child, new SubProgressMonitor(monitor, 1));
131                 } else if (child instanceof IField) {
132                     if (stub && !Flags.isEnum(flags) && !Flags.isSynthetic(flags))
133                         appendFieldDeclaration((IField) child);
134                 } else if (child instanceof IMethod) {
135                     final IMethod method= (IMethod) child;
136                     final String JavaDoc name= method.getElementName();
137                     if (method.getDeclaringType().isEnum()) {
138                         final int count= method.getNumberOfParameters();
139                         if (count == 0 && "values".equals(name)) //$NON-NLS-1$
140
continue;
141                         if (count == 1 && "valueOf".equals(name) && "Ljava.lang.String;".equals(method.getParameterTypes()[0])) //$NON-NLS-1$ //$NON-NLS-2$
142
continue;
143                         if (method.isConstructor())
144                             continue;
145                     }
146                     boolean skip= !stub || name.equals("<clinit>"); //$NON-NLS-1$
147
if (method.isConstructor())
148                         skip= false;
149                     skip= skip || Flags.isSynthetic(flags) || Flags.isBridge(flags);
150                     if (!skip)
151                         appendMethodDeclaration(method);
152                 }
153                 fBuffer.append("\n"); //$NON-NLS-1$
154
}
155         } finally {
156             monitor.done();
157         }
158     }
159
160     protected void appendMethodBody(final IMethod method) throws JavaModelException {
161         if (method.isConstructor()) {
162             final IType declaringType= method.getDeclaringType();
163             String JavaDoc superSignature= declaringType.getSuperclassTypeSignature();
164             if (superSignature != null) {
165                 superSignature= Signature.getTypeErasure(superSignature);
166                 final IType superclass= declaringType.getJavaProject().findType(Signature.getSignatureQualifier(superSignature), Signature.getSignatureSimpleName(superSignature));
167                 if (superclass != null) {
168                     final IMethod[] superMethods= superclass.getMethods();
169                     IMethod superConstructor= null;
170                     final int length= superMethods.length;
171                     for (int index= 0; index < length; index++) {
172                         final IMethod superMethod= superMethods[index];
173                         if (superMethod.isConstructor() && !Flags.isPrivate(superMethod.getFlags())) {
174                             superConstructor= superMethod;
175                             if (superConstructor.getExceptionTypes().length == 0)
176                                 break;
177                         }
178                     }
179                     if (superConstructor != null) {
180                         final String JavaDoc[] superParameters= superConstructor.getParameterTypes();
181                         final int paramLength= superParameters.length;
182                         if (paramLength != 0) {
183                             fBuffer.append("super("); //$NON-NLS-1$
184
for (int index= 0; index < paramLength; index++) {
185                                 if (index > 0)
186                                     fBuffer.append(","); //$NON-NLS-1$
187
appendExpression(superParameters[index]);
188                             }
189                             fBuffer.append(");"); //$NON-NLS-1$
190
}
191                     }
192                 }
193             }
194         } else {
195             String JavaDoc returnType= method.getReturnType();
196             if (!Signature.SIG_VOID.equals(returnType)) {
197                 fBuffer.append("return "); //$NON-NLS-1$
198
appendExpression(returnType);
199                 fBuffer.append(";"); //$NON-NLS-1$
200
}
201         }
202     }
203
204     protected void appendMethodDeclaration(final IMethod method) throws JavaModelException {
205         appendFlags(method);
206         fBuffer.append(" "); //$NON-NLS-1$
207
final String JavaDoc returnType= method.getReturnType();
208         if (!method.isConstructor()) {
209             fBuffer.append(Signature.toString(returnType));
210             fBuffer.append(" "); //$NON-NLS-1$
211
final ITypeParameter[] parameters= method.getTypeParameters();
212             if (parameters.length > 0) {
213                 appendTypeParameters(parameters);
214                 fBuffer.append(" "); //$NON-NLS-1$
215
}
216         }
217         fBuffer.append(method.getElementName());
218         fBuffer.append("("); //$NON-NLS-1$
219
final String JavaDoc[] parameterTypes= method.getParameterTypes();
220         final int flags= method.getFlags();
221         final boolean varargs= Flags.isVarargs(flags);
222         final int parameterLength= parameterTypes.length;
223         for (int index= 0; index < parameterLength; index++) {
224             if (index > 0)
225                 fBuffer.append(","); //$NON-NLS-1$
226
fBuffer.append(Signature.toString(parameterTypes[index]));
227             if (varargs && index == parameterLength - 1) {
228                 final int length= fBuffer.length();
229                 if (length >= 2 && fBuffer.indexOf("[]", length - 2) >= 0) //$NON-NLS-1$
230
fBuffer.setLength(length - 2);
231                 fBuffer.append("..."); //$NON-NLS-1$
232
}
233             fBuffer.append(" "); //$NON-NLS-1$
234
appendMethodParameterName(method, index);
235         }
236         fBuffer.append(")"); //$NON-NLS-1$
237
final String JavaDoc[] exceptionTypes= method.getExceptionTypes();
238         final int exceptionLength= exceptionTypes.length;
239         if (exceptionLength > 0)
240             fBuffer.append(" throws "); //$NON-NLS-1$
241
for (int index= 0; index < exceptionLength; index++) {
242             if (index > 0)
243                 fBuffer.append(","); //$NON-NLS-1$
244
fBuffer.append(Signature.toString(exceptionTypes[index]));
245         }
246         if (Flags.isAbstract(flags) || Flags.isNative(flags))
247             fBuffer.append(";"); //$NON-NLS-1$
248
else {
249             fBuffer.append("{\n"); //$NON-NLS-1$
250
appendMethodBody(method);
251             fBuffer.append("}"); //$NON-NLS-1$
252
}
253     }
254
255     protected void appendMethodParameterName(IMethod method, int index) {
256         fBuffer.append("a"); //$NON-NLS-1$
257
fBuffer.append(index);
258     }
259
260     protected void appendSuperInterfaceTypes(final IType type) throws JavaModelException {
261         final String JavaDoc[] signatures= type.getSuperInterfaceTypeSignatures();
262         if (signatures.length > 0) {
263             if (type.isInterface())
264                 fBuffer.append(" extends "); //$NON-NLS-1$
265
else
266                 fBuffer.append(" implements "); //$NON-NLS-1$
267
}
268         for (int index= 0; index < signatures.length; index++) {
269             if (index > 0)
270                 fBuffer.append(","); //$NON-NLS-1$
271
fBuffer.append(Signature.toString(signatures[index]));
272         }
273     }
274
275     protected void appendTopLevelType(final IType type, IProgressMonitor subProgressMonitor) throws JavaModelException {
276         String JavaDoc packageName= type.getPackageFragment().getElementName();
277         if (packageName.length() > 0) {
278             fBuffer.append("package "); //$NON-NLS-1$
279
fBuffer.append(packageName);
280             fBuffer.append(";\n"); //$NON-NLS-1$
281
}
282         appendTypeDeclaration(type, subProgressMonitor);
283     }
284
285     protected void appendTypeDeclaration(final IType type, final IProgressMonitor monitor) throws JavaModelException {
286         try {
287             monitor.beginTask(RefactoringCoreMessages.StubCreationOperation_creating_type_stubs, 1);
288             if (type.isInterface()) {
289                 appendFlags(type);
290                 fBuffer.append(" interface "); //$NON-NLS-1$
291
fBuffer.append(type.getElementName());
292                 appendTypeParameters(type.getTypeParameters());
293                 appendSuperInterfaceTypes(type);
294                 fBuffer.append("{\n"); //$NON-NLS-1$
295
appendMembers(type, new SubProgressMonitor(monitor, 1));
296                 fBuffer.append("}"); //$NON-NLS-1$
297
} else if (type.isClass()) {
298                 appendFlags(type);
299                 fBuffer.append(" class "); //$NON-NLS-1$
300
fBuffer.append(type.getElementName());
301                 appendTypeParameters(type.getTypeParameters());
302                 final String JavaDoc signature= type.getSuperclassTypeSignature();
303                 if (signature != null) {
304                     fBuffer.append(" extends "); //$NON-NLS-1$
305
fBuffer.append(Signature.toString(signature));
306                 }
307                 appendSuperInterfaceTypes(type);
308                 fBuffer.append("{\n"); //$NON-NLS-1$
309
appendMembers(type, new SubProgressMonitor(monitor, 1));
310                 fBuffer.append("}"); //$NON-NLS-1$
311
} else if (type.isAnnotation()) {
312                 appendFlags(type);
313                 fBuffer.append(" @interface "); //$NON-NLS-1$
314
fBuffer.append(type.getElementName());
315                 fBuffer.append("{\n"); //$NON-NLS-1$
316
appendMembers(type, new SubProgressMonitor(monitor, 1));
317                 fBuffer.append("}"); //$NON-NLS-1$
318
} else if (type.isEnum()) {
319                 appendFlags(type);
320                 fBuffer.append(" enum "); //$NON-NLS-1$
321
fBuffer.append(type.getElementName());
322                 appendSuperInterfaceTypes(type);
323                 fBuffer.append("{\n"); //$NON-NLS-1$
324
appendEnumConstants(type);
325                 appendMembers(type, new SubProgressMonitor(monitor, 1));
326                 fBuffer.append("}"); //$NON-NLS-1$
327
}
328         } finally {
329             monitor.done();
330         }
331     }
332
333     protected void appendTypeParameters(final ITypeParameter[] parameters) throws JavaModelException {
334         final int length= parameters.length;
335         if (length > 0)
336             fBuffer.append("<"); //$NON-NLS-1$
337
for (int index= 0; index < length; index++) {
338             if (index > 0)
339                 fBuffer.append(","); //$NON-NLS-1$
340
final ITypeParameter parameter= parameters[index];
341             fBuffer.append(parameter.getElementName());
342             final String JavaDoc[] bounds= parameter.getBounds();
343             final int size= bounds.length;
344             if (size > 0)
345                 fBuffer.append(" extends "); //$NON-NLS-1$
346
for (int offset= 0; offset < size; offset++) {
347                 if (offset > 0)
348                     fBuffer.append(" & "); //$NON-NLS-1$
349
fBuffer.append(bounds[offset]);
350             }
351         }
352         if (length > 0)
353             fBuffer.append(">"); //$NON-NLS-1$
354
}
355
356     /**
357      * @param topLevelType
358      * @param monitor
359      * progress monitor, can be <code>null</code>
360      * @return source stub
361      * @throws JavaModelException
362      */

363     public String JavaDoc createStub(IType topLevelType, IProgressMonitor monitor) throws JavaModelException {
364         Assert.isTrue(Checks.isTopLevel(topLevelType));
365         if (monitor == null)
366             monitor= new NullProgressMonitor();
367
368         fBuffer= new StringBuffer JavaDoc(2046);
369         appendTopLevelType(topLevelType, monitor);
370         String JavaDoc result= fBuffer.toString();
371         fBuffer= null;
372         return result;
373     }
374
375 }
376
Popular Tags