/******************************************************************************* * Copyright (c) 2003, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jst.j2ee.internal.common.operations; import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.ABSTRACT_METHODS; import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.CLASS_NAME; import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.CONSTRUCTOR; import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.INTERFACES; import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.JAVA_PACKAGE; import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.JAVA_PACKAGE_FRAGMENT_ROOT; import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.MODIFIER_ABSTRACT; import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.MODIFIER_FINAL; import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.MODIFIER_PUBLIC; import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.SOURCE_FOLDER; import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.SUPERCLASS; import java.io.ByteArrayInputStream; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.commands.operations.AbstractOperation; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.jdt.core.Flags; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.ITypeHierarchy; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.Signature; import org.eclipse.jem.util.emf.workbench.ProjectUtilities; import org.eclipse.jem.workbench.utility.JemProjectUtilities; import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin; import org.eclipse.wst.common.componentcore.internal.operation.IArtifactEditOperationDataModelProperties; import org.eclipse.wst.common.frameworks.datamodel.AbstractDataModelOperation; import org.eclipse.wst.common.frameworks.datamodel.IDataModel; /** * NewJavaClassOperation is a data model operation that is used to create a default instance of a new java class * based on the input and properties set in the NewJavaClassDataModelProvider. * @see org.eclipse.jst.j2ee.internal.common.operations.NewJavaClassDataModelProvider * * It is a subclass of ArtifactEditProviderOperation and clients can invoke this operation as is or it may be subclassed to * add additional or modify behaviour. The execute() method can be extended to drive this behaviour. * @see org.eclipse.wst.common.componentcore.internal.operation.ArtifactEditProviderOperation * * The new java class is generated through the use of adding a series of static tokens defined within to * an ongoing string buffer. * * * This needs to be removed as it is legacy inherited from another team */ public class NewJavaClassOperation extends AbstractDataModelOperation { // Tokens for string buffer creation of default java class protected static final String EMPTY_STRING = ""; //$NON-NLS-1$ protected static final String TAB = "\t"; //$NON-NLS-1$ protected static final String SPACE = " "; //$NON-NLS-1$ protected static final String DOT = "."; //$NON-NLS-1$ protected static final String COMMA = ","; //$NON-NLS-1$ protected static final String SEMICOLON = ";"; //$NON-NLS-1$ protected static final String POUND = "#"; //$NON-NLS-1$ protected static final String OPEN_PAR = "("; //$NON-NLS-1$ protected static final String CLOSE_PAR = ")"; //$NON-NLS-1$ protected static final String OPEN_BRA = "{"; //$NON-NLS-1$ protected static final String CLOSE_BRA = "}"; //$NON-NLS-1$ protected static final String lineSeparator = System.getProperty("line.separator"); //$NON-NLS-1$ protected static final String JAVA_LANG_OBJECT = "java.lang.Object"; //$NON-NLS-1$ protected static final String PACKAGE = "package "; //$NON-NLS-1$ protected static final String CLASS = "class "; //$NON-NLS-1$ protected static final String IMPORT = "import "; //$NON-NLS-1$ protected static final String EXTENDS = "extends "; //$NON-NLS-1$ protected static final String IMPLEMENTS = "implements "; //$NON-NLS-1$ protected static final String THROWS = "throws "; //$NON-NLS-1$ protected static final String SUPER = "super"; //$NON-NLS-1$ protected static final String PUBLIC = "public "; //$NON-NLS-1$ protected static final String PROTECTED = "protected "; //$NON-NLS-1$ protected static final String PRIVATE = "private "; //$NON-NLS-1$ protected static final String STATIC = "static "; //$NON-NLS-1$ protected static final String ABSTRACT = "abstract "; //$NON-NLS-1$ protected static final String FINAL = "final "; //$NON-NLS-1$ protected static final String VOID = "void"; //$NON-NLS-1$ protected static final String INT = "int"; //$NON-NLS-1$ protected static final String BOOLEAN = "boolean"; //$NON-NLS-1$ protected static final String MAIN_METHOD = "\tpublic static void main(String[] args) {"; //$NON-NLS-1$ protected static final String TODO_COMMENT = "\t\t// TODO Auto-generated method stub"; //$NON-NLS-1$ protected static final String RETURN_NULL = "\t\treturn null;"; //$NON-NLS-1$ protected static final String RETURN_0 = "\t\treturn 0;"; //$NON-NLS-1$ protected static final String RETURN_FALSE = "\t\treturn false;"; //$NON-NLS-1$ /** * This is a list of all the calculated import statements that will need to be added */ private List importStatements; /** * This is a NewJavaClassOperation constructor. Data models passed in should be instances * of NewJavaClassDataModel. This method does not accept null. It will not return null. * @see NewJavaClassDataModelProvider * * @param dataModel * @return NewJavaClassOperation */ public NewJavaClassOperation(IDataModel dataModel) { super(dataModel); importStatements = new ArrayList(); } /** * Subclasses may extend this method to add their own actions during execution. * The implementation of the execute method drives the running of the operation. This * method will create the source folder, the java package, and then create the java file. * This method will accept null. * @see AbstractOperation#execute(org.eclipse.core.runtime.IProgressMonitor, org.eclipse.core.runtime.IAdaptable) * * @param monitor ProgressMonitor * @throws CoreException * @throws InterruptedException * @throws InvocationTargetException */ public IStatus doExecute(IProgressMonitor monitor, IAdaptable info) throws ExecutionException { // Ensure source folder exists IFolder sourceFolder = createJavaSourceFolder(); // Ensure java package exists IPackageFragment pack = createJavaPackage(); // Create java class createJavaFile(sourceFolder, pack); return OK_STATUS; } /** * This method will return the java source folder as specified in the java class data model. * It will create the java source folder if it does not exist. This method may return null. * @see #SOURCE_FOLDER * @see IFolder#create(boolean, boolean, org.eclipse.core.runtime.IProgressMonitor) * * @return IFolder the java source folder */ protected final IFolder createJavaSourceFolder() { // Get the source folder name from the data model String folderFullPath = model.getStringProperty(SOURCE_FOLDER); IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); IFolder folder = root.getFolder(new Path(folderFullPath)); // If folder does not exist, create the folder with the specified path if (!folder.exists()) { try { folder.create(true, true, null); } catch (CoreException e) { J2EEPlugin.logError(e); } } // Return the source folder return folder; } /** * This method will return the java package as specified by the new java class data model. * If the package does not exist, it will create the package. This method should not return * null. * @see #JAVA_PACKAGE * @see IPackageFragmentRoot#createPackageFragment(java.lang.String, boolean, org.eclipse.core.runtime.IProgressMonitor) * * @return IPackageFragment the java package */ protected final IPackageFragment createJavaPackage() { // Retrieve the package name from the java class data model String packageName = model.getStringProperty(JAVA_PACKAGE); IPackageFragmentRoot packRoot = (IPackageFragmentRoot) model.getProperty(JAVA_PACKAGE_FRAGMENT_ROOT); IPackageFragment pack = packRoot.getPackageFragment(packageName); // Handle default package if (pack == null) { pack = packRoot.getPackageFragment(""); //$NON-NLS-1$ } // Create the package fragment if it does not exist if (!pack.exists()) { String packName = pack.getElementName(); try { pack = packRoot.createPackageFragment(packName, true, null); } catch (JavaModelException e) { J2EEPlugin.logError(e); } } // Return the package return pack; } /** * Subclasses may extend this method to provide their own java file creation path. * This implementation will use the properties specified in the data model to create * a default java class. The class will be built using pre-defined tokens and will be * built up using a string buffer. The method getJavaFileContent will handle the building * of the string buffer while this method will write those contents to the file. * This method does not accept null parameters. * @see #CLASS_NAME * @see NewJavaClassOperation#getJavaFileContent(IPackageFragment, String) * * @param sourceFolder * @param pack */ protected void createJavaFile(IFolder sourceFolder, IPackageFragment pack) { // Retrieve properties from the java class data model String packageName = model.getStringProperty(JAVA_PACKAGE); String className = model.getStringProperty(CLASS_NAME); String fileName = className + ".java"; //$NON-NLS-1$ //ICompilationUnit cu = null; try { // Get the java file content from the string buffer String content = getJavaFileContent(pack, className); // Create the compilation unit pack.createCompilationUnit(fileName, content, true, null); byte[] contentBytes = content.getBytes(); IPath packageFullPath = new Path(packageName.replace('.', IPath.SEPARATOR)); IPath javaFileFullPath = packageFullPath.append(fileName); IFile file = sourceFolder.getFile(javaFileFullPath); // Set the contents in the file if it already exists if (file != null && file.exists()) { file.setContents(new ByteArrayInputStream(contentBytes), false, true, null); } // If the file does not exist, create it with the contents else if (file != null) { file.create(new ByteArrayInputStream(contentBytes), false, null); } // editModel.getWorkingCopy(cu, true); //Track CU. } catch (Exception ex) { J2EEPlugin.logError(ex); } } /** * This is intended for internal use only. This is where the string buffer for the contents * of the java file is built up using the properties in the data model and the predefined tokens. * This method will not accept null parameters. It will not return null. * @see NewJavaClassDataModelProvider * @see NewJavaClassOperation#createJavaFile(IFolder, IPackageFragment) * * @param pack * @param className * @return String java file contents */ private String getJavaFileContent(IPackageFragment pack, String className) { // Create the superclass name String superclassName = model.getStringProperty(SUPERCLASS); List interfaces = (List) model.getProperty(INTERFACES); String packageStatement = getPackageStatement(pack); // Create the import statements setupImportStatements(pack, superclassName, interfaces); // Create the class declaration String classDeclaration = getClassDeclaration(superclassName, className, interfaces); // Create the fields String fields = getFields(); // Create the methods String methods = getMethodStubs(superclassName, className); StringBuffer contents = new StringBuffer(); // Add the package statement to the buffer contents.append(packageStatement); // Add all the import statements to the buffer for (int i = 0; i < importStatements.size(); i++) { contents.append(IMPORT + importStatements.get(i) + SEMICOLON); contents.append(lineSeparator); } contents.append(lineSeparator); // Add the class declaration to the buffer contents.append(classDeclaration); // Add the fields to the buffer contents.append(fields); // Add the method bodies to the buffer contents.append(methods); contents.append(CLOSE_BRA); // Return the contents of the buffer return contents.toString(); } /** * This is intended for internal use only. This method will return a package string for * the class. It will not accept a null parameter. It will not return null. * @see NewJavaClassOperation#getJavaFileContent(IPackageFragment, String) * * @param pack * @return String package statement */ private String getPackageStatement(IPackageFragment pack) { StringBuffer sb = new StringBuffer(); // If it is not default package, add package statement if (!pack.isDefaultPackage()) { sb.append(PACKAGE + pack.getElementName() + SEMICOLON); sb.append(lineSeparator); sb.append(lineSeparator); } // Return contents of buffer return sb.toString(); } /** * This method is intended for internal use. It checks to see if the qualified class name * belongs to the specified package. This method will not accept nulls. It will not return null. * @see NewJavaClassOperation#setupImportStatements(IPackageFragment, String, List) * * @param packageFragment * @param className * @return boolean is class in this package? */ private boolean isSamePackage(IPackageFragment packageFragment, String className) { if (className != null && className.length() > 0) { String sPackageName = packageFragment.getElementName(); String classPackageName = Signature.getQualifier(className); // Does the qualified class's package name match the passed in package's name? if (classPackageName.equals(sPackageName)) return true; } return false; } /** * This method is intended for internal use only. This method will set up the required import * statements and cache to the importStatements list. * This method does not accept null parameters. * @see NewJavaClassOperation#importStatements * @see NewJavaClassOperation#getJavaFileContent(IPackageFragment, String) * * @param pack * @param superclassName * @param interfaces */ private void setupImportStatements(IPackageFragment pack, String superclassName, List interfaces) { // If there is a superclass and it is not in the same package, add an import for it if (superclassName != null && superclassName.length() > 0) { if (!superclassName.equals(JAVA_LANG_OBJECT) && !isSamePackage(pack, superclassName)) { importStatements.add(superclassName); } } // Add an import the list of implemented interfaces if (interfaces != null && interfaces.size() > 0) { int size = interfaces.size(); for (int i = 0; i < size; i++) { String interfaceName = (String) interfaces.get(i); if(!interfaceName.equals(JAVA_LANG_OBJECT) && !isSamePackage(pack, interfaceName)){ importStatements.add(interfaceName); } } } } /** * This class is intended for internal use only. This will build up the class declartion * statement based off the properties set in the java class data model. * This method does not accept null parameters. It will not return null. * @see NewJavaClassOperation#getJavaFileContent(IPackageFragment, String) * * @param superClass * @param className * @param interfaces * @return String class declaration string */ private String getClassDeclaration(String superClass, String className, List interfaces) { String innerSuperClass = superClass; StringBuffer sb = new StringBuffer(); // Append appropriate modifiers if (model.getBooleanProperty(MODIFIER_PUBLIC)) sb.append(PUBLIC); if (model.getBooleanProperty(MODIFIER_ABSTRACT)) sb.append(ABSTRACT); if (model.getBooleanProperty(MODIFIER_FINAL)) sb.append(FINAL); // Add the class token sb.append(CLASS); // Add the class name sb.append(className + SPACE); // If there is a superclass, add the extends and super class name if (innerSuperClass != null && innerSuperClass.length() > 0 && !innerSuperClass.equals(JAVA_LANG_OBJECT)) { int index = innerSuperClass.lastIndexOf(DOT); if (index != -1) innerSuperClass = innerSuperClass.substring(index + 1); sb.append(EXTENDS + innerSuperClass + SPACE); } // If there are interfaces, add the implements and then interate over the interface list if (interfaces != null && interfaces.size() > 0) { sb.append(IMPLEMENTS); int size = interfaces.size(); for (int i = 0; i < size; i++) { String interfaceName = (String) interfaces.get(i); int index = interfaceName.lastIndexOf(DOT); if (index != -1) interfaceName = interfaceName.substring(index + 1); sb.append(interfaceName); if (i < size - 1) sb.append(COMMA); sb.append(SPACE); } } sb.append(OPEN_BRA); sb.append(lineSeparator); // Return the finished class declaration string return sb.toString(); } /** * Subclasses may extend this method to add their own fields. The default implementation * is not to have any fields. This method will not return null. * @see NewJavaClassOperation#getJavaFileContent(IPackageFragment, String) * * @return String fields string */ protected String getFields() { return EMPTY_STRING; } /** * This method is intended for internal use only. This will build up a string with the * contents of all the method stubs for the unimplemented methods defined in the interfaces. * It will also add inherited constructors from the superclass as appropriate. * This method does not accept null parameters. It will not return null. * @see NewJavaClassOperation#getJavaFileContent(IPackageFragment, String) * * @param superclassName * @param className * @return String method stubs string */ private String getMethodStubs(String superclassName, String className) { StringBuffer sb = new StringBuffer(); IJavaProject javaProj = JemProjectUtilities.getJavaProject(getTargetProject()); if (model.getBooleanProperty(INewJavaClassDataModelProperties.MAIN_METHOD)) { // Add main method sb.append(MAIN_METHOD); sb.append(lineSeparator); sb.append(TODO_COMMENT); sb.append(lineSeparator); sb.append(TAB + CLOSE_BRA); sb.append(lineSeparator); sb.append(lineSeparator); } IType superClassType = null; if (model.getBooleanProperty(CONSTRUCTOR) || model.getBooleanProperty(ABSTRACT_METHODS)) { // Find super class type try { superClassType = javaProj.findType(superclassName); } catch (JavaModelException e) { J2EEPlugin.logError(e); } } if (model.getBooleanProperty(CONSTRUCTOR)) { // Implement constructors from superclass try { if (superClassType != null) { IMethod[] methods = superClassType.getMethods(); for (int j = 0; j < methods.length; j++) { if (methods[j].isConstructor() && !Flags.isPrivate(methods[j].getFlags()) && !hasGenericParams(methods[j])) { String methodStub = getMethodStub(methods[j], superclassName, className); sb.append(methodStub); } } } } catch (JavaModelException e) { J2EEPlugin.logError(e); } } // Add unimplemented methods defined in the interfaces list if (model.getBooleanProperty(ABSTRACT_METHODS) && superClassType != null) { String methodStub = getUnimplementedMethodsFromSuperclass(superClassType, className); if (methodStub != null && methodStub.trim().length() > 0) sb.append(methodStub); methodStub = getUnimplementedMethodsFromInterfaces(superClassType, className, javaProj); if (methodStub != null && methodStub.trim().length() > 0) sb.append(methodStub); } // Add any user defined method stubs if (superClassType != null) { String userDefined = getUserDefinedMethodStubs(superClassType); if (userDefined != null && userDefined.trim().length() > 0) sb.append(userDefined); } // Return the methods string return sb.toString(); } private boolean hasGenericParams(IMethod method) { try { IType parentType = method.getDeclaringType(); String[] paramTypes = method.getParameterTypes(); int nP = paramTypes.length; for (int i = 0; i < nP; i++) { String type = paramTypes[i]; if (!isPrimitiveType(type)) { type = JavaModelUtil.getResolvedTypeName(type, parentType); if(type.indexOf(Signature.C_GENERIC_START, 0) != -1){ return true; } } } } catch (JavaModelException e) { J2EEPlugin.logError(e); } return false; } /** * This method is intended for internal use only. This will retrieve method stubs for * unimplemented methods in the superclass that will need to be created in the new class. * This method does not accept null parameters. It will not return null. * @see NewJavaClassOperation#getMethodStubs(String, String) * * @param superClassType * @param className * @return String unimplemented methods defined in superclass */ private String getUnimplementedMethodsFromSuperclass(IType superClassType, String className) { StringBuffer sb = new StringBuffer(); try { // Implement abstract methods from superclass IMethod[] methods = superClassType.getMethods(); for (int j = 0; j < methods.length; j++) { IMethod method = methods[j]; int flags = method.getFlags(); // Add if the method is abstract, not private or static, and the option is selected in data model if ((Flags.isAbstract(flags) && !Flags.isStatic(flags) && !Flags.isPrivate(flags)) || implementImplementedMethod(methods[j])) { String methodStub = getMethodStub(methods[j], superClassType.getFullyQualifiedName(), className); sb.append(methodStub); } } } catch (JavaModelException e) { J2EEPlugin.logError(e); } // Return method stubs string return sb.toString(); } /** * This method is intended for internal use only. This will retrieve method stubs for * unimplemented methods defined in the interfaces that will need to be created in the new class. * This method does not accept null parameters. It will not return null. * @see NewJavaClassOperation#getMethodStubs(String, String) * * @param superClassType * @param className * @param javaProj * @return String unimplemented methods defined in interfaces */ private String getUnimplementedMethodsFromInterfaces(IType superClassType, String className, IJavaProject javaProj) { StringBuffer sb = new StringBuffer(); try { // Implement defined methods from interfaces List interfaces = (List) model.getProperty(INTERFACES); if (interfaces != null) { for (int i = 0; i < interfaces.size(); i++) { String qualifiedClassName = (String) interfaces.get(i); IType interfaceType = javaProj.findType(qualifiedClassName); IMethod[] methodArray = interfaceType.getMethods(); // Make sure the method isn't already defined in the heirarchy for (int j = 0; j < methodArray.length; j++) { if (isMethodImplementedInHierarchy(methodArray[j], superClassType)) continue; String methodStub = getMethodStub(methodArray[j], qualifiedClassName, className); sb.append(methodStub); } } } } catch (JavaModelException e) { J2EEPlugin.logError(e); } // Return method stubs string return sb.toString(); } /** * This method is intended for internal use only. Checks to see if the passed type name * is of a primitive type. This method does not accept null. It will not return null. * @see Signature#getElementType(java.lang.String) * * @param typeName * @return boolean is type Primitive? */ private boolean isPrimitiveType(String typeName) { char first = Signature.getElementType(typeName).charAt(0); return (first != Signature.C_RESOLVED && first != Signature.C_UNRESOLVED); } /** * This method is intended for internal use only. This will add import statements for the specified * type if it is determined to be necessary. This does accept null parameters. It will not return null. * @see NewJavaClassOperation#getMethodStub(IMethod, String, String) * * @param refTypeSig * @param declaringType * @return String type signature * @throws JavaModelException */ private String resolveAndAdd(String refTypeSig, IType declaringType) throws JavaModelException { if(refTypeSig.indexOf(Signature.C_GENERIC_START, 0) != -1){ getImportStatements(refTypeSig, declaringType); } else { String resolvedTypeName = JavaModelUtil.getResolvedTypeName(refTypeSig, declaringType); // Could type not be resolved and is import statement missing? if (resolvedTypeName != null && !importStatements.contains(resolvedTypeName) && !resolvedTypeName.startsWith("java.lang")) { //$NON-NLS-1$ importStatements.add(resolvedTypeName); } } return Signature.toString(refTypeSig); } private void getImportStatements(String signature, IType declaringType) throws JavaModelException{ String erasure = Signature.getTypeErasure(signature); String resolvedTypeName = JavaModelUtil.getResolvedTypeName(erasure, declaringType); if (resolvedTypeName != null && !importStatements.contains(resolvedTypeName) && !resolvedTypeName.startsWith("java.lang")) { //$NON-NLS-1$ importStatements.add(resolvedTypeName); } String [] params = Signature.getTypeArguments(signature); for(int i=0;i<params.length; i++){ getImportStatements(params[i], declaringType); } } /** * This method is intended for internal use only. This will use the predefined tokens to generate the * actual method stubs. This method does not accept null parameters. It will not return null. * * @param method * @param superClassName * @param className * @return String method stub */ private String getMethodStub(IMethod method, String superClassName, String className) { StringBuffer sb = new StringBuffer(); try { IType parentType = method.getDeclaringType(); String name = method.getElementName(); String[] paramTypes = method.getParameterTypes(); String[] paramNames = method.getParameterNames(); String[] exceptionTypes = method.getExceptionTypes(); // Parameters String String paramString = EMPTY_STRING; int nP = paramTypes.length; for (int i = 0; i < nP; i++) { String type = paramTypes[i]; // update import statements if (!isPrimitiveType(type)) { type = resolveAndAdd(type, parentType); } else { type = Signature.toString(type); } int index = type.lastIndexOf(DOT); if (index != -1) type = type.substring(index + 1); paramString += type + SPACE + paramNames[i]; if (i < nP - 1) paramString += COMMA + SPACE; } // Java doc sb.append("\t/* (non-Java-doc)"); //$NON-NLS-1$ sb.append(lineSeparator); sb.append("\t * @see "); //$NON-NLS-1$ sb.append(superClassName + POUND + name + OPEN_PAR); sb.append(paramString); sb.append(CLOSE_PAR); sb.append(lineSeparator); sb.append("\t */"); //$NON-NLS-1$ sb.append(lineSeparator); // access sb.append(TAB); if (Flags.isPublic(method.getFlags())) sb.append(PUBLIC); else if (Flags.isProtected(method.getFlags())) sb.append(PROTECTED); else if (Flags.isPrivate(method.getFlags())) sb.append(PRIVATE); String returnType = null; if (method.isConstructor()) { sb.append(className); } else { // return type returnType = method.getReturnType(); if (!isPrimitiveType(returnType)) { returnType = resolveAndAdd(returnType, parentType); } else { returnType = Signature.toString(returnType); } int idx = returnType.lastIndexOf(DOT); if (idx == -1) sb.append(returnType); else sb.append(returnType.substring(idx + 1)); sb.append(SPACE); // name sb.append(name); } // Parameters sb.append(OPEN_PAR + paramString + CLOSE_PAR); // exceptions int nE = exceptionTypes.length; if (nE > 0) { sb.append(SPACE + THROWS); for (int i = 0; i < nE; i++) { String type = exceptionTypes[i]; if (!isPrimitiveType(type)) { type = resolveAndAdd(type, parentType); } else { type = Signature.toString(type); } int index = type.lastIndexOf(DOT); if (index != -1) type = type.substring(index + 1); sb.append(type); if (i < nE - 1) sb.append(COMMA + SPACE); } } sb.append(SPACE + OPEN_BRA); sb.append(lineSeparator); if (method.isConstructor()) { sb.append(TAB + TAB + SUPER + OPEN_PAR); for (int i = 0; i < nP; i++) { sb.append(paramNames[i]); if (i < nP - 1) sb.append(COMMA + SPACE); } sb.append(CLOSE_PAR + SEMICOLON); sb.append(lineSeparator); } else { String methodBody = getMethodBody(method, returnType); sb.append(methodBody); } sb.append(TAB + CLOSE_BRA); sb.append(lineSeparator); sb.append(lineSeparator); } catch (JavaModelException e) { J2EEPlugin.logError(e); } return sb.toString(); } /** * This method is intended for internal use only. It checks to see whether or not the * method is already implemented in the class heirarchy. * It does not accept null parameters. It will not return null. * @see NewJavaClassOperation#getUnimplementedMethodsFromInterfaces(IType, String, IJavaProject) * * @param method * @param superClass * @return boolean is method already in heirarchy? */ private boolean isMethodImplementedInHierarchy(IMethod method, IType superClass) { boolean ret = false; IMethod foundMethod = findMethodImplementationInHierarchy(method, superClass); // if the method exists and the property is set on the data model, then return true if (foundMethod != null && foundMethod.exists() && !implementImplementedMethod(method)) ret = true; return ret; } /** * This method is intended for internal use only. This will recursively check the supertype heirarchy for * the passed in method. This will not accept null parameters. It will return null if the method does * not already exist in the heirarchy. * @see NewJavaClassOperation#isMethodImplementedInHierarchy(IMethod, IType) * * @param method * @param superClass * @return IMethod the method from the heirarchy */ private IMethod findMethodImplementationInHierarchy(IMethod method, IType superClass) { IMethod implementedMethod = null; try { if (superClass != null && superClass.exists()) { ITypeHierarchy tH = superClass.newSupertypeHierarchy(new NullProgressMonitor()); implementedMethod = findMethodImplementationInHierarchy(tH, superClass, method.getElementName(), method.getParameterTypes(), method.isConstructor()); } } catch (JavaModelException e) { //Ignore } return implementedMethod; } /** * This method is intended for internal use only. This will recursively check the supertype heirarchy for * the passed in method. This will not accept null parameters. It will return null if the method does * not already exist in the heirarchy. * @see NewJavaClassOperation#findMethodImplementationInHierarchy(IMethod, IType) * @see JavaModelUtil#findMethodImplementationInHierarchy(ITypeHierarchy, IType, String, String[], boolean) * * @param tH * @param thisType * @param methodName * @param parameterTypes * @param isConstructor * @return IMethod * @throws JavaModelException */ private IMethod findMethodImplementationInHierarchy(ITypeHierarchy tH, IType thisType, String methodName, String parameterTypes[], boolean isConstructor) throws JavaModelException { IMethod found = JavaModelUtil.findMethod(methodName, parameterTypes, isConstructor, thisType); // If method exists make sure it is not abstract if (found != null && !Flags.isAbstract(found.getFlags())) { return found; } // Check recursively return JavaModelUtil.findMethodInHierarchy(tH, thisType, methodName, parameterTypes, isConstructor); } /** * Subclasses may extend this method to provide their own specific method body definitions. * The default implementation is to add a todo, and to return the appropriate type. * This method does not accept null parameters. It will not return null. * @see NewJavaClassOperation#getMethodStub(IMethod, String, String) * * @param method * @param returnType * @return String method body */ protected String getMethodBody(IMethod method, String returnType) { // Add a todo comment String body = TODO_COMMENT; body += lineSeparator; // Add the appropriate default return type if (returnType == null || returnType.equals(VOID)) return body; if (returnType.equals(INT)) body += RETURN_0; else if (returnType.equals(BOOLEAN)) body += RETURN_FALSE; else body += RETURN_NULL; body += lineSeparator; // Return the method body return body; } /** * Subclasses may extend this method to provide their own user defined method stubs. The * default implementation to just return an empty string. This method will not accept * null parameter. It will not return null. * @see NewJavaClassOperation#getMethodStubs(String, String) * * @param superClassType * @return String user defined methods */ protected String getUserDefinedMethodStubs(IType superClassType) { return EMPTY_STRING; } /** * Subclasses may extend this method to provide their own specialized return on which nonimplemented * methods to implement. This does not accept a null parameter. This will not return null. * The default implementation is to always return false. * * @param method * @return boolean should implement method? */ protected boolean implementImplementedMethod(IMethod method) { return false; } @Override public IStatus execute(IProgressMonitor monitor, IAdaptable info) throws ExecutionException { return doExecute(monitor, info); } public IProject getTargetProject() { String projectName = model.getStringProperty(IArtifactEditOperationDataModelProperties.PROJECT_NAME); return ProjectUtilities.getProject(projectName); } }