| /******************************************************************************* |
| * Copyright (c) 2008 SAP AG 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: |
| * Kaloyan Raev, kaloyan.raev@sap.com - 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.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.PROJECT; |
| import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.SUPERCLASS; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.jdt.core.ICompilationUnit; |
| import org.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jdt.core.IMethod; |
| import org.eclipse.jdt.core.IType; |
| import org.eclipse.jdt.core.JavaCore; |
| import org.eclipse.jdt.core.JavaModelException; |
| import org.eclipse.jdt.core.Signature; |
| import org.eclipse.jdt.core.dom.AST; |
| import org.eclipse.jdt.core.dom.ASTNode; |
| import org.eclipse.jdt.core.dom.ASTParser; |
| import org.eclipse.jdt.core.dom.CompilationUnit; |
| import org.eclipse.jdt.core.dom.ITypeBinding; |
| import org.eclipse.jdt.core.dom.MethodDeclaration; |
| import org.eclipse.jdt.core.dom.Type; |
| import org.eclipse.jdt.core.dom.TypeDeclaration; |
| import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin; |
| import org.eclipse.wst.common.frameworks.datamodel.IDataModel; |
| |
| public class CreateJavaEEArtifactTemplateModel { |
| |
| /** |
| * Constant representing no compatibility flag. |
| */ |
| public static final int FLAG_NONE = 0x00000000; |
| |
| /** |
| * Constant representing the <i>Qualified Superclass Name</i> compatibility |
| * flag. |
| * |
| * <p> |
| * When this flag is set then the {@link #getSuperclassName()} method always |
| * returns the qualified name of the superclass. |
| * </p> |
| * |
| * @see #getSuperclassName() |
| */ |
| public static final int FLAG_QUALIFIED_SUPERCLASS_NAME = 0x00000001; |
| |
| /** |
| * Constant representing a combination of all possible compatibility flags. |
| */ |
| public static final int FLAG_ALL = 0xffffffff; |
| |
| /** |
| * Compatibility flags. |
| * |
| * @see #addFlags(int) |
| * @see #removeFlags(int) |
| * @see #FLAG_NONE |
| * @see #FLAG_QUALIFIED_SUPERCLASS_NAME |
| * @see #FLAG_ALL |
| */ |
| protected int flags; |
| |
| protected IDataModel dataModel; |
| |
| public CreateJavaEEArtifactTemplateModel(IDataModel dataModel) { |
| this.dataModel = dataModel; |
| this.flags = FLAG_QUALIFIED_SUPERCLASS_NAME; |
| } |
| |
| /** |
| * Adds compatibility flags represented by the given bitmask. |
| * |
| * @param bitmask - |
| * represents the flags to add. |
| * |
| * @see #addFlags(int) |
| * @see #removeFlags(int) |
| * @see #FLAG_NONE |
| * @see #FLAG_QUALIFIED_SUPERCLASS_NAME |
| * @see #FLAG_ALL |
| */ |
| public void addFlags(int bitmask) { |
| flags = flags | bitmask; |
| } |
| |
| /** |
| * Removes compatibility flags represented by the given bitmask. |
| * |
| * @param bitmask - |
| * represents the flags to remove. |
| * |
| * @see #addFlags(int) |
| * @see #removeFlags(int) |
| * @see #FLAG_NONE |
| * @see #FLAG_QUALIFIED_SUPERCLASS_NAME |
| * @see #FLAG_ALL |
| */ |
| public void removeFlags(int bitmask) { |
| flags = flags & ~bitmask; |
| } |
| |
| /** |
| * Check if compatibility flags, represented by the given bitmask, are set. |
| * |
| * @param bitmask - |
| * represents the flags to check. |
| * |
| * @return <code>true</code> - if all of the given flags are set, |
| * <code>false</code> - if any of the given flags is not set. |
| * |
| * @see #addFlags(int) |
| * @see #removeFlags(int) |
| * @see #FLAG_NONE |
| * @see #FLAG_QUALIFIED_SUPERCLASS_NAME |
| * @see #FLAG_ALL |
| */ |
| public boolean areFlagsSet(int bitmask) { |
| return (flags & bitmask) != 0; |
| } |
| |
| public Collection<String> getImports() { |
| Collection<String> collection = new ImportsCollection(this); |
| |
| String className = getClassName(); |
| String superclassName = getQualifiedSuperclassName(); |
| |
| if (superclassName != null && superclassName.length() > 0 && |
| !areFlagsSet(FLAG_QUALIFIED_SUPERCLASS_NAME) && |
| !equalSimpleNames(className, superclassName)) { |
| collection.add(superclassName); |
| } |
| |
| List<String> interfaces = getQualifiedInterfaces(); |
| if (interfaces != null) { |
| for (String iface : interfaces) { |
| if (!equalSimpleNames(getClassName(), iface)) { |
| collection.add(iface); |
| } |
| } |
| } |
| |
| List<Constructor> constructors = getConstructors(); |
| for (Constructor constructor : constructors) { |
| List<String> types = constructor.getNonPrimitiveParameterTypes(); |
| for (String type : types) { |
| collection.add(type); |
| } |
| } |
| |
| Collection<Method> methods = getUnimplementedMethods(); |
| for (Method method : methods) { |
| collection.addAll(method.getParameterImports()); |
| collection.addAll(method.getReturnTypeImports()); |
| } |
| |
| return collection; |
| } |
| |
| public String getClassName() { |
| return getProperty(CLASS_NAME).trim(); |
| } |
| |
| public String getJavaPackageName() { |
| return getProperty(JAVA_PACKAGE).trim(); |
| } |
| |
| public String getQualifiedJavaClassName() { |
| return getJavaPackageName() + "." + getClassName(); //$NON-NLS-1$ |
| } |
| |
| public String getSuperclassName() { |
| String qualified = getQualifiedSuperclassName(); |
| if (areFlagsSet(FLAG_QUALIFIED_SUPERCLASS_NAME) || equalSimpleNames(getClassName(), qualified)) { |
| return qualified; |
| } else { |
| return Signature.getSimpleName(qualified); |
| } |
| } |
| |
| public String getQualifiedSuperclassName() { |
| return getProperty(SUPERCLASS).trim(); |
| } |
| |
| public List<String> getInterfaces() { |
| List<String> qualifiedInterfaces = getQualifiedInterfaces(); |
| List<String> interfaces = new ArrayList<String>(qualifiedInterfaces.size()); |
| |
| for (String qualified : qualifiedInterfaces) { |
| if (equalSimpleNames(getClassName(), qualified)) { |
| interfaces.add(qualified); |
| } else { |
| interfaces.add(Signature.getSimpleName(qualified)); |
| } |
| } |
| |
| return interfaces; |
| } |
| |
| public List<String> getQualifiedInterfaces() { |
| List<String> interfaces = (List<String>) dataModel.getProperty(INTERFACES); |
| return (interfaces == null) ? new ArrayList<String>() : interfaces; |
| } |
| |
| public boolean isPublic() { |
| return dataModel.getBooleanProperty(MODIFIER_PUBLIC); |
| } |
| |
| public boolean isFinal() { |
| return dataModel.getBooleanProperty(MODIFIER_FINAL); |
| } |
| |
| public boolean isAbstract() { |
| return dataModel.getBooleanProperty(MODIFIER_ABSTRACT); |
| } |
| |
| public boolean shouldGenSuperclassConstructors() { |
| return dataModel.getBooleanProperty(CONSTRUCTOR); |
| } |
| |
| public boolean shouldImplementAbstractMethods(){ |
| return dataModel.getBooleanProperty(ABSTRACT_METHODS); |
| } |
| |
| public boolean hasEmptySuperclassConstructor() { |
| List<Constructor> constructors = getConstructors(); |
| for (Constructor constructor : constructors) { |
| if (constructor.isParameterless()) |
| return true; |
| } |
| |
| return false; |
| } |
| |
| public List<Constructor> getConstructors() { |
| List<Constructor> constrs = new ArrayList<Constructor>(); |
| |
| String superclass = dataModel.getStringProperty(SUPERCLASS); |
| if (superclass != null && superclass.length() > 0) { |
| IProject p = (IProject) dataModel.getProperty(PROJECT); |
| IJavaProject javaProject = JavaCore.create(p); |
| if (javaProject != null) { |
| try { |
| IType type = javaProject.findType(superclass); |
| if (type != null) { |
| if (type.isBinary()) { |
| IMethod[] methods = type.getMethods(); |
| for (IMethod method : methods) { |
| if (method.isConstructor()) |
| constrs.add(new BinaryConstructor(method)); |
| } |
| } else { |
| ICompilationUnit compilationUnit = type.getCompilationUnit(); |
| TypeDeclaration declarationFromType = getTypeDeclarationFromType(superclass, compilationUnit); |
| if (declarationFromType != null) { |
| MethodDeclaration[] methods = declarationFromType.getMethods(); |
| for (MethodDeclaration method : methods) { |
| if (method.isConstructor()) |
| constrs.add(new SourceConstructor(method)); |
| } |
| } |
| } |
| } |
| } catch (JavaModelException e) { |
| J2EEPlugin.logError(e); |
| } |
| } |
| } |
| |
| return constrs; |
| } |
| |
| public Collection<Method> getUnimplementedMethods() { |
| Collection<Method> unimplementedMethods = new HashSet<Method>(); |
| |
| if (shouldImplementAbstractMethods()) { |
| IJavaProject javaProject = getJavaProject(); |
| List<String> interfaces = getQualifiedInterfaces(); |
| for (String iface : interfaces) { |
| try { |
| IType type = javaProject.findType(iface); |
| if (type != null) |
| getUnimplementedMethod0(type, unimplementedMethods); |
| } catch (JavaModelException e) { |
| J2EEPlugin.logError(e); |
| } |
| } |
| } |
| |
| return unimplementedMethods; |
| } |
| |
| private void getUnimplementedMethod0(IType type, Collection<Method> unimplementedMethods) throws JavaModelException { |
| IJavaProject javaProject = getJavaProject(); |
| if (type.isBinary()) { |
| IMethod[] methods = type.getMethods(); |
| for (IMethod method : methods) { |
| unimplementedMethods.add(new BinaryMethod(method)); |
| } |
| |
| // process super interfaces |
| String[] superInterfaces = type.getSuperInterfaceNames(); |
| for (String superInterface : superInterfaces) { |
| IType superInterfaceType = javaProject.findType(superInterface); |
| if (superInterfaceType != null) |
| getUnimplementedMethod0(superInterfaceType, unimplementedMethods); |
| } |
| } else { |
| ICompilationUnit compilationUnit = type.getCompilationUnit(); |
| TypeDeclaration declarationFromType = getTypeDeclarationFromType(type.getFullyQualifiedName(), compilationUnit); |
| if (declarationFromType != null) { |
| MethodDeclaration[] methods = declarationFromType.getMethods(); |
| for (MethodDeclaration method : methods) { |
| unimplementedMethods.add(new SourceMethod(method)); |
| } |
| } |
| |
| // process super interfaces |
| List<Type> superInterfaces = declarationFromType.superInterfaceTypes(); |
| for (Type superInterface : superInterfaces) { |
| ITypeBinding binding = superInterface.resolveBinding(); |
| IType superInterfaceType = javaProject.findType(binding.getQualifiedName()); |
| if (superInterfaceType != null) |
| getUnimplementedMethod0(superInterfaceType, unimplementedMethods); |
| } |
| } |
| } |
| |
| protected String getProperty(String propertyName) { |
| return dataModel.getStringProperty(propertyName); |
| } |
| |
| protected boolean equalSimpleNames(String name1, String name2) { |
| String simpleName1 = Signature.getSimpleName(name1); |
| String simpleName2 = Signature.getSimpleName(name2); |
| return simpleName1.equals(simpleName2); |
| } |
| |
| protected IJavaProject getJavaProject() { |
| IProject p = (IProject) dataModel.getProperty(PROJECT); |
| return JavaCore.create(p); |
| } |
| |
| private TypeDeclaration getTypeDeclarationFromType(String typeName, ICompilationUnit unit) { |
| CompilationUnit cu = (CompilationUnit) parse(unit); |
| Iterator iterator = cu.types().iterator(); |
| while (iterator.hasNext()) { |
| Object obj = iterator.next(); |
| if (obj instanceof TypeDeclaration) { |
| TypeDeclaration declaration = (TypeDeclaration) obj; |
| ITypeBinding tb = declaration.resolveBinding(); |
| if (tb != null) { |
| String declarationName = tb.getQualifiedName(); |
| if (typeName.equals(declarationName)) { |
| return declaration; |
| } |
| } |
| } |
| } |
| |
| return null; |
| } |
| |
| private ASTNode parse(ICompilationUnit unit) { |
| ASTParser parser = ASTParser.newParser(AST.JLS3); |
| parser.setKind(ASTParser.K_COMPILATION_UNIT); |
| parser.setSource(unit); |
| parser.setResolveBindings(true); |
| parser.setStatementsRecovery(true); |
| return parser.createAST(null); |
| } |
| |
| } |