/******************************************************************************* * Copyright (c) 2010 Michal Antkiewicz. * 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: * Michal Antkiewicz - initial API and implementation ******************************************************************************/ package ca.uwaterloo.gsd.fsml.javaMappingInterpreter.mappings; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.emf.ecore.EAnnotation; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.jdt.core.IClassFile; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IMember; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.ITypeRoot; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.Signature; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.IMethodBinding; import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.TypeDeclaration; import org.eclipse.jdt.core.search.SearchMatch; import ca.uwaterloo.gsd.fsml.core.Context; import ca.uwaterloo.gsd.fsml.core.FSMLMappingException; import ca.uwaterloo.gsd.fsml.core.Mapping; import ca.uwaterloo.gsd.fsml.core.Mode; import ca.uwaterloo.gsd.fsml.core.Queries; import ca.uwaterloo.gsd.fsml.ecore.FSMLEcoreUtil; import ca.uwaterloo.gsd.fsml.javaMappingInterpreter.IJavaContextManager; import ca.uwaterloo.gsd.fsml.javaMappingInterpreter.JavaMappingInterpreter; import ca.uwaterloo.gsd.fsml.javaMappingInterpreter.JavaMarkerDescriptor; import ca.uwaterloo.gsd.fsml.javaMappingInterpreter.analysis.ASTUtils; import ca.uwaterloo.gsd.fsml.javaMappingInterpreter.analysis.IAnalysisManagers; import ca.uwaterloo.gsd.fsml.javaMappingInterpreter.analysis.IHierarchicalCallGraphManager; import ca.uwaterloo.gsd.fsml.javaMappingInterpreter.analysis.IIncrementalTypeHierarchy; import ca.uwaterloo.gsd.fsml.javaMappingInterpreter.analysis.IJavaASTManager; import ca.uwaterloo.gsd.fsml.javaMappingInterpreter.analysis.IJavaImplVariantManager; import ca.uwaterloo.gsd.fsml.javaMappingInterpreter.analysis.JavaModelUtils; import ca.uwaterloo.gsd.fsml.stats.Stats; import ca.uwaterloo.gsd.fsml.sync.SyncItem; public abstract class JavaMapping extends Mapping { protected IAnalysisManagers analysisManagers; protected JavaMappingInterpreter javaInterpreter; protected IJavaContextManager contextManager; protected IJavaASTManager javaAstManager; protected IHierarchicalCallGraphManager callGraphManager; protected IJavaImplVariantManager javaImplVariantManager; protected IIncrementalTypeHierarchy typeHierarchy; /** * Reverse */ public JavaMapping( EObject element, EStructuralFeature feature, EAnnotation annotation, EClass concreteChildType, JavaMappingInterpreter interpreter, IProgressMonitor progressMonitor) throws FSMLMappingException { super(element, feature, annotation, concreteChildType, interpreter, progressMonitor); javaInterpreter = interpreter; getAnalysisManagers(); } /** * Reverse essential */ public JavaMapping( EObject element, EStructuralFeature feature, EStructuralFeature essentialFeature, EAnnotation annotation, EClass concreteChildType, JavaMappingInterpreter interpreter, IProgressMonitor progressMonitor) throws FSMLMappingException { super(element, feature, essentialFeature, annotation, concreteChildType, interpreter, progressMonitor); javaInterpreter = interpreter; getAnalysisManagers(); } /** * Forward */ public JavaMapping( SyncItem syncItem, EAnnotation annotation, JavaMappingInterpreter interpreter, IProgressMonitor progressMonitor) throws FSMLMappingException { super(syncItem.getModel() != null ? syncItem.getModel() : syncItem.getCode(), syncItem, annotation, null, interpreter, progressMonitor); javaInterpreter = interpreter; getAnalysisManagers(); } private void getAnalysisManagers() { analysisManagers = javaInterpreter.getAnalysisManagers(); javaAstManager = analysisManagers.getJavaASTManager(); contextManager = analysisManagers.getJavaContextManager(); callGraphManager = analysisManagers.getHierarchicalCallGraphManager(); javaImplVariantManager = analysisManagers.getJavaImplVariantManager(); typeHierarchy = analysisManagers.getTypeHierarchy(); } @Context(mode=Mode.ALL) public IJavaProject contextIJavaProject; protected JavaMarkerDescriptor createJavaMarkerDescriptor(IResource resource, Object value, String explanation) { JavaMarkerDescriptor markerDescriptor = new JavaMarkerDescriptor(resource); markerDescriptor.setFeature(feature); markerDescriptor.setExplanation(explanation); if (value != null) markerDescriptor.setValue(value); addMarkerDescriptor(markerDescriptor); return markerDescriptor; } protected JavaMarkerDescriptor createJavaMarkerDescriptor(IResource resource, String fullyQualifiedName, Object value, String explanation) { JavaMarkerDescriptor markerDescriptor = new JavaMarkerDescriptor(resource, fullyQualifiedName); markerDescriptor.setFeature(feature); markerDescriptor.setExplanation(explanation); if (value != null) markerDescriptor.setValue(value); addMarkerDescriptor(markerDescriptor); return markerDescriptor; } public void createMarkerDescriptor(Object item) { createMarkerDescriptor(item, null, null); } public void createMarkerDescriptor(Object item, Object value) { createMarkerDescriptor(item, value, null); } /** * @param item could be of one of the following types: IMemeber, SearchMatch, ASTNode * @param value */ public void createMarkerDescriptor(Object item, Object value, String explanation) { if (Stats.INSTANCE.logScatteringAndTangling) logScatteringAndTangling(item, value); if (item instanceof IMember) { IMember iMember = (IMember) item; if (iMember.isBinary()) { String fullyQualifiedName = iMember instanceof IType && ((IType) iMember).getDeclaringType() == null ? ((IType) iMember).getFullyQualifiedName() // top level type : iMember.getDeclaringType().getFullyQualifiedName(); // member or inner type IResource resource = iMember.getJavaProject().getResource(); JavaMarkerDescriptor markerDescriptor = createJavaMarkerDescriptor(resource, fullyQualifiedName, value, explanation); markerDescriptor.setCharStartCharEnd(iMember); return; } else { JavaMarkerDescriptor markerDescriptor = createJavaMarkerDescriptor(iMember.getResource(), value, explanation); markerDescriptor.setCharStartCharEnd(iMember); return; } } else if (item instanceof IClassFile) { IClassFile classFile = (IClassFile) item; String fullyQualifiedName = classFile.findPrimaryType().getFullyQualifiedName(); IResource resource = classFile.getJavaProject().getResource(); JavaMarkerDescriptor markerDescriptor = createJavaMarkerDescriptor(resource, fullyQualifiedName, value, explanation); markerDescriptor.setCharStartCharEnd(classFile); return; } else if (item instanceof ICompilationUnit) { ICompilationUnit iCompilationUnit = (ICompilationUnit) item; IResource resource = iCompilationUnit.getResource(); JavaMarkerDescriptor markerDescriptor = createJavaMarkerDescriptor(resource, value, explanation); markerDescriptor.setCharStartCharEnd(iCompilationUnit); return; } else if (item instanceof SearchMatch) { SearchMatch searchMatch = (SearchMatch) item; IJavaElement matchElement = (IJavaElement) searchMatch.getElement(); JavaMarkerDescriptor markerDescriptor = null; ICompilationUnit iCompilationUnit = (ICompilationUnit) matchElement.getAncestor(IJavaElement.COMPILATION_UNIT); if (iCompilationUnit != null) markerDescriptor = createJavaMarkerDescriptor(iCompilationUnit.getResource(), value, explanation); else { IClassFile iClassFile = (IClassFile) matchElement.getAncestor(IJavaElement.CLASS_FILE); String fqName = iClassFile.getType().getFullyQualifiedName(); markerDescriptor = createJavaMarkerDescriptor(matchElement.getJavaProject().getResource(), fqName, value, explanation); } if (markerDescriptor != null) { markerDescriptor.setCharStartCharEnd(searchMatch); return; } } else if (item instanceof ASTNode) { ASTNode astNode = (ASTNode) item; CompilationUnit compilationUnit = (CompilationUnit) astNode.getRoot(); ITypeRoot iTypeRoot = (ITypeRoot) compilationUnit.getJavaElement(); JavaMarkerDescriptor markerDescriptor = null; if (iTypeRoot instanceof ICompilationUnit) markerDescriptor = createJavaMarkerDescriptor(((ICompilationUnit)iTypeRoot).getResource(), value, explanation); else { String fqName = ((IClassFile)iTypeRoot).getType().getFullyQualifiedName(); markerDescriptor = createJavaMarkerDescriptor(iTypeRoot.getJavaProject().getResource(), fqName, value, explanation); } if (markerDescriptor != null) { markerDescriptor.setCharStartCharEnd(astNode); return; } } else { Stats.INSTANCE.logError("Marker not created for item: " + item.toString()); } } public boolean setFeatureContextAndMarker(boolean result, Object context, Object markerObject, Object markerValue) throws FSMLMappingException { return setFeatureContextAndMarker(result, context, markerObject, markerValue, null); } public boolean setFeatureContextAndMarker(boolean result, Object context, Object markerObject, Object markerValue, String explanation) throws FSMLMappingException { if (setFeature(result, context)) { if (markerObject != null) { // setFeature might have set the child field // child != null for containment references, markerValue != null for attributes createMarkerDescriptor(markerObject, (child != null ? child : markerValue), explanation); } return true; } return false; } public boolean setFeatureContextAndMarker(String result, Object context, Object markerObject, Object markerValue) throws FSMLMappingException { return setFeatureContextAndMarker(result, context, markerObject, markerValue, null); } public boolean setFeatureContextAndMarker(String result, Object context, Object markerObject, Object markerValue, String explanation) throws FSMLMappingException { if (setFeature(result, context)) { // setFeature might have set the child field // child != null for containment references, markerValue != null for attributes createMarkerDescriptor(markerObject, (child != null ? child : markerValue), explanation); return true; } return false; } public void setContextAndMarker(Object context, Object markerObject, String explanation) { Queries.INSTANCE.associateContext(child, context); createMarkerDescriptor(markerObject, child, explanation); } protected void logScatteringAndTangling(Object item, Object value) { String location = ""; if (item instanceof IMember) { IMember iMember = (IMember) item; try { IType iType = iMember instanceof IType ? (IType) iMember : JavaModelUtils.getDeclaringType(iMember); location = iType.getFullyQualifiedName(); Stats.INSTANCE.logScatteringAndTangling(element, feature, value, location); } catch (JavaModelException e) { e.printStackTrace(); } } else if (item instanceof SearchMatch) { SearchMatch searchMatch = (SearchMatch) item; IJavaElement iJavaElement = (IJavaElement) searchMatch.getElement(); try { IType iType = iJavaElement instanceof IType ? (IType) iJavaElement : JavaModelUtils.getDeclaringType(iJavaElement); location = iType.getFullyQualifiedName(); Stats.INSTANCE.logScatteringAndTangling(element, feature, value, location); IMethod iMethod = (IMethod) iJavaElement.getAncestor(IJavaElement.METHOD); if (iMethod != null) { location = iType.getFullyQualifiedName() + "." + iMethod.getElementName() + "()"; Stats.INSTANCE.logScatteringAndTangling(element, feature, value, location); } } catch (JavaModelException e) { e.printStackTrace(); } } else if (item instanceof ASTNode) { ASTNode astNode = (ASTNode) item; TypeDeclaration typeDeclaration = (TypeDeclaration) ASTUtils.getAncestorOfType(astNode, ASTNode.TYPE_DECLARATION); if (typeDeclaration != null) { location = ASTUtils.getFullyQualifiedName(typeDeclaration); Stats.INSTANCE.logScatteringAndTangling(element, feature, value, location); MethodDeclaration methodDeclaration = (MethodDeclaration) ASTUtils.getAncestorOfType(astNode, ASTNode.METHOD_DECLARATION); if (methodDeclaration != null) { IMethodBinding iMethodBinding = methodDeclaration.resolveBinding(); if (iMethodBinding != null) { location = ASTUtils.getFullyQualifiedName(typeDeclaration) + "." + iMethodBinding.getName() + "()"; Stats.INSTANCE.logScatteringAndTangling(element, feature, value, location); } } } } } /** * * @param syncItem * @param index * @return */ public static String retrieveTypeOfArgumentFromSignature(SyncItem syncItem, int index) { EObject element = FSMLEcoreUtil.retrieveContextElement(syncItem, JavaMappingInterpreter.CONTEXT_METHOD_CALL); EReference containingReference = (EReference) element.eContainingFeature(); EAnnotation annotation = containingReference.getEAnnotation(JavaMappingInterpreter.QUERY_CALLS_RECEIVED); String signature = null; if (annotation != null) { signature = annotation.getDetails().get(JavaMappingInterpreter.DETAIL_SIGNATURE); } else { annotation = containingReference.getEAnnotation(JavaMappingInterpreter.QUERY_METHOD_CALLS); if (annotation != null) { signature = annotation.getDetails().get(JavaMappingInterpreter.DETAIL_SIGNATURE); } } // variable "index" is 1-based, not 0-based String type = Signature.getParameterTypes(signature)[index-1]; return type; } }