/******************************************************************************* * 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 java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.emf.ecore.EAnnotation; import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.Signature; import org.eclipse.jdt.core.dom.Annotation; import org.eclipse.jdt.core.dom.BodyDeclaration; import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.TypeDeclaration; import org.eclipse.jdt.core.dom.VariableDeclarationFragment; import org.eclipse.jdt.core.search.IJavaSearchConstants; import org.eclipse.jdt.core.search.IJavaSearchScope; import org.eclipse.jdt.core.search.SearchEngine; import org.eclipse.jdt.core.search.SearchMatch; import org.eclipse.jdt.core.search.SearchParticipant; import org.eclipse.jdt.core.search.SearchPattern; import org.eclipse.jdt.core.search.SearchRequestor; import org.eclipse.jdt.core.search.TypeReferenceMatch; import ca.uwaterloo.gsd.fsml.core.FSMLMappingException; import ca.uwaterloo.gsd.fsml.core.Mode; import ca.uwaterloo.gsd.fsml.core.Parameter; import ca.uwaterloo.gsd.fsml.ecore.FSMLEcoreUtil; import ca.uwaterloo.gsd.fsml.javaMappingInterpreter.JavaMappingInterpreter; import ca.uwaterloo.gsd.fsml.javaMappingInterpreter.analysis.ASTUtils; import ca.uwaterloo.gsd.fsml.sync.SyncItem; public class AnnotatedWithMapping extends JavaMapping { public AnnotatedWithMapping(EObject element, EStructuralFeature feature, EAnnotation annotation, EClass concreteChildType, JavaMappingInterpreter interpreter, IProgressMonitor progressMonitor) throws FSMLMappingException { super(element, feature, annotation, concreteChildType, interpreter, progressMonitor); } public AnnotatedWithMapping(EObject element, EStructuralFeature feature, EStructuralFeature essentialFeature, EAnnotation annotation, EClass concreteChildType, JavaMappingInterpreter interpreter, IProgressMonitor progressMonitor) throws FSMLMappingException { super(element, feature, essentialFeature, annotation, concreteChildType, interpreter, progressMonitor); } public AnnotatedWithMapping(SyncItem syncItem, EAnnotation annotation, JavaMappingInterpreter interpreter, IProgressMonitor progressMonitor) throws FSMLMappingException { super(syncItem, annotation, interpreter, progressMonitor); } @Parameter(name=JavaMappingInterpreter.DETAIL_FULLY_QUALIFIED_TYPE, mode=Mode.ALL, required=true) public String fullyQualifiedName; @Override protected boolean forward() throws FSMLMappingException { return false; } @Override protected boolean reverse() throws FSMLMappingException { String simpleAnnotationType = Signature.getSimpleName(fullyQualifiedName); BodyDeclaration bodyDeclaration = null; if (FSMLEcoreUtil.getEAnnotation(element.eClass(),JavaMappingInterpreter.CONTEXT_METHOD) != null) //we have a method bodyDeclaration = contextManager.getContextMethodDeclaration(element, true, progressMonitor); else if (FSMLEcoreUtil.getEAnnotation(element.eClass(),JavaMappingInterpreter.CONTEXT_FIELD) != null) bodyDeclaration = (BodyDeclaration) contextManager.getContextVariableDeclarationFragment(element, true, progressMonitor).getParent(); else if (FSMLEcoreUtil.getEAnnotation(element.eClass(),JavaMappingInterpreter.CONTEXT_CLASS) != null) //we have a class bodyDeclaration = contextManager.getContextTypeDeclaration(element, true, progressMonitor); else return setFeature(false); boolean foundDesiredAnnotation = false; Annotation foundAnnotation = null; for (Object modifier : bodyDeclaration.modifiers()) { if (modifier instanceof Annotation){ String modifierType = ((Annotation)modifier).getTypeName().getFullyQualifiedName(); if (fullyQualifiedName.equalsIgnoreCase(modifierType) || simpleAnnotationType.equalsIgnoreCase(modifierType)){ foundDesiredAnnotation = true; foundAnnotation = (Annotation) modifier; break; } } } if (!foundDesiredAnnotation){ return setFeature(false); } return setFeatureContextAndMarker(true, foundAnnotation, feature instanceof EAttribute ? bodyDeclaration : foundAnnotation, null); } @Override protected boolean reverseEssential() throws FSMLMappingException { try { IType annotationType = contextIJavaProject.findType(fullyQualifiedName); if (annotationType == null || !annotationType.exists()) return false; if (FSMLEcoreUtil.getEAnnotation(concreteChildType, JavaMappingInterpreter.CONTEXT_FIELD) != null) { TypeDeclaration contextTypeDeclaration = contextManager.getContextTypeDeclaration(element, true, progressMonitor); List<VariableDeclarationFragment> fields = ASTUtils.getFieldsAnnotatedWithType(contextTypeDeclaration, fullyQualifiedName, progressMonitor); for (VariableDeclarationFragment field : fields) setFeatureContextAndMarker(true, field, field, null); return FSMLEcoreUtil.isFeaturePresent(element, feature); } if (FSMLEcoreUtil.getEAnnotation(concreteChildType, JavaMappingInterpreter.CONTEXT_METHOD) != null) { TypeDeclaration contextTypeDeclaration = contextManager.getContextTypeDeclaration(element, true, progressMonitor); List<MethodDeclaration> methods = ASTUtils.getMethodsAnnotatedWithType(contextTypeDeclaration, fullyQualifiedName, progressMonitor); for (MethodDeclaration method : methods) setFeatureContextAndMarker(true, method, method, null); return FSMLEcoreUtil.isFeaturePresent(element, feature); } else if (FSMLEcoreUtil.getEAnnotation(concreteChildType, JavaMappingInterpreter.CONTEXT_CLASS) != null) { final ArrayList<TypeReferenceMatch> found = new ArrayList<TypeReferenceMatch>(); SearchPattern pattern = SearchPattern.createPattern(annotationType, IJavaSearchConstants.REFERENCES); // Create search scope IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[] { contextIJavaProject }); SearchRequestor requestor = new SearchRequestor(){ @Override public void acceptSearchMatch(SearchMatch match) throws CoreException { if (match instanceof TypeReferenceMatch){ if (match.getElement() instanceof IType){ found.add((TypeReferenceMatch)match); } } } }; SearchEngine searchEngine = new SearchEngine(); try { searchEngine.search(pattern, new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()}, scope, requestor, null); } catch (CoreException e) { e.printStackTrace(); } for (TypeReferenceMatch typeReferenceMatch : found) { IType type = (IType) typeReferenceMatch.getElement(); setFeatureContextAndMarker(true, type, type, null); } return FSMLEcoreUtil.isFeaturePresent(element, feature); } } catch (JavaModelException e) { e.printStackTrace(); } return false; } }