blob: dfd3983f9a5059930dfc86c90c86606d2c3b7886 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005 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.jdt.jeview.properties;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map.Entry;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.ui.views.properties.IPropertyDescriptor;
import org.eclipse.ui.views.properties.IPropertySource;
import org.eclipse.ui.views.properties.PropertyDescriptor;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IImportDeclaration;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.jeview.JEViewPlugin;
public class JavaElementProperties implements IPropertySource {
private static HashMap<String, Property<?>> fgIdToProperty= new HashMap<String, Property<?>>();
private static LinkedHashMap<Class<?>, List<? extends Property>> fgTypeToProperty= new LinkedHashMap<Class<?>, List<? extends Property>>();
abstract static class Property<E> {
private final String fTypeName;
private final String fName;
private final PropertyDescriptor fDescriptor;
public Property(Class<E> type, String name) {
fTypeName= type.getSimpleName();
fName= name;
fDescriptor= new PropertyDescriptor(getId(), fName);
fDescriptor.setAlwaysIncompatible(true);
fDescriptor.setCategory(type.getSimpleName());
}
public abstract Object compute(E target) throws JavaModelException;
public String getName() {
return fName;
}
public String getTypeName() {
return fTypeName;
}
public String getId() {
return "org.eclipse.jdt.jeview." + fTypeName + "." + fName;
}
public PropertyDescriptor getDescriptor() {
return fDescriptor;
}
}
private abstract static class P1 extends Property<IJavaElement> {
public static final Class<IJavaElement> CLASS= IJavaElement.class;
private P1(String name) {
super(CLASS, name);
}
static List<P1> createAll() {
return Arrays.asList(
new P1("elementName") {
@Override public Object compute(IJavaElement element) {
return element.getElementName();
}
},
new P1("elementType") {
@Override public Object compute(IJavaElement element) {
return getElementTypeString(element.getElementType());
}
},
new P1("exists") {
@Override public Object compute(IJavaElement element) {
return element.exists();
}
},
new P1("isReadOnly") {
@Override public Object compute(IJavaElement element) {
return element.isReadOnly();
}
},
new P1("isStructureKnown") {
@Override public Object compute(IJavaElement element) throws JavaModelException {
return element.isStructureKnown();
}
},
new P1("handleIdentifier") {
@Override public Object compute(IJavaElement element) {
return element.getHandleIdentifier();
}
},
new P1("path") {
@Override public Object compute(IJavaElement element) {
return element.getPath();
}
},
new P1("schedulingRule") {
@Override public Object compute(IJavaElement element) {
return getSchedulingRuleString(element.getSchedulingRule());
}
});
}
}
abstract static class IClassFileProperty extends Property<IClassFile> {
public IClassFileProperty(String name) {
super(IClassFile.class, name);
}
static void createAll() {
addProperties(IClassFile.class, Arrays.asList(
new IClassFileProperty("isClass") {
@Override public Object compute(IClassFile element) throws JavaModelException {
return element.isClass();
}
},
new IClassFileProperty("isInterface") {
@Override public Object compute(IClassFile element) throws JavaModelException {
return element.isInterface();
}
}));
}
}
abstract static class ICompilationUnitProperty extends Property<ICompilationUnit> {
public ICompilationUnitProperty(String name) {
super(ICompilationUnit.class, name);
}
static void createAll() {
addProperties(ICompilationUnit.class, Arrays.asList(
new ICompilationUnitProperty("hasResourceChanged") {
@Override public Object compute(ICompilationUnit element) {
return element.hasResourceChanged();
}
},
new ICompilationUnitProperty("isWorkingCopy") {
@Override public Object compute(ICompilationUnit element) {
return element.isWorkingCopy();
}
}));
}
}
abstract static class IImportDeclarationProperty extends Property<IImportDeclaration> {
public IImportDeclarationProperty(String name) {
super(IImportDeclaration.class, name);
}
static void createAll() {
addProperties(IImportDeclaration.class, Arrays.asList(
new IImportDeclarationProperty("flags") {
@Override public Object compute(IImportDeclaration element) throws JavaModelException {
return getFlagsString(element.getFlags());
}
},
new IImportDeclarationProperty("isOnDemand") {
@Override public Object compute(IImportDeclaration element) {
return element.isOnDemand();
}
}));
}
}
abstract static class IJavaProjectProperty extends Property<IJavaProject> {
public IJavaProjectProperty(String name) {
super(IJavaProject.class, name);
}
static void createAll() {
addProperties(IJavaProject.class, Arrays.asList(
new IJavaProjectProperty("hasBuildState") {
@Override public Object compute(IJavaProject element) {
return element.hasBuildState();
}
},
new IJavaProjectProperty("getOutputLocation") {
@Override public Object compute(IJavaProject element) throws JavaModelException {
return element.getOutputLocation();
}
},
new IJavaProjectProperty("readOutputLocation") {
@Override public Object compute(IJavaProject element) {
return element.readOutputLocation();
}
}));
}
}
static {
addProperties(P1.CLASS, P1.createAll());
IClassFileProperty.createAll();
ICompilationUnitProperty.createAll();
IImportDeclarationProperty.createAll();
IJavaProjectProperty.createAll();
/*
new Property\((\w+)\.class, "(\w+)"\) \{(\s+)@Override public Object compute\(IJavaElement element\)
new $1Property\("$2"\) \{$3@Override public Object compute\($1 element\)
*/
// addProperty(new Property(ILocalVariable.class, "nameRange") {
// @Override public Object compute(IJavaElement element) {
// return getNameRangeString(((ILocalVariable) element).getNameRange());
// }
// });
// addProperty(new Property(ILocalVariable.class, "typeSignature") {
// @Override public Object compute(IJavaElement element) {
// return ((ILocalVariable) element).getTypeSignature();
// }
// });
//
// addProperty(new Property(IMember.class, "nameRange") {
// @Override public Object compute(IJavaElement element) throws JavaModelException {
// return getNameRangeString(((IMember) element).getNameRange());
// }
// });
// addProperty(new Property(IMember.class, "flags") {
// @Override public Object compute(IJavaElement element) throws JavaModelException {
// return getFlagsString(((IMember) element).getFlags());
// }
// });
// addProperty(new Property(IMember.class, "isBinary") {
// @Override public Object compute(IJavaElement element) {
// return ((IMember) element).isBinary();
// }
// });
//
// addProperty(new Property(IField.class, "isResolved") {
// @Override public Object compute(IJavaElement element) {
// return ((IField) element).isResolved();
// }
// });
// addProperty(new Property(IField.class, "key") {
// @Override public Object compute(IJavaElement element) {
// return ((IField) element).getKey();
// }
// });
// addProperty(new Property(IField.class, "typeSignature") {
// @Override public Object compute(IJavaElement element) throws JavaModelException {
// return ((IField) element).getTypeSignature();
// }
// });
// addProperty(new Property(IField.class, "constant") {
// @Override public Object compute(IJavaElement element) throws JavaModelException {
// return ((IField) element).getConstant();
// }
// });
// addProperty(new Property(IField.class, "isEnumConstant") {
// @Override public Object compute(IJavaElement element) throws JavaModelException {
// return ((IField) element).isEnumConstant();
// }
// });
//
// addProperty(new Property(IMethod.class, "isResolved") {
// @Override public Object compute(IJavaElement element) {
// return ((IMethod) element).isResolved();
// }
// });
// addProperty(new Property(IMethod.class, "key") {
// @Override public Object compute(IJavaElement element) {
// return ((IMethod) element).getKey();
// }
// });
// addProperty(new Property(IMethod.class, "numberOfParameters") {
// @Override public Object compute(IJavaElement element) {
// return ((IMethod) element).getNumberOfParameters();
// }
// });
// addProperty(new Property(IMethod.class, "signature") {
// @Override public Object compute(IJavaElement element) throws JavaModelException {
// return ((IMethod) element).getSignature();
// }
// });
// addProperty(new Property(IMethod.class, "returnType") {
// @Override public Object compute(IJavaElement element) throws JavaModelException {
// return ((IMethod) element).getReturnType();
// }
// });
// addProperty(new Property(IMethod.class, "isConstructor") {
// @Override public Object compute(IJavaElement element) throws JavaModelException {
// return ((IMethod) element).isConstructor();
// }
// });
// addProperty(new Property(IMethod.class, "isMainMethod") {
// @Override public Object compute(IJavaElement element) throws JavaModelException {
// return ((IMethod) element).isMainMethod();
// }
// });
//
// addProperty(new Property(IType.class, "isResolved") {
// @Override public Object compute(IJavaElement element) {
// return ((IType) element).isResolved();
// }
// });
// addProperty(new Property(IType.class, "key") {
// @Override public Object compute(IJavaElement element) {
// return ((IType) element).getKey();
// }
// });
// addProperty(new Property(IType.class, "fullyQualifiedName") {
// @Override public Object compute(IJavaElement element) {
// return ((IType) element).getFullyQualifiedName();
// }
// });
// addProperty(new Property(IType.class, "fullyQualifiedName('*')") {
// @Override public Object compute(IJavaElement element) {
// return ((IType) element).getFullyQualifiedName('*');
// }
// });
// addProperty(new Property(IType.class, "fullyQualifiedParameterizedName") {
// @Override public Object compute(IJavaElement element) throws JavaModelException {
// return ((IType) element).getFullyQualifiedParameterizedName();
// }
// });
// addProperty(new Property(IType.class, "typeQualifiedName") {
// @Override public Object compute(IJavaElement element) {
// return ((IType) element).getTypeQualifiedName();
// }
// });
// addProperty(new Property(IType.class, "typeQualifiedName('*')") {
// @Override public Object compute(IJavaElement element) {
// return ((IType) element).getTypeQualifiedName('*');
// }
// });
// addProperty(new Property(IType.class, "isAnnotation") {
// @Override public Object compute(IJavaElement element) throws JavaModelException {
// return ((IType) element).isAnnotation();
// }
// });
// addProperty(new Property(IType.class, "isClass") {
// @Override public Object compute(IJavaElement element) throws JavaModelException {
// return ((IType) element).isClass();
// }
// });
// addProperty(new Property(IType.class, "isEnum") {
// @Override public Object compute(IJavaElement element) throws JavaModelException {
// return ((IType) element).isEnum();
// }
// });
// addProperty(new Property(IType.class, "isInterface") {
// @Override public Object compute(IJavaElement element) throws JavaModelException {
// return ((IType) element).isInterface();
// }
// });
// addProperty(new Property(IType.class, "isAnonymous") {
// @Override public Object compute(IJavaElement element) throws JavaModelException {
// return ((IType) element).isAnonymous();
// }
// });
// addProperty(new Property(IType.class, "isLocal") {
// @Override public Object compute(IJavaElement element) throws JavaModelException {
// return ((IType) element).isLocal();
// }
// });
// addProperty(new Property(IType.class, "isMember") {
// @Override public Object compute(IJavaElement element) throws JavaModelException {
// return ((IType) element).isMember();
// }
// });
//
// addProperty(new Property(IPackageFragment.class, "containsJavaResources") {
// @Override public Object compute(IJavaElement element) throws JavaModelException {
// return ((IPackageFragment) element).containsJavaResources();
// }
// });
// addProperty(new Property(IPackageFragment.class, "kind") {
// @Override public Object compute(IJavaElement element) throws JavaModelException {
// return getPFRKindString(((IPackageFragment) element).getKind());
// }
// });
// addProperty(new Property(IPackageFragment.class, "hasSubpackages") {
// @Override public Object compute(IJavaElement element) throws JavaModelException {
// return ((IPackageFragment) element).hasSubpackages();
// }
// });
// addProperty(new Property(IPackageFragment.class, "isDefaultPackage") {
// @Override public Object compute(IJavaElement element) {
// return ((IPackageFragment) element).isDefaultPackage();
// }
// });
//
// addProperty(new Property(IPackageFragmentRoot.class, "kind") {
// @Override public Object compute(IJavaElement element) throws JavaModelException {
// return getPFRKindString(((IPackageFragmentRoot) element).getKind());
// }
// });
// addProperty(new Property(IPackageFragmentRoot.class, "sourceAttachmentPath") {
// @Override public Object compute(IJavaElement element) throws JavaModelException {
// return ((IPackageFragmentRoot) element).getSourceAttachmentPath();
// }
// });
// addProperty(new Property(IPackageFragmentRoot.class, "sourceAttachmentRootPath") {
// @Override public Object compute(IJavaElement element) throws JavaModelException {
// return ((IPackageFragmentRoot) element).getSourceAttachmentRootPath();
// }
// });
// addProperty(new Property(IPackageFragmentRoot.class, "isArchive") {
// @Override public Object compute(IJavaElement element) {
// return ((IPackageFragmentRoot) element).isArchive();
// }
// });
// addProperty(new Property(IPackageFragmentRoot.class, "isExternal") {
// @Override public Object compute(IJavaElement element) {
// return ((IPackageFragmentRoot) element).isExternal();
// }
// });
//
// addProperty(new Property(ITypeParameter.class, "nameRange") {
// @Override public Object compute(IJavaElement element) throws JavaModelException {
// return getNameRangeString(((ITypeParameter) element).getNameRange());
// }
// });
//
//
// addProperty(new Property(IParent.class, "hasChildren") {
// @Override public Object compute(IJavaElement element) throws JavaModelException {
// return ((IParent) element).hasChildren();
// }
// });
//
// addProperty(new Property(ISourceReference.class, "sourceRange") {
// @Override public Object compute(IJavaElement element) throws JavaModelException {
// return ((ISourceReference) element).getSourceRange();
// }
// });
//
// addProperty(new Property(IOpenable.class, "hasUnsavedChanges") {
// @Override public Object compute(IJavaElement element) throws JavaModelException {
// return ((IOpenable) element).hasUnsavedChanges();
// }
// });
// addProperty(new Property(IOpenable.class, "isConsistent") {
// @Override public Object compute(IJavaElement element) throws JavaModelException {
// return ((IOpenable) element).isConsistent();
// }
// });
// addProperty(new Property(IOpenable.class, "isOpen") {
// @Override public Object compute(IJavaElement element) {
// return ((IOpenable) element).isOpen();
// }
// });
}
static <T> void addProperties(Class<T> type, List<? extends Property<T>> properties) {
for (Property<T> property : properties) {
fgIdToProperty.put(property.getId(), property);
}
fgTypeToProperty.put(type, properties);
}
protected IJavaElement fJavaElement;
public JavaElementProperties(IJavaElement javaElement) {
fJavaElement= javaElement;
}
public IPropertyDescriptor[] getPropertyDescriptors() {
List<IPropertyDescriptor> result= new ArrayList<IPropertyDescriptor>();
for (Entry<Class<?>, List<? extends Property>> entry : fgTypeToProperty.entrySet()) {
if (entry.getKey().isAssignableFrom(fJavaElement.getClass())) {
for (Property property : entry.getValue()) {
result.add(property.getDescriptor());
}
}
}
return result.toArray(new IPropertyDescriptor[result.size()]);
}
public Object getPropertyValue(Object id) {
Property property= fgIdToProperty.get(id);
if (property == null) {
return null;
} else {
try {
return property.compute(fJavaElement);
} catch (JavaModelException e) {
if (e.isDoesNotExist()) {
return "JavaModelException: " + e.getLocalizedMessage();
} else {
JEViewPlugin.log("error calculating property '" + property.getTypeName() + '#' + property.getName() + '\'', e);
return "Error: " + e.getLocalizedMessage();
}
}
}
}
static String getElementTypeString(int elementType) {
String name;
switch (elementType) {
case IJavaElement.JAVA_MODEL :
name= "IJavaModel";
break;
case IJavaElement.JAVA_PROJECT :
name= "IJavaProject";
break;
case IJavaElement.PACKAGE_FRAGMENT_ROOT :
name= "IPackageFragmentRoot";
break;
case IJavaElement.PACKAGE_FRAGMENT :
name= "IPackageFragment";
break;
case IJavaElement.COMPILATION_UNIT :
name= "ICompilationUnit";
break;
case IJavaElement.CLASS_FILE :
name= "IClassFile";
break;
case IJavaElement.TYPE :
name= "IType";
break;
case IJavaElement.FIELD :
name= "IField";
break;
case IJavaElement.METHOD :
name= "IMethod";
break;
case IJavaElement.INITIALIZER :
name= "IInitializer";
break;
case IJavaElement.PACKAGE_DECLARATION :
name= "IPackageDeclaration";
break;
case IJavaElement.IMPORT_CONTAINER :
name= "IImportContainer";
break;
case IJavaElement.IMPORT_DECLARATION :
name= "IImportDeclaration";
break;
case IJavaElement.LOCAL_VARIABLE :
name= "ILocalVariable";
break;
case IJavaElement.TYPE_PARAMETER :
name= "ITypeParameter";
break;
default :
name= "UNKNOWN";
break;
}
return elementType + " (" + name + ")";
}
static String getNameRangeString(ISourceRange range) {
return range.getOffset() + " + " + range.getLength();
}
static String getFlagsString(int flags) {
StringBuffer sb = new StringBuffer().append("0x").append(Integer.toHexString(flags)).append(" (");
int prologLen= sb.length();
int rest= flags;
rest&= ~ appendFlag(sb, flags, Flags.AccPublic, "public ");
rest&= ~ appendFlag(sb, flags, Flags.AccPrivate, "private ");
rest&= ~ appendFlag(sb, flags, Flags.AccProtected, "protected ");
rest&= ~ appendFlag(sb, flags, Flags.AccStatic, "static ");
rest&= ~ appendFlag(sb, flags, Flags.AccFinal, "final ");
rest&= ~ appendFlag(sb, flags, Flags.AccSynchronized, "synchronized/super ");
rest&= ~ appendFlag(sb, flags, Flags.AccVolatile, "volatile/bridge ");
rest&= ~ appendFlag(sb, flags, Flags.AccTransient, "transient/varargs ");
rest&= ~ appendFlag(sb, flags, Flags.AccNative, "native ");
rest&= ~ appendFlag(sb, flags, Flags.AccInterface, "interface ");
rest&= ~ appendFlag(sb, flags, Flags.AccAbstract, "abstract ");
rest&= ~ appendFlag(sb, flags, Flags.AccStrictfp, "strictfp ");
rest&= ~ appendFlag(sb, flags, Flags.AccSynthetic, "synthetic ");
rest&= ~ appendFlag(sb, flags, Flags.AccAnnotation, "annotation ");
rest&= ~ appendFlag(sb, flags, Flags.AccEnum, "enum ");
rest&= ~ appendFlag(sb, flags, Flags.AccDeprecated, "deprecated ");
if (rest != 0)
sb.append("unknown:0x").append(Integer.toHexString(rest));
int len = sb.length();
if (len != prologLen)
sb.setLength(len - 1);
sb.append(")");
return sb.toString();
}
private static int appendFlag(StringBuffer sb, int flags, int flag, String name) {
if ((flags & flag) != 0) {
sb.append(name);
return flag;
} else {
return 0;
}
}
static String getPFRKindString(int kind) {
StringBuffer sb = new StringBuffer().append("0x").append(Integer.toHexString(kind)).append(" (");
int prologLen= sb.length();
int rest= kind;
rest&= ~ appendFlag(sb, kind, IPackageFragmentRoot.K_BINARY, "binary ");
rest&= ~ appendFlag(sb, kind, IPackageFragmentRoot.K_SOURCE, "source ");
if (rest != 0)
sb.append("unknown:0x").append(Integer.toHexString(rest));
int len = sb.length();
if (len != prologLen)
sb.setLength(len - 1);
sb.append(")");
return sb.toString();
}
static String getSchedulingRuleString(ISchedulingRule schedulingRule) {
if (schedulingRule == null)
return null;
else
return schedulingRule.getClass().getSimpleName() + ": " + schedulingRule.toString();
}
public void setPropertyValue(Object name, Object value) {
// do nothing
}
public Object getEditableValue() {
return this;
}
public boolean isPropertySet(Object property) {
return false;
}
public void resetPropertyValue(Object property) {
// do nothing
}
}