Java tutorial
/********************************************************************** * This file is part of "Object Teams Development Tooling"-Software * * Copyright 2004, 2012 Fraunhofer Gesellschaft, Munich, Germany, * for its Fraunhofer Institute for Computer Architecture and Software * Technology (FIRST), Berlin, Germany and Technical University Berlin, * Germany, 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 * * Please visit http://www.eclipse.org/objectteams for updates and contact. * * Contributors: * Fraunhofer FIRST - Initial API and implementation * Technical University Berlin - Initial API and implementation **********************************************************************/ package org.eclipse.objectteams.otdt.core; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.core.ElementChangedEvent; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IMember; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.internal.core.ExternalJavaProject; import org.eclipse.objectteams.otdt.internal.core.BinaryRoleType; import org.eclipse.objectteams.otdt.internal.core.CallinMapping; import org.eclipse.objectteams.otdt.internal.core.CalloutMapping; import org.eclipse.objectteams.otdt.internal.core.CalloutToFieldMapping; import org.eclipse.objectteams.otdt.internal.core.MappingElementInfo; import org.eclipse.objectteams.otdt.internal.core.OTModel; import org.eclipse.objectteams.otdt.internal.core.OTType; import org.eclipse.objectteams.otdt.internal.core.RoleFileType; import org.eclipse.objectteams.otdt.internal.core.RoleType; import org.eclipse.objectteams.otdt.internal.core.util.MethodData; /** * Manager provides connection between JavaModel and OTM. * * @author jwloka * @version $Id: OTModelManager.java 23416 2010-02-03 19:59:31Z stephan $ */ public class OTModelManager { /** * Expose this constant from {@link ExternalJavaProject} for use by other OT plugins. * @since 3.7 */ public static final String EXTERNAL_PROJECT_NAME = ExternalJavaProject.EXTERNAL_PROJECT_NAME; private final static OTModel MAPPING = OTModel.getSharedInstance(); private static OTModelManager singleton; private OTModelReconcileListener reconcileListener; protected OTModelManager() { singleton = this; this.reconcileListener = new OTModelReconcileListener(); JavaCore.addElementChangedListener(this.reconcileListener, ElementChangedEvent.POST_RECONCILE); } public static OTModelManager getSharedInstance() { if (singleton == null) { new OTModelManager(); } return singleton; } public static void dispose() { if (singleton != null) { JavaCore.removeElementChangedListener(singleton.reconcileListener); OTModel.dispose(); } singleton = null; } /** Register a type of which we don't yet have the flags. */ public void addUnopenedType(IType type) { MAPPING.addUnopenedType(type); } /** * Add the propriate Object Teams Model element for a given IType */ public IOTType addType(IType elem, int typeDeclFlags, String baseClassName, String baseClassAnchor, boolean isRoleFile) { IJavaElement parent = elem.getParent(); IOTType result = null; switch (parent.getElementType()) { case IJavaElement.COMPILATION_UNIT: case IJavaElement.CLASS_FILE: if (isRoleFile) { // could also be a teeam, which is handled inside the constructor if (elem.isBinary()) { MAPPING.addOTElement(result = new BinaryRoleType(elem, parent, typeDeclFlags, baseClassName, baseClassAnchor)); } else { MAPPING.addOTElement( result = new RoleFileType(elem, parent, typeDeclFlags, baseClassName, baseClassAnchor)); } } else if (TypeHelper.isTeam(typeDeclFlags)) { MAPPING.addOTElement(result = new OTType(IOTJavaElement.TEAM, elem, null, typeDeclFlags)); } break; case IJavaElement.TYPE: IType encType = (IType) parent; IOTType otmParent = MAPPING.getOTElement(encType); result = maybeAddRoleType(elem, otmParent, typeDeclFlags, baseClassName, baseClassAnchor); break; //do nothing if anonymous type case IJavaElement.METHOD: break; case IJavaElement.INITIALIZER: break; case IJavaElement.FIELD: break; //TODO (jwl) Wether anonymous types are roles or not will be discoverable with // a future implementation (probably with the help of a newer version of the compiler) // case IJavaElement.METHOD: // IMethod encMethod = (IMethod)parent; // otmParent = MAPPING.getOTElement(encMethod.getDeclaringType()); // // addRoleType(elem, otmParent, typeDeclFlags, baseClassName); // break; // case IJavaElement.INITIALIZER: // IInitializer encInitializer = (IInitializer)parent; // otmParent = MAPPING.getOTElement(encInitializer.getDeclaringType()); // // addRoleType(elem, otmParent, typeDeclFlags, baseClassName); // break; // case IJavaElement.FIELD: // IField encField = (IField)parent; // otmParent = MAPPING.getOTElement(encField.getDeclaringType()); // // addRoleType(elem, otmParent, typeDeclFlags, baseClassName); // break; default: new Throwable("Warning: unexpected parent for OT element: " + parent).printStackTrace(); //$NON-NLS-1$ break; } return result; } private IOTType maybeAddRoleType(IType elem, IOTType otmParent, int typeDeclFlags, String baseClassName, String baseClassAnchor) { IOTType result = null; if ((otmParent != null) && (TypeHelper.isTeam(otmParent.getFlags()) || (TypeHelper.isRole(otmParent.getFlags())))) { MAPPING.addOTElement( result = new RoleType(elem, otmParent, typeDeclFlags, baseClassName, baseClassAnchor)); } return result; } /** * @noreference This method is not intended to be referenced by clients. * @nooverride This method is not intended to be re-implemented or extended by clients. */ public ICallinMapping addCallinBinding(IType role, MappingElementInfo info) { IOTType otmRole = MAPPING.getOTElement(role); if ((otmRole != null) && (otmRole instanceof IRoleType)) { //{OTModelUpdate IMethodSpec corrRoleMethData = info.getRoleMethod(); IMethod correspondingRoleMethod = role.getMethod(corrRoleMethData.getSelector(), corrRoleMethData.getArgumentTypes()); //haebor} return new CallinMapping(info.getDeclarationSourceStart(), info.getSourceStart(), info.getSourceEnd(), info.getDeclarationSourceEnd(), (IRoleType) otmRole, //{OTModelUpdate //orig: (IMethod) otmRole.getParent(), correspondingRoleMethod, //haebor} info.getCallinName(), info.getCallinKind(), info.getRoleMethod(), info.getBaseMethods(), info.hasSignature()); } return null; } /** * @noreference This method is not intended to be referenced by clients. * @nooverride This method is not intended to be re-implemented or extended by clients. */ public ICalloutMapping addCalloutBinding(IType role, MappingElementInfo info) { IOTType otmRole = MAPPING.getOTElement(role); if ((otmRole != null) && (otmRole instanceof IRoleType)) { //{OTModelUpdate IMethodSpec corrRoleMethData = info.getRoleMethod(); IMethod correspondingRoleMethod = role.getMethod(corrRoleMethData.getSelector(), corrRoleMethData.getArgumentTypes()); //haebor} MethodData[] baseMethods = info.getBaseMethods(); return new CalloutMapping(info.getDeclarationSourceStart(), info.getSourceStart(), info.getSourceEnd(), info.getDeclarationSourceEnd(), role, correspondingRoleMethod, info.getRoleMethod(), baseMethods == null ? null : baseMethods[0], info.hasSignature(), info.isOverride(), info.getDeclaredModifiers(), true/*addAsChild*/); } return null; } /** * @noreference This method is not intended to be referenced by clients. * @nooverride This method is not intended to be re-implemented or extended by clients. */ public ICalloutToFieldMapping addCalloutToFieldBinding(IType role, MappingElementInfo info) { IOTType otmRole = MAPPING.getOTElement(role); if ((otmRole != null) && (otmRole instanceof IRoleType)) { IMethodSpec corrRoleMethData = info.getRoleMethod(); IMethod correspondingRoleMethod = role.getMethod(corrRoleMethData.getSelector(), corrRoleMethData.getArgumentTypes()); return new CalloutToFieldMapping(info.getDeclarationSourceStart(), info.getSourceStart(), info.getSourceEnd(), info.getDeclarationSourceEnd(), role, correspondingRoleMethod, info.getRoleMethod(), info.getBaseField(), info.hasSignature(), info.isOverride(), true/*addAsChild*/); } return null; } public void addOTElement(IOTType otType) { MAPPING.addOTElement(otType); } /** * Returns associated OTM element for a given type if there is one. * * @return corresponding OTM element or null if no such element exists */ public static IOTType getOTElement(@Nullable IType type) { if (type != null) { type.exists(); // ensure opened return MAPPING.getOTElement(type); } return null; } public static boolean hasOTElementFor(@Nullable IType type) { if (type != null) { type.exists(); // ensure opened return MAPPING.hasOTElementFor(type); } return false; } public static void removeOTElement(IType type) { removeOTElement(type, false); } /** * @see OTModel#removeOTElement(IType, boolean) */ public static void removeOTElement(IType type, boolean hasChanged) { MAPPING.removeOTElement(type, hasChanged); } /** * Utility function. * @param type * @return true if an OT-Type is registered for type that is a role */ public static boolean isRole(IType type) { IOTType ottype = getOTElement(type); return ottype != null && ottype.isRole(); } /** * Utility function. * @param type * @return true if an OT-Type is registered for type that is a team */ public static boolean isTeam(IType type) { if (hasOTElementFor(type)) { IOTType ottype = getOTElement(type); return ottype.isTeam(); } return false; } /** * returns true if this member belongs to a role. Takes binary role-interfaceparts into account. * FIXME (carp): this is mostly a workaround for binary role-interfaceparts. When this problem is * fixed conceptually, check and "port" all clients of this method. */ public static boolean belongsToRole(IMember member) { IType enclosing = member.getDeclaringType(); if (enclosing != null) { IOTType otType = getOTElement(enclosing); return otType != null && otType.isRole(); } return false; } }