blob: a5c0248ecb23951f898042b9d22af3c65710971f [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010 BSI Business Systems Integration AG.
* 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:
* BSI Business Systems Integration AG - initial API and implementation
******************************************************************************/
package org.eclipse.scout.sdk.workspace.type;
import java.io.PrintStream;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.scout.commons.CompositeObject;
import org.eclipse.scout.commons.StringUtility;
import org.eclipse.scout.sdk.extensions.runtime.classes.RuntimeClasses;
import org.eclipse.scout.sdk.internal.ScoutSdk;
import org.eclipse.scout.sdk.util.SdkProperties;
import org.eclipse.scout.sdk.util.jdt.JdtUtility;
import org.eclipse.scout.sdk.util.signature.SignatureUtility;
import org.eclipse.scout.sdk.util.type.IMethodFilter;
import org.eclipse.scout.sdk.util.type.ITypeFilter;
import org.eclipse.scout.sdk.util.type.MethodFilters;
import org.eclipse.scout.sdk.util.type.TypeComparators;
import org.eclipse.scout.sdk.util.type.TypeFilters;
import org.eclipse.scout.sdk.util.type.TypeUtility;
import org.eclipse.scout.sdk.util.typecache.ITypeHierarchy;
public class ScoutStructuredType implements IStructuredType {
private static final Pattern PROPERTY_BEAN_REGEX = Pattern.compile("^(get|set|is|add|remove|clear|delete)(.*)$");
private final IType m_type;
private final EnumSet<CATEGORIES> m_enabledCategories;
private EnumSet<CATEGORIES> m_visitedCategories;
private HashMap<CATEGORIES, IJavaElement[]> m_elements;
private ITypeHierarchy m_typeHierarchy;
public ScoutStructuredType(IType type, EnumSet<CATEGORIES> enabledCategories) {
m_type = type;
m_enabledCategories = enabledCategories;
m_visitedCategories = EnumSet.noneOf(CATEGORIES.class);
m_elements = new HashMap<CATEGORIES, IJavaElement[]>();
// initialy put all into unknown categories
m_typeHierarchy = TypeUtility.getLocalTypeHierarchy(type);
List<IJavaElement> fields = new ArrayList<IJavaElement>();
List<IJavaElement> enums = new ArrayList<IJavaElement>();
List<IJavaElement> methods = new ArrayList<IJavaElement>();
List<IJavaElement> types = new ArrayList<IJavaElement>();
try {
for (IJavaElement childElement : type.getChildren()) {
switch (childElement.getElementType()) {
case IJavaElement.FIELD:
fields.add(childElement);
break;
case IJavaElement.METHOD:
methods.add(childElement);
break;
case IJavaElement.TYPE:
if (((IType) childElement).isEnum()) {
enums.add(childElement);
}
else {
types.add(childElement);
}
break;
default:
ScoutSdk.logError("Found not considered java element '" + childElement.getElementName() + "' of source builder for '" + getType().getFullyQualifiedName() + "'.");
break;
}
}
m_elements.put(CATEGORIES.FIELD_UNKNOWN, fields.toArray(new IJavaElement[fields.size()]));
m_elements.put(CATEGORIES.ENUM, enums.toArray(new IJavaElement[enums.size()]));
m_elements.put(CATEGORIES.METHOD_UNCATEGORIZED, methods.toArray(new IJavaElement[methods.size()]));
m_elements.put(CATEGORIES.TYPE_UNCATEGORIZED, types.toArray(new IJavaElement[types.size()]));
}
catch (JavaModelException e) {
ScoutSdk.logError("could not build structured type of '" + type.getFullyQualifiedName() + "'.", e);
}
}
public IType getType() {
return m_type;
}
@Override
public IJavaElement[] getElements(CATEGORIES category) {
cache(category);
IJavaElement[] iJavaElements = m_elements.get(category);
if (iJavaElements == null) {
iJavaElements = new IJavaElement[0];
}
return iJavaElements;
}
@SuppressWarnings("unchecked")
@Override
public <T extends IJavaElement> T[] getElements(CATEGORIES category, Class<T> clazz) {
IJavaElement[] elements = getElements(category);
T[] result = (T[]) Array.newInstance(clazz, elements.length);
for (int i = 0; i < elements.length; i++) {
result[i] = (T) elements[i];
}
return result;
}
@Override
public IJavaElement getSiblingMethodConfigGetConfigured(String methodName) {
IJavaElement[] configProperties = getElements(CATEGORIES.METHOD_CONFIG_PROPERTY);
if (configProperties != null) {
for (IJavaElement reference : configProperties) {
if (reference.getElementName().compareTo(methodName) > 0) {
return reference;
}
}
}
return getSibling(CATEGORIES.METHOD_CONFIG_PROPERTY);
}
@Override
public IJavaElement getSiblingMethodConfigExec(String methodName) {
cache(CATEGORIES.METHOD_CONFIG_EXEC);
IJavaElement[] references = getElements(CATEGORIES.METHOD_CONFIG_EXEC);
if (references != null) {
for (IJavaElement reference : references) {
if (reference.getElementName().compareTo(methodName) > 0) {
return reference;
}
}
}
return getSibling(CATEGORIES.METHOD_CONFIG_EXEC);
}
@Override
public IJavaElement getSiblingMethodFieldGetter(String methodName) {
cache(CATEGORIES.METHOD_INNER_TYPE_GETTER);
IJavaElement[] references = getElements(CATEGORIES.METHOD_INNER_TYPE_GETTER);
if (references != null) {
for (IJavaElement reference : references) {
if (reference.getElementName().compareTo(methodName) > 0) {
return reference;
}
}
}
return getSibling(CATEGORIES.METHOD_INNER_TYPE_GETTER);
}
@Override
public IJavaElement getSiblingMethodStartHandler(String methodName) {
cache(CATEGORIES.METHOD_START_HANDLER);
IJavaElement[] references = getElements(CATEGORIES.METHOD_START_HANDLER);
if (references != null) {
for (IJavaElement reference : references) {
if (reference.getElementName().compareTo(methodName) > 0) {
return reference;
}
}
}
return getSibling(CATEGORIES.METHOD_START_HANDLER);
}
@Override
public IJavaElement getSiblingTypeKeyStroke(String keyStrokeName) {
cache(CATEGORIES.TYPE_KEYSTROKE);
IJavaElement[] types = getElements(CATEGORIES.TYPE_KEYSTROKE);
if (types != null) {
for (IJavaElement fh : types) {
if (fh.getElementName().compareTo(keyStrokeName) > 0) {
return fh;
}
}
}
return getSibling(CATEGORIES.TYPE_KEYSTROKE);
}
@Override
public IJavaElement getSiblingComposerAttribute(String attributeName) {
cache(CATEGORIES.TYPE_COMPOSER_ATTRIBUTE);
IJavaElement[] attributes = getElements(CATEGORIES.TYPE_COMPOSER_ATTRIBUTE);
if (attributes != null) {
for (IJavaElement element : attributes) {
if (element.getElementName().compareTo(attributeName) > 0) {
return element;
}
}
}
return getSibling(CATEGORIES.TYPE_COMPOSER_ATTRIBUTE);
}
@Override
public IJavaElement getSiblingComposerEntity(String entityName) {
cache(CATEGORIES.TYPE_COMPOSER_ENTRY);
IJavaElement[] entities = getElements(CATEGORIES.TYPE_COMPOSER_ENTRY);
if (entities != null) {
for (IJavaElement element : entities) {
if (element.getElementName().compareTo(entityName) > 0) {
return element;
}
}
}
return getSibling(CATEGORIES.TYPE_COMPOSER_ENTRY);
}
@Override
public IJavaElement getSiblingTypeFormHandler(String formHandlerName) {
cache(CATEGORIES.TYPE_FORM_HANDLER);
IJavaElement[] formHandlers = getElements(CATEGORIES.TYPE_FORM_HANDLER);
if (formHandlers != null) {
for (IJavaElement fh : formHandlers) {
if (fh.getElementName().compareTo(formHandlerName) > 0) {
return fh;
}
}
}
return getSibling(CATEGORIES.TYPE_UNCATEGORIZED);
}
@Override
public IJavaElement getSibling(CATEGORIES category) {
boolean search = false;
CATEGORIES[] methodCategories = CATEGORIES.values();
for (int i = 0; i < methodCategories.length; i++) {
cache(methodCategories[i]);
if (search) {
IJavaElement[] elements = m_elements.get(methodCategories[i]);
if (elements != null && elements.length > 0) {
return elements[0];
}
}
if (methodCategories[i].equals(category)) {
search = true;
}
}
return null;
}
protected final void cache(CATEGORIES category) {
if (m_enabledCategories.contains(category) && !m_visitedCategories.contains(category)) {
try {
ArrayList<IJavaElement> unknownMethods = new ArrayList<IJavaElement>(Arrays.asList(m_elements.get(CATEGORIES.METHOD_UNCATEGORIZED)));
ArrayList<IJavaElement> unknownTypes = new ArrayList<IJavaElement>(Arrays.asList(m_elements.get(CATEGORIES.TYPE_UNCATEGORIZED)));
switch (category) {
case FIELD_LOGGER:
case FIELD_STATIC:
case FIELD_MEMBER:
visitFields(new ArrayList<IJavaElement>(Arrays.asList(m_elements.get(CATEGORIES.FIELD_UNKNOWN))));
m_visitedCategories.add(CATEGORIES.FIELD_LOGGER);
m_visitedCategories.add(CATEGORIES.FIELD_STATIC);
m_visitedCategories.add(CATEGORIES.FIELD_MEMBER);
break;
case METHOD_CONSTRUCTOR:
visitMethodConstructors(unknownMethods);
m_visitedCategories.add(CATEGORIES.METHOD_CONSTRUCTOR);
m_elements.put(CATEGORIES.METHOD_UNCATEGORIZED, unknownMethods.toArray(new IJavaElement[unknownMethods.size()]));
break;
case METHOD_CONFIG_PROPERTY:
visitMethodConfigProperty(unknownMethods, m_typeHierarchy);
m_visitedCategories.add(CATEGORIES.METHOD_CONFIG_PROPERTY);
m_elements.put(CATEGORIES.METHOD_UNCATEGORIZED, unknownMethods.toArray(new IJavaElement[unknownMethods.size()]));
break;
case METHOD_CONFIG_EXEC:
visitMethodConfigExec(unknownMethods, m_typeHierarchy);
m_visitedCategories.add(CATEGORIES.METHOD_CONFIG_EXEC);
m_elements.put(CATEGORIES.METHOD_UNCATEGORIZED, unknownMethods.toArray(new IJavaElement[unknownMethods.size()]));
break;
case METHOD_FORM_DATA_BEAN:
m_visitedCategories.add(CATEGORIES.METHOD_FORM_DATA_BEAN);
visitMethodFormDataBean(unknownMethods);
m_elements.put(CATEGORIES.METHOD_UNCATEGORIZED, unknownMethods.toArray(new IJavaElement[unknownMethods.size()]));
break;
case METHOD_OVERRIDDEN:
visitMethodOverridden(unknownMethods, m_typeHierarchy);
m_visitedCategories.add(CATEGORIES.METHOD_OVERRIDDEN);
m_elements.put(CATEGORIES.METHOD_UNCATEGORIZED, unknownMethods.toArray(new IJavaElement[unknownMethods.size()]));
break;
case METHOD_START_HANDLER:
visitMethodStartHandler(unknownMethods);
m_visitedCategories.add(CATEGORIES.METHOD_START_HANDLER);
m_elements.put(CATEGORIES.METHOD_UNCATEGORIZED, unknownMethods.toArray(new IJavaElement[unknownMethods.size()]));
break;
case METHOD_INNER_TYPE_GETTER:
visitMethodInnerTypeGetter(unknownMethods);
m_visitedCategories.add(CATEGORIES.METHOD_INNER_TYPE_GETTER);
m_elements.put(CATEGORIES.METHOD_UNCATEGORIZED, unknownMethods.toArray(new IJavaElement[unknownMethods.size()]));
break;
case METHOD_LOCAL_BEAN:
visitMethodLocalBean(unknownMethods);
m_visitedCategories.add(CATEGORIES.METHOD_LOCAL_BEAN);
m_elements.put(CATEGORIES.METHOD_UNCATEGORIZED, unknownMethods.toArray(new IJavaElement[unknownMethods.size()]));
break;
case TYPE_FORM_FIELD:
visitTypeFormFields(unknownTypes);
m_visitedCategories.add(CATEGORIES.TYPE_FORM_FIELD);
m_elements.put(CATEGORIES.TYPE_UNCATEGORIZED, unknownTypes.toArray(new IJavaElement[unknownTypes.size()]));
break;
case TYPE_COLUMN:
visitTypeColumns(unknownTypes);
m_visitedCategories.add(CATEGORIES.TYPE_COLUMN);
m_elements.put(CATEGORIES.TYPE_UNCATEGORIZED, unknownTypes.toArray(new IJavaElement[unknownTypes.size()]));
break;
case TYPE_CODE:
visitTypeCodes(unknownTypes);
m_visitedCategories.add(CATEGORIES.TYPE_CODE);
m_elements.put(CATEGORIES.TYPE_UNCATEGORIZED, unknownTypes.toArray(new IJavaElement[unknownTypes.size()]));
break;
case TYPE_FORM:
visitTypeForms(unknownTypes);
m_visitedCategories.add(CATEGORIES.TYPE_FORM);
m_elements.put(CATEGORIES.TYPE_UNCATEGORIZED, unknownTypes.toArray(new IJavaElement[unknownTypes.size()]));
break;
case TYPE_TABLE:
visitTypeTables(unknownTypes);
m_visitedCategories.add(CATEGORIES.TYPE_TABLE);
m_elements.put(CATEGORIES.TYPE_UNCATEGORIZED, unknownTypes.toArray(new IJavaElement[unknownTypes.size()]));
break;
case TYPE_ACTIVITY_MAP:
visitTypeActivityMaps(unknownTypes);
m_visitedCategories.add(CATEGORIES.TYPE_ACTIVITY_MAP);
m_elements.put(CATEGORIES.TYPE_UNCATEGORIZED, unknownTypes.toArray(new IJavaElement[unknownTypes.size()]));
break;
case TYPE_TREE:
visitTypeTrees(unknownTypes);
m_visitedCategories.add(CATEGORIES.TYPE_TREE);
m_elements.put(CATEGORIES.TYPE_UNCATEGORIZED, unknownTypes.toArray(new IJavaElement[unknownTypes.size()]));
break;
case TYPE_CALENDAR:
visitTypeCalendar(unknownTypes);
m_visitedCategories.add(CATEGORIES.TYPE_CALENDAR);
m_elements.put(CATEGORIES.TYPE_UNCATEGORIZED, unknownTypes.toArray(new IJavaElement[unknownTypes.size()]));
break;
case TYPE_CALENDAR_ITEM_PROVIDER:
visitTypeCalendarItemProvider(unknownTypes);
m_visitedCategories.add(CATEGORIES.TYPE_CALENDAR_ITEM_PROVIDER);
m_elements.put(CATEGORIES.TYPE_UNCATEGORIZED, unknownTypes.toArray(new IJavaElement[unknownTypes.size()]));
break;
case TYPE_WIZARD:
visitTypeWizards(unknownTypes);
m_visitedCategories.add(CATEGORIES.TYPE_WIZARD);
m_elements.put(CATEGORIES.TYPE_UNCATEGORIZED, unknownTypes.toArray(new IJavaElement[unknownTypes.size()]));
break;
case TYPE_WIZARD_STEP:
visitTypeWizardSteps(unknownTypes);
m_visitedCategories.add(CATEGORIES.TYPE_WIZARD_STEP);
m_elements.put(CATEGORIES.TYPE_UNCATEGORIZED, unknownTypes.toArray(new IJavaElement[unknownTypes.size()]));
break;
case TYPE_MENU:
visitTypeMenus(unknownTypes);
m_visitedCategories.add(CATEGORIES.TYPE_MENU);
m_elements.put(CATEGORIES.TYPE_UNCATEGORIZED, unknownTypes.toArray(new IJavaElement[unknownTypes.size()]));
break;
case TYPE_VIEW_BUTTON:
visitTypeViewbuttons(unknownTypes);
m_visitedCategories.add(CATEGORIES.TYPE_VIEW_BUTTON);
m_elements.put(CATEGORIES.TYPE_UNCATEGORIZED, unknownTypes.toArray(new IJavaElement[unknownTypes.size()]));
break;
case TYPE_TOOL_BUTTON:
visitTypeToolbuttons(unknownTypes);
m_visitedCategories.add(CATEGORIES.TYPE_TOOL_BUTTON);
m_elements.put(CATEGORIES.TYPE_UNCATEGORIZED, unknownTypes.toArray(new IJavaElement[unknownTypes.size()]));
break;
case TYPE_KEYSTROKE:
visitTypeKeystrokes(unknownTypes);
m_visitedCategories.add(CATEGORIES.TYPE_KEYSTROKE);
m_elements.put(CATEGORIES.TYPE_UNCATEGORIZED, unknownTypes.toArray(new IJavaElement[unknownTypes.size()]));
break;
case TYPE_COMPOSER_ATTRIBUTE:
visitTypeComposerAttribute(unknownTypes);
m_visitedCategories.add(CATEGORIES.TYPE_COMPOSER_ATTRIBUTE);
m_elements.put(CATEGORIES.TYPE_UNCATEGORIZED, unknownTypes.toArray(new IJavaElement[unknownTypes.size()]));
break;
case TYPE_COMPOSER_ENTRY:
visitTypeDataModelEntry(unknownTypes);
m_visitedCategories.add(CATEGORIES.TYPE_COMPOSER_ENTRY);
m_elements.put(CATEGORIES.TYPE_UNCATEGORIZED, unknownTypes.toArray(new IJavaElement[unknownTypes.size()]));
break;
case TYPE_FORM_HANDLER:
visitTypeFormHandlers(unknownTypes);
m_visitedCategories.add(CATEGORIES.TYPE_FORM_HANDLER);
m_elements.put(CATEGORIES.TYPE_UNCATEGORIZED, unknownTypes.toArray(new IJavaElement[unknownTypes.size()]));
break;
case FIELD_UNKNOWN:
break;
case METHOD_UNCATEGORIZED:
break;
case TYPE_UNCATEGORIZED:
break;
case ENUM:
break;
}
}
catch (CoreException e) {
ScoutSdk.logError("could build sturucted type '" + m_type.getFullyQualifiedName() + "'.", e);
}
}
}
/**
* can be overwritten. Overwrites must ensure to super call after processing the working set.
*
* @param workingSet
* @throws JavaModelException
*/
protected void visitFields(ArrayList<IJavaElement> workingSet) throws JavaModelException {
ArrayList<IField> loggers = new ArrayList<IField>(2);
ArrayList<IField> statics = new ArrayList<IField>();
ArrayList<IField> members = new ArrayList<IField>();
for (Iterator<IJavaElement> it = workingSet.iterator(); it.hasNext();) {
IField f = (IField) it.next();
// static
if ((f.getFlags() & Flags.AccStatic) != 0) {
String fqn = getFullyQuallifiedTypeName(f.getTypeSignature(), getType());
if (RuntimeClasses.IScoutLogger.equals(fqn)) {
loggers.add(f);
it.remove();
}
else {
statics.add(f);
it.remove();
}
}
else {
members.add(f);
it.remove();
}
}
m_elements.put(CATEGORIES.FIELD_LOGGER, loggers.toArray(new IField[loggers.size()]));
m_elements.put(CATEGORIES.FIELD_STATIC, statics.toArray(new IField[statics.size()]));
m_elements.put(CATEGORIES.FIELD_MEMBER, members.toArray(new IField[members.size()]));
m_elements.put(CATEGORIES.FIELD_UNKNOWN, workingSet.toArray(new IField[workingSet.size()]));
}
private static String getFullyQuallifiedTypeName(String signature, IType jdtType) throws JavaModelException {
if (Signature.getTypeArguments(signature).length > 0) {
signature = Signature.getTypeErasure(signature);
}
if (SignatureUtility.getTypeSignatureKind(signature) == Signature.BASE_TYPE_SIGNATURE) {
return Signature.getSignatureSimpleName(signature);
}
if (signature.length() > 0 && signature.charAt(0) == Signature.C_UNRESOLVED) {
String simpleName = Signature.getSignatureSimpleName(signature);
return TypeUtility.getReferencedTypeFqn(jdtType, simpleName, false);
}
return null;
}
protected void visitMethodConstructors(ArrayList<IJavaElement> workingSet) throws JavaModelException {
TreeMap<CompositeObject, IMethod> constructors = new TreeMap<CompositeObject, IMethod>();
for (Iterator<IJavaElement> it = workingSet.iterator(); it.hasNext();) {
IMethod method = (IMethod) it.next();
if (method.isConstructor()) {
CompositeObject key = createConstructorKey(method.getParameterTypes());
constructors.put(key, method);
it.remove();
}
}
m_elements.put(CATEGORIES.METHOD_CONSTRUCTOR, constructors.values().toArray(new IMethod[constructors.size()]));
}
protected void visitMethodConfigExec(ArrayList<IJavaElement> workingSet, ITypeHierarchy superTypeHierarchy) throws CoreException {
TreeMap<CompositeObject, IMethod> execMethods = new TreeMap<CompositeObject, IMethod>();
IMethodFilter execMethodFilter = MethodFilters.getFilterWithAnnotation(TypeUtility.getType(RuntimeClasses.ConfigOperation));
for (Iterator<IJavaElement> it = workingSet.iterator(); it.hasNext();) {
IMethod method = (IMethod) it.next();
IMethod visitedmethod = method;
while (TypeUtility.exists(visitedmethod)) {
if (execMethodFilter.accept(visitedmethod)) {
CompositeObject key = new CompositeObject(method.getElementName(), method.getParameterNames().length, method);
execMethods.put(key, method);
it.remove();
break;
}
visitedmethod = TypeUtility.getOverwrittenMethod(visitedmethod, superTypeHierarchy.getJdtHierarchy());
}
}
m_elements.put(CATEGORIES.METHOD_CONFIG_EXEC, execMethods.values().toArray(new IMethod[execMethods.size()]));
}
protected void visitMethodConfigProperty(ArrayList<IJavaElement> workingSet, ITypeHierarchy superTypeHierarchy) throws CoreException {
TreeMap<CompositeObject, IMethod> methods = new TreeMap<CompositeObject, IMethod>();
IMethodFilter configPropertyMethodFilter = MethodFilters.getFilterWithAnnotation(TypeUtility.getType(RuntimeClasses.ConfigProperty));
for (Iterator<IJavaElement> it = workingSet.iterator(); it.hasNext();) {
IMethod method = (IMethod) it.next();
IMethod visitedmethod = method;
while (TypeUtility.exists(visitedmethod)) {
if (configPropertyMethodFilter.accept(visitedmethod)) {
CompositeObject key = new CompositeObject(method.getElementName(), method.getParameterNames().length, method);
methods.put(key, method);
it.remove();
break;
}
visitedmethod = TypeUtility.getOverwrittenMethod(visitedmethod, superTypeHierarchy.getJdtHierarchy());
}
}
m_elements.put(CATEGORIES.METHOD_CONFIG_PROPERTY, methods.values().toArray(new IMethod[methods.size()]));
}
protected void visitMethodFormDataBean(ArrayList<IJavaElement> workingSet) throws JavaModelException {
TreeMap<CompositeObject, IMethod> methods = new TreeMap<CompositeObject, IMethod>();
for (Iterator<IJavaElement> it = workingSet.iterator(); it.hasNext();) {
IMethod method = (IMethod) it.next();
if (JdtUtility.hasAnnotation(method, RuntimeClasses.FormData)) {
CompositeObject methodKey = createPropertyMethodKey(method);
if (methodKey != null) {
methods.put(methodKey, method);
it.remove();
}
else {
ScoutSdk.logWarning("could not parse property method '" + method.getElementName() + "'.");
}
}
}
m_elements.put(CATEGORIES.METHOD_FORM_DATA_BEAN, methods.values().toArray(new IMethod[methods.size()]));
}
protected void visitMethodOverridden(ArrayList<IJavaElement> workingSet, ITypeHierarchy superTypeHierarchy) throws JavaModelException {
TreeMap<CompositeObject, IMethod> overriddenMethods = new TreeMap<CompositeObject, IMethod>();
for (Iterator<IJavaElement> it = workingSet.iterator(); it.hasNext();) {
IMethod method = (IMethod) it.next();
if (TypeUtility.getOverwrittenMethod(method, superTypeHierarchy.getJdtHierarchy()) != null) {
CompositeObject key = new CompositeObject(method.getElementName(), method.getParameterNames().length, method);
overriddenMethods.put(key, method);
it.remove();
}
}
m_elements.put(CATEGORIES.METHOD_OVERRIDDEN, overriddenMethods.values().toArray(new IMethod[overriddenMethods.size()]));
}
protected void visitMethodStartHandler(ArrayList<IJavaElement> workingSet) throws JavaModelException {
TreeMap<CompositeObject, IMethod> startHandlerMethods = new TreeMap<CompositeObject, IMethod>();
for (Iterator<IJavaElement> it = workingSet.iterator(); it.hasNext();) {
IMethod method = (IMethod) it.next();
Matcher matcher = Pattern.compile("^start(.*)$").matcher(method.getElementName());
if (matcher.find()) {
String fieldName = matcher.group(1);
if (TypeUtility.findInnerType(getType(), fieldName + SdkProperties.SUFFIX_FORM_HANDLER) != null) {
CompositeObject key = new CompositeObject(method.getElementName(), method.getParameterNames().length, method);
startHandlerMethods.put(key, method);
it.remove();
}
}
}
m_elements.put(CATEGORIES.METHOD_START_HANDLER, startHandlerMethods.values().toArray(new IMethod[startHandlerMethods.size()]));
}
protected void visitMethodInnerTypeGetter(ArrayList<IJavaElement> workingSet) throws JavaModelException {
TreeMap<CompositeObject, IMethod> fieldGetterMethods = new TreeMap<CompositeObject, IMethod>();
for (Iterator<IJavaElement> it = workingSet.iterator(); it.hasNext();) {
IMethod method = (IMethod) it.next();
Matcher matcher = Pattern.compile("^get(.*)$").matcher(method.getElementName());
if (matcher.find()) {
String fieldName = matcher.group(1);
if (TypeUtility.findInnerType(getType(), fieldName) != null) {
CompositeObject key = new CompositeObject(method.getElementName(), method.getParameterNames().length, method);
fieldGetterMethods.put(key, method);
it.remove();
}
}
}
m_elements.put(CATEGORIES.METHOD_INNER_TYPE_GETTER, fieldGetterMethods.values().toArray(new IMethod[fieldGetterMethods.size()]));
}
protected void visitMethodLocalBean(ArrayList<IJavaElement> workingSet) throws JavaModelException {
TreeMap<CompositeObject, IMethod> localPropertyMethods = new TreeMap<CompositeObject, IMethod>();
for (Iterator<IJavaElement> it = workingSet.iterator(); it.hasNext();) {
IMethod method = (IMethod) it.next();
CompositeObject key = createPropertyMethodKey(method);
if (key != null) {
localPropertyMethods.put(key, method);
it.remove();
}
}
m_elements.put(CATEGORIES.METHOD_LOCAL_BEAN, localPropertyMethods.values().toArray(new IMethod[localPropertyMethods.size()]));
}
protected void visitMethodUncategorized(ArrayList<IMethod> workingSet) throws JavaModelException {
TreeMap<CompositeObject, IMethod> methods = new TreeMap<CompositeObject, IMethod>();
for (Iterator<IMethod> it = workingSet.iterator(); it.hasNext();) {
IMethod method = it.next();
CompositeObject key = new CompositeObject(method.getElementName(), method.getParameterNames().length, method);
methods.put(key, method);
it.remove();
}
m_elements.put(CATEGORIES.METHOD_UNCATEGORIZED, methods.values().toArray(new IMethod[methods.size()]));
}
protected void visitTypeFormFields(ArrayList<IJavaElement> workingSet) {
TreeSet<IType> formFields = new TreeSet<IType>(ScoutTypeComparators.getOrderAnnotationComparator());
ITypeFilter filter = TypeFilters.getMultiTypeFilter(TypeFilters.getClassFilter(), TypeFilters.getSubtypeFilter(TypeUtility.getType(RuntimeClasses.IFormField), m_typeHierarchy));
for (Iterator<IJavaElement> it = workingSet.iterator(); it.hasNext();) {
IType candidate = (IType) it.next();
if (filter.accept(candidate)) {
formFields.add(candidate);
it.remove();
}
}
m_elements.put(CATEGORIES.TYPE_FORM_FIELD, formFields.toArray(new IType[formFields.size()]));
}
protected void visitTypeColumns(ArrayList<IJavaElement> workingSet) {
TreeSet<IType> types = new TreeSet<IType>(ScoutTypeComparators.getOrderAnnotationComparator());
ITypeFilter filter = TypeFilters.getMultiTypeFilter(TypeFilters.getClassFilter(), TypeFilters.getSubtypeFilter(TypeUtility.getType(RuntimeClasses.IColumn), m_typeHierarchy));
for (Iterator<IJavaElement> it = workingSet.iterator(); it.hasNext();) {
IType candidate = (IType) it.next();
if (filter.accept(candidate)) {
types.add(candidate);
it.remove();
}
}
m_elements.put(CATEGORIES.TYPE_COLUMN, types.toArray(new IType[types.size()]));
}
protected void visitTypeCodes(ArrayList<IJavaElement> workingSet) {
TreeSet<IType> types = new TreeSet<IType>(ScoutTypeComparators.getOrderAnnotationComparator());
ITypeFilter filter = TypeFilters.getMultiTypeFilter(TypeFilters.getClassFilter(), TypeFilters.getSubtypeFilter(TypeUtility.getType(RuntimeClasses.ICode), m_typeHierarchy));
for (Iterator<IJavaElement> it = workingSet.iterator(); it.hasNext();) {
IType candidate = (IType) it.next();
if (filter.accept(candidate)) {
types.add(candidate);
it.remove();
}
}
m_elements.put(CATEGORIES.TYPE_CODE, types.toArray(new IType[types.size()]));
}
protected void visitTypeForms(ArrayList<IJavaElement> workingSet) {
TreeSet<IType> types = new TreeSet<IType>(ScoutTypeComparators.getOrderAnnotationComparator());
ITypeFilter filter = TypeFilters.getMultiTypeFilter(TypeFilters.getClassFilter(), TypeFilters.getSubtypeFilter(TypeUtility.getType(RuntimeClasses.IForm), m_typeHierarchy));
for (Iterator<IJavaElement> it = workingSet.iterator(); it.hasNext();) {
IType candidate = (IType) it.next();
if (filter.accept(candidate)) {
types.add(candidate);
it.remove();
}
}
m_elements.put(CATEGORIES.TYPE_FORM, types.toArray(new IType[types.size()]));
}
protected void visitTypeTables(ArrayList<IJavaElement> workingSet) {
TreeSet<IType> types = new TreeSet<IType>(ScoutTypeComparators.getOrderAnnotationComparator());
ITypeFilter filter = TypeFilters.getMultiTypeFilter(TypeFilters.getClassFilter(), TypeFilters.getSubtypeFilter(TypeUtility.getType(RuntimeClasses.ITable), m_typeHierarchy));
for (Iterator<IJavaElement> it = workingSet.iterator(); it.hasNext();) {
IType candidate = (IType) it.next();
if (filter.accept(candidate)) {
types.add(candidate);
it.remove();
}
}
m_elements.put(CATEGORIES.TYPE_TABLE, types.toArray(new IType[types.size()]));
}
/**
* @param workingSet
*/
private void visitTypeActivityMaps(ArrayList<IJavaElement> workingSet) {
TreeSet<IType> types = new TreeSet<IType>(TypeComparators.getTypeNameComparator());
ITypeFilter filter = TypeFilters.getMultiTypeFilter(TypeFilters.getClassFilter(), TypeFilters.getSubtypeFilter(TypeUtility.getType(RuntimeClasses.IActivityMap), m_typeHierarchy));
for (Iterator<IJavaElement> it = workingSet.iterator(); it.hasNext();) {
IType candidate = (IType) it.next();
if (filter.accept(candidate)) {
types.add(candidate);
it.remove();
}
}
m_elements.put(CATEGORIES.TYPE_ACTIVITY_MAP, types.toArray(new IType[types.size()]));
}
protected void visitTypeTrees(ArrayList<IJavaElement> workingSet) {
TreeSet<IType> types = new TreeSet<IType>(ScoutTypeComparators.getOrderAnnotationComparator());
ITypeFilter filter = TypeFilters.getMultiTypeFilter(TypeFilters.getClassFilter(), TypeFilters.getSubtypeFilter(TypeUtility.getType(RuntimeClasses.ITree), m_typeHierarchy));
for (Iterator<IJavaElement> it = workingSet.iterator(); it.hasNext();) {
IType candidate = (IType) it.next();
if (filter.accept(candidate)) {
types.add(candidate);
it.remove();
}
}
m_elements.put(CATEGORIES.TYPE_TREE, types.toArray(new IType[types.size()]));
}
protected void visitTypeCalendar(ArrayList<IJavaElement> workingSet) {
TreeSet<IType> types = new TreeSet<IType>(ScoutTypeComparators.getOrderAnnotationComparator());
ITypeFilter filter = TypeFilters.getMultiTypeFilter(TypeFilters.getClassFilter(), TypeFilters.getSubtypeFilter(TypeUtility.getType(RuntimeClasses.ICalendar), m_typeHierarchy));
for (Iterator<IJavaElement> it = workingSet.iterator(); it.hasNext();) {
IType candidate = (IType) it.next();
if (filter.accept(candidate)) {
types.add(candidate);
it.remove();
}
}
m_elements.put(CATEGORIES.TYPE_CALENDAR, types.toArray(new IType[types.size()]));
}
protected void visitTypeCalendarItemProvider(ArrayList<IJavaElement> workingSet) {
TreeSet<IType> types = new TreeSet<IType>(ScoutTypeComparators.getOrderAnnotationComparator());
ITypeFilter filter = TypeFilters.getMultiTypeFilter(TypeFilters.getClassFilter(), TypeFilters.getSubtypeFilter(TypeUtility.getType(RuntimeClasses.ICalendarItemProvider), m_typeHierarchy));
for (Iterator<IJavaElement> it = workingSet.iterator(); it.hasNext();) {
IType candidate = (IType) it.next();
if (filter.accept(candidate)) {
types.add(candidate);
it.remove();
}
}
m_elements.put(CATEGORIES.TYPE_CALENDAR_ITEM_PROVIDER, types.toArray(new IType[types.size()]));
}
protected void visitTypeWizards(ArrayList<IJavaElement> workingSet) {
TreeSet<IType> types = new TreeSet<IType>(ScoutTypeComparators.getOrderAnnotationComparator());
ITypeFilter filter = TypeFilters.getMultiTypeFilter(TypeFilters.getClassFilter(), TypeFilters.getSubtypeFilter(TypeUtility.getType(RuntimeClasses.IWizard), m_typeHierarchy));
for (Iterator<IJavaElement> it = workingSet.iterator(); it.hasNext();) {
IType candidate = (IType) it.next();
if (filter.accept(candidate)) {
types.add(candidate);
it.remove();
}
}
m_elements.put(CATEGORIES.TYPE_WIZARD, types.toArray(new IType[types.size()]));
}
protected void visitTypeWizardSteps(ArrayList<IJavaElement> workingSet) {
TreeSet<IType> types = new TreeSet<IType>(ScoutTypeComparators.getOrderAnnotationComparator());
ITypeFilter filter = TypeFilters.getMultiTypeFilter(TypeFilters.getClassFilter(), TypeFilters.getSubtypeFilter(TypeUtility.getType(RuntimeClasses.IWizardStep), m_typeHierarchy));
for (Iterator<IJavaElement> it = workingSet.iterator(); it.hasNext();) {
IType candidate = (IType) it.next();
if (filter.accept(candidate)) {
types.add(candidate);
it.remove();
}
}
m_elements.put(CATEGORIES.TYPE_WIZARD_STEP, types.toArray(new IType[types.size()]));
}
protected void visitTypeMenus(ArrayList<IJavaElement> workingSet) {
TreeSet<IType> types = new TreeSet<IType>(ScoutTypeComparators.getOrderAnnotationComparator());
ITypeFilter filter = TypeFilters.getMultiTypeFilter(TypeFilters.getClassFilter(), TypeFilters.getSubtypeFilter(TypeUtility.getType(RuntimeClasses.IMenu), m_typeHierarchy));
for (Iterator<IJavaElement> it = workingSet.iterator(); it.hasNext();) {
IType candidate = (IType) it.next();
if (filter.accept(candidate)) {
types.add(candidate);
it.remove();
}
}
m_elements.put(CATEGORIES.TYPE_MENU, types.toArray(new IType[types.size()]));
}
protected void visitTypeViewbuttons(ArrayList<IJavaElement> workingSet) {
TreeSet<IType> types = new TreeSet<IType>(ScoutTypeComparators.getOrderAnnotationComparator());
ITypeFilter filter = TypeFilters.getMultiTypeFilter(TypeFilters.getClassFilter(), TypeFilters.getSubtypeFilter(TypeUtility.getType(RuntimeClasses.IViewButton), m_typeHierarchy));
for (Iterator<IJavaElement> it = workingSet.iterator(); it.hasNext();) {
IType candidate = (IType) it.next();
if (filter.accept(candidate)) {
types.add(candidate);
it.remove();
}
}
m_elements.put(CATEGORIES.TYPE_VIEW_BUTTON, types.toArray(new IType[types.size()]));
}
protected void visitTypeToolbuttons(ArrayList<IJavaElement> workingSet) {
TreeSet<IType> types = new TreeSet<IType>(ScoutTypeComparators.getOrderAnnotationComparator());
ITypeFilter filter = TypeFilters.getMultiTypeFilter(TypeFilters.getClassFilter(), TypeFilters.getSubtypeFilter(TypeUtility.getType(RuntimeClasses.IToolButton), m_typeHierarchy));
for (Iterator<IJavaElement> it = workingSet.iterator(); it.hasNext();) {
IType candidate = (IType) it.next();
if (filter.accept(candidate)) {
types.add(candidate);
it.remove();
}
}
m_elements.put(CATEGORIES.TYPE_TOOL_BUTTON, types.toArray(new IType[types.size()]));
}
protected void visitTypeKeystrokes(ArrayList<IJavaElement> workingSet) {
TreeSet<IType> types = new TreeSet<IType>(TypeComparators.getTypeNameComparator());
ITypeFilter filter = TypeFilters.getMultiTypeFilter(TypeFilters.getClassFilter(), TypeFilters.getSubtypeFilter(TypeUtility.getType(RuntimeClasses.IKeyStroke), m_typeHierarchy));
for (Iterator<IJavaElement> it = workingSet.iterator(); it.hasNext();) {
IType candidate = (IType) it.next();
if (filter.accept(candidate)) {
types.add(candidate);
it.remove();
}
}
m_elements.put(CATEGORIES.TYPE_KEYSTROKE, types.toArray(new IType[types.size()]));
}
protected void visitTypeComposerAttribute(ArrayList<IJavaElement> workingSet) {
TreeSet<IType> types = new TreeSet<IType>(TypeComparators.getTypeNameComparator());
@SuppressWarnings("deprecation")
ITypeFilter filter = TypeFilters.getMultiTypeFilter(TypeFilters.getClassFilter(), TypeFilters.getSubtypeFilter(TypeUtility.getType(RuntimeClasses.IComposerAttribute), m_typeHierarchy));
for (Iterator<IJavaElement> it = workingSet.iterator(); it.hasNext();) {
IType candidate = (IType) it.next();
if (filter.accept(candidate)) {
types.add(candidate);
it.remove();
}
}
m_elements.put(CATEGORIES.TYPE_COMPOSER_ATTRIBUTE, types.toArray(new IType[types.size()]));
}
protected void visitTypeDataModelEntry(ArrayList<IJavaElement> workingSet) {
TreeSet<IType> types = new TreeSet<IType>(TypeComparators.getTypeNameComparator());
ITypeFilter filter = TypeFilters.getMultiTypeFilter(TypeFilters.getClassFilter(), TypeFilters.getSubtypeFilter(TypeUtility.getType(RuntimeClasses.IDataModelEntity), m_typeHierarchy));
for (Iterator<IJavaElement> it = workingSet.iterator(); it.hasNext();) {
IType candidate = (IType) it.next();
if (filter.accept(candidate)) {
types.add(candidate);
it.remove();
}
}
m_elements.put(CATEGORIES.TYPE_COMPOSER_ENTRY, types.toArray(new IType[types.size()]));
}
protected void visitTypeFormHandlers(ArrayList<IJavaElement> workingSet) {
TreeSet<IType> types = new TreeSet<IType>(TypeComparators.getTypeNameComparator());
ITypeFilter filter = TypeFilters.getMultiTypeFilter(TypeFilters.getClassFilter(), TypeFilters.getSubtypeFilter(TypeUtility.getType(RuntimeClasses.IFormHandler), m_typeHierarchy));
for (Iterator<IJavaElement> it = workingSet.iterator(); it.hasNext();) {
IType candidate = (IType) it.next();
if (filter.accept(candidate)) {
types.add(candidate);
it.remove();
}
}
m_elements.put(CATEGORIES.TYPE_FORM_HANDLER, types.toArray(new IType[types.size()]));
}
private static CompositeObject createPropertyMethodKey(IMethod method) {
if (TypeUtility.exists(method)) {
Matcher matcher = PROPERTY_BEAN_REGEX.matcher(method.getElementName());
if (matcher.find()) {
int getSetOrder = 20;
if (StringUtility.equalsIgnoreCase("get", matcher.group(1))) {
getSetOrder = 1;
}
else if (StringUtility.equalsIgnoreCase("is", matcher.group(1))) {
getSetOrder = 2;
}
else if (StringUtility.equalsIgnoreCase("set", matcher.group(1))) {
getSetOrder = 3;
}
else if (StringUtility.equalsIgnoreCase("add", matcher.group(1))) {
getSetOrder = 4;
}
else if (StringUtility.equalsIgnoreCase("remove", matcher.group(1))) {
getSetOrder = 5;
}
else if (StringUtility.equalsIgnoreCase("clear", matcher.group(1))) {
getSetOrder = 6;
}
else if (StringUtility.equalsIgnoreCase("delete", matcher.group(1))) {
getSetOrder = 7;
}
String propName = matcher.group(2);
CompositeObject key = new CompositeObject(propName, getSetOrder, method.getElementName(), method.getParameterTypes().length, method);
return key;
}
}
return null;
}
protected CompositeObject createConstructorKey(String[] parameterSignatures) {
if (parameterSignatures == null) {
parameterSignatures = new String[0];
}
StringBuilder b = new StringBuilder();
for (String sig : parameterSignatures) {
b.append(sig);
}
return new CompositeObject(parameterSignatures.length, b.toString());
}
@Override
public void print(PrintStream printer) {
printer.println("------ Structured type of '" + getType().getFullyQualifiedName() + "' ------------");
for (CATEGORIES c : CATEGORIES.values()) {
printCategory(printer, c);
}
printer.println("---------------------------------------------------------------------------");
}
private void printCategory(PrintStream printer, CATEGORIES category) {
printer.println("category '" + category.name() + "'");
for (IJavaElement e : getElements(category)) {
printer.println(" - " + e.getElementName());
}
}
}