/******************************************************************************* * 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.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.IField; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.Expression; import org.eclipse.jdt.core.dom.IBinding; import org.eclipse.jdt.core.dom.IVariableBinding; import org.eclipse.jdt.core.dom.SimpleName; import org.eclipse.jdt.core.dom.VariableDeclarationFragment; import org.eclipse.jdt.internal.corext.refactoring.structure.ASTNodeSearchUtil; import ca.uwaterloo.gsd.fsml.core.Cause; 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.ecore.FSMLEcoreUtil.NavigationResult; import ca.uwaterloo.gsd.fsml.javaMappingInterpreter.CodeTransforms; import ca.uwaterloo.gsd.fsml.javaMappingInterpreter.JavaMappingInterpreter; import ca.uwaterloo.gsd.fsml.sync.SyncItem; public class ArgumentIsFieldMapping extends ArgumentIs_Mapping { public ArgumentIsFieldMapping(EObject element, EStructuralFeature feature, EAnnotation annotation, EClass concreteChildType, JavaMappingInterpreter interpreter, IProgressMonitor progressMonitor) throws FSMLMappingException { super(element, feature, annotation, concreteChildType, interpreter, progressMonitor); } public ArgumentIsFieldMapping(SyncItem syncItem, EAnnotation annotation, JavaMappingInterpreter interpreter, IProgressMonitor progressMonitor) throws FSMLMappingException { super(syncItem, annotation, interpreter, progressMonitor); } @Parameter(name=JavaMappingInterpreter.DETAIL_SAME_AS, mode=Mode.NONE) public String detailSameAs; @Override protected boolean forward() throws FSMLMappingException { String fieldName = null; // field name comes from either // 1) an attribute annotated with QUERY_FIELD_NAME or // 2) from other feature annotated with CONTEXT_FIELD pointed to by DETAIL_SAME_AS parameter EObject contextFieldElement = element; String detailSameAs = (String) FSMLEcoreUtil.retrieveParameterValue(annotation, JavaMappingInterpreter.DETAIL_SAME_AS, false); if (detailSameAs != null) { NavigationResult target = FSMLEcoreUtil.navigateToEObject(element, detailSameAs); contextFieldElement = target.eObject; if (target == null || target.eObject == null) throw new FSMLMappingException(Cause.INCORRECT_VALUE, detailSameAs + " of " + JavaMappingInterpreter.DETAIL_SAME_AS); } // the field name is the value of the attribute annotated with QUERY_FIELD_NAME EAnnotation contextFieldAnnotation = FSMLEcoreUtil.getEAnnotation(contextFieldElement.eClass(), JavaMappingInterpreter.CONTEXT_FIELD); if (contextFieldAnnotation != null) { // find an attribute annotated with QUERY_FIELD_NAME EStructuralFeature fieldNameFeature = FSMLEcoreUtil.findEStructuralFeatureWithAnnotations(contextFieldElement.eClass(), new String[] { JavaMappingInterpreter.QUERY_FIELD_NAME }); if (fieldNameFeature == null) throw new FSMLMappingException(Cause.MISSING_ATTRIBUTE, JavaMappingInterpreter.QUERY_FIELD_NAME); if (fieldNameFeature instanceof EAttribute){ fieldName = (String) contextFieldElement.eGet(fieldNameFeature); while(fieldName==null || fieldName.length()==0){ fieldName = (String)FSMLEcoreUtil.getAttributeValueFromAttributeValueWizard((EAttribute)fieldNameFeature); if (fieldName!=null && fieldName.length()>0){ contextFieldElement.eSet(fieldNameFeature, fieldName); break; } } } else throw new FSMLMappingException(Cause.MAPPING_REQUIRES_ATTRIBUTE, fieldNameFeature); } else throw new FSMLMappingException(Cause.REQUIRED_CONTEXT_MISSING, JavaMappingInterpreter.CONTEXT_FIELD); switch (syncItem.getReconciliationAction()) { case CODE_ADD: if (contextMethodInvocation != null) { Expression expression = CodeTransforms.replaceMethodCallArgument(null, contextMethodInvocation, index, fieldName, progressMonitor); return expression != null; } if (contextClassInstanceCreation != null) { Expression expression = CodeTransforms.replaceMethodCallArgument(null, contextClassInstanceCreation, index, fieldName, progressMonitor); return expression != null; } break; case CODE_REMOVE: if (contextMethodInvocation != null) return CodeTransforms.replaceMethodCallArgument(null, contextMethodInvocation, index, "null", progressMonitor) != null; if (contextClassInstanceCreation != null) return CodeTransforms.replaceMethodCallArgument(null, contextClassInstanceCreation, index, "null", progressMonitor) != null; } return false; } @Override protected boolean reverse() throws FSMLMappingException { ASTNode argument = null; if (contextMethodInvocation != null) argument = (ASTNode) contextMethodInvocation.arguments().get(index); if (contextClassInstanceCreation != null) argument = (ASTNode) contextClassInstanceCreation.arguments().get(index); if (argument instanceof SimpleName) { SimpleName simpleName = (SimpleName) argument; IBinding binding = simpleName.resolveBinding(); if (binding instanceof IVariableBinding) { IVariableBinding variableBinding = (IVariableBinding) binding; if (variableBinding.isField()) { if (detailSameAs != null && !detailSameAs.isEmpty()) { NavigationResult navigationResult = FSMLEcoreUtil.navigateToEObject(element, detailSameAs); VariableDeclarationFragment targetField = contextManager.getContextVariableDeclarationFragment(navigationResult.eObject, true, progressMonitor); if (targetField == null || !targetField.resolveBinding().getKey().equals(variableBinding.getKey())) return setFeature(false); // else ok, proceed } IField field = (IField) variableBinding.getJavaElement(); CompilationUnit cu = javaAstManager.getCompilationUnit(field); try { VariableDeclarationFragment fieldDeclarationFragment = ASTNodeSearchUtil.getFieldDeclarationFragmentNode(field, cu); if (feature.getEType().getName().equals("EString")) return setFeatureContextAndMarker(fieldDeclarationFragment.getName().getIdentifier(), fieldDeclarationFragment, argument, null); else return setFeatureContextAndMarker(true, fieldDeclarationFragment, argument, null); } catch (JavaModelException e) { e.printStackTrace(); } } } } if (feature.getEType().getName().equals("EString")) return setFeature((String) null); else return setFeature(false); } }