/* This file is part of Green. * * Copyright (C) 2005 The Research Foundation of State University of New York * All Rights Under Copyright Reserved, The Research Foundation of S.U.N.Y. * * Green is free software, licensed under the terms of the Eclipse * Public License, version 1.0. The license is available at * http://www.eclipse.org/legal/epl-v10.html */ package edu.buffalo.cse.green.relationships; import static org.eclipse.jdt.core.dom.ASTNode.FIELD_DECLARATION; import static org.eclipse.jdt.core.dom.ASTNode.METHOD_DECLARATION; import java.util.AbstractList; import java.util.ArrayList; import java.util.List; import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; import org.eclipse.jdt.core.dom.BodyDeclaration; import org.eclipse.jdt.core.dom.EnumDeclaration; import org.eclipse.jdt.core.dom.FieldDeclaration; import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.Type; import org.eclipse.jdt.core.dom.TypeDeclaration; import org.eclipse.jdt.core.dom.VariableDeclarationFragment; import edu.buffalo.cse.green.GreenException; /** * Provides a uniform way to access information contained within an * <code>AbstractTypeDeclaration</code> subclass. This is necessary because the * nodes that represent enum instances are different from the ones that * represent classes and interfaces. * * @author bcmartin */ public abstract class DeclarationInfoProvider { private AbstractTypeDeclaration _node; /** * @return A list of <code>FieldDeclaration</code> nodes belonging to the * given <code>AbstractTypeDeclaration</code>. */ public abstract List<FieldDeclaration> getFields(); /** * @return A list of <code>MethodDeclaration</code> nodes belonging to the * given <code>AbstractTypeDeclaration</code>. */ public abstract List<MethodDeclaration> getMethods(); /** * @return The superclass <code>Type</code> of the given * <code>AbstractTypeDeclaration</code>. */ public abstract Type getSuperclassType(); /** * @return true if the given <code>AbstractTypeDeclaration</code> represents * an interface, false otherwise. */ public abstract boolean isInterface(); /** * Sets the given <code>AbstractTypeDeclaration</code>'s superclass to the * given type. * * @param type - The given <code>Type</code> */ public abstract void setSuperclassType(Type type); /** * @return A list of <code>Type</code> nodes. For a class or enum, returns * a list of implemented interfaces; for an interface, returns a list of * extended interfaces. */ public abstract List<Type> getSuperInterfaceTypes(); protected DeclarationInfoProvider(AbstractTypeDeclaration node) { _node = node; } /** * @param node - The <code>EnumDeclaration</code> to represent * @return An info provider for the given enum */ public static DeclarationInfoProvider getInfoProvider(EnumDeclaration node) { return new EnumDeclarationInfoProvider(node); } /** * @param node - The <code>TypeDeclaration</code> to represent * @return An info provider for the given type */ public static DeclarationInfoProvider getInfoProvider(TypeDeclaration node) { return new TypeDeclarationInfoProvider(node); } /** * @param fields - A list of <code>FieldDeclaration</code> to get the names * of * @return The names of the given fields */ public static List<String> getFieldNames(List<FieldDeclaration> fields) { List<String> fieldNames = new ArrayList<String>(); for (FieldDeclaration field : fields) { fieldNames.addAll(getFieldNamesFromFragments(field)); } return fieldNames; } /** * @param field - The given <code>FieldDeclaration</code> * @return The list of names of fields in the given declaration */ private static List<String> getFieldNamesFromFragments( FieldDeclaration field) { List<String> fields = new ArrayList<String>(); List<VariableDeclarationFragment> fragments = (AbstractList<VariableDeclarationFragment>) field.fragments(); for (VariableDeclarationFragment fragment : fragments) { String name = fragment.getName().getIdentifier(); if (!name.equals("")) { fields.add(name); break; } } return fields; } /** * @return The node represented by this instance */ public AbstractTypeDeclaration getDeclaration() { return _node; } /** * @return All the body declarations of the represented node */ public List bodyDeclarations() { return _node.bodyDeclarations(); } } /** * An implementation of a <code>DeclarationInfoProvider</code> for * <code>EnumDeclaration</code> nodes. * * @author bcmartin */ class EnumDeclarationInfoProvider extends DeclarationInfoProvider { private EnumDeclaration _node; EnumDeclarationInfoProvider(EnumDeclaration node) { super(node); _node = node; } /** * @see edu.buffalo.cse.green.relationships.DeclarationInfoProvider#getFields() */ public List<FieldDeclaration> getFields() { List<FieldDeclaration> fields = new ArrayList<FieldDeclaration>(); for (BodyDeclaration dec : (AbstractList<BodyDeclaration>) (List) _node.bodyDeclarations()) { if (dec.getNodeType() == FIELD_DECLARATION) { fields.add((FieldDeclaration) dec); } } return fields; } /** * @see edu.buffalo.cse.green.relationships.DeclarationInfoProvider#getMethods() */ public List<MethodDeclaration> getMethods() { List<MethodDeclaration> methods = new ArrayList<MethodDeclaration>(); for (BodyDeclaration dec : (AbstractList<BodyDeclaration>) (List) _node.bodyDeclarations()) { if (dec.getNodeType() == METHOD_DECLARATION) { methods.add((MethodDeclaration) dec); } } return methods; } /** * @see edu.buffalo.cse.green.relationships.DeclarationInfoProvider#getSuperclassType() */ public Type getSuperclassType() { return null; } /** * @see edu.buffalo.cse.green.relationships.DeclarationInfoProvider#getSuperInterfaceTypes() */ public List<Type> getSuperInterfaceTypes() { return (AbstractList<Type>) _node.superInterfaceTypes(); } /** * @see edu.buffalo.cse.green.relationships.DeclarationInfoProvider#isInterface() */ public boolean isInterface() { return false; } /** * @see edu.buffalo.cse.green.relationships.DeclarationInfoProvider#setSuperclassType(org.eclipse.jdt.core.dom.Type) */ public void setSuperclassType(Type type) { GreenException.illegalOperation("Enums do not have a superclass"); } } /** * An implementation of a <code>DeclarationInfoProvider</code> for * <code>TypeDeclaration</code> nodes. * * @author bcmartin */ class TypeDeclarationInfoProvider extends DeclarationInfoProvider { private TypeDeclaration _node; TypeDeclarationInfoProvider(TypeDeclaration node) { super(node); _node = node; } /** * @see edu.buffalo.cse.green.relationships.DeclarationInfoProvider#getFields() */ public List<FieldDeclaration> getFields() { List<FieldDeclaration> fields = new ArrayList<FieldDeclaration>(); for (FieldDeclaration field : _node.getFields()) { fields.add(field); } return fields; } /** * @see edu.buffalo.cse.green.relationships.DeclarationInfoProvider#getMethods() */ public List<MethodDeclaration> getMethods() { List<MethodDeclaration> fields = new ArrayList<MethodDeclaration>(); for (MethodDeclaration field : _node.getMethods()) { fields.add(field); } return fields; } /** * @see edu.buffalo.cse.green.relationships.DeclarationInfoProvider#getSuperclassType() */ public Type getSuperclassType() { return _node.getSuperclassType(); } /** * @see edu.buffalo.cse.green.relationships.DeclarationInfoProvider#getSuperInterfaceTypes() */ public List<Type> getSuperInterfaceTypes() { return (AbstractList<Type>) _node.superInterfaceTypes(); } /** * @see edu.buffalo.cse.green.relationships.DeclarationInfoProvider#isInterface() */ public boolean isInterface() { return _node.isInterface(); } /** * @see edu.buffalo.cse.green.relationships.DeclarationInfoProvider#setSuperclassType(org.eclipse.jdt.core.dom.Type) */ public void setSuperclassType(Type type) { _node.setSuperclassType(type); } }