/***************************************************************************** * Copyright (c) 2010 CEA LIST. * * * 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: * CEA LIST - Initial API and implementation * *****************************************************************************/ package org.eclipse.papyrus.uml.textedit.property.xtext.ui.contributions; import java.util.ArrayList; import java.util.List; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.transaction.TransactionalEditingDomain; import org.eclipse.gmf.runtime.common.core.command.CompositeCommand; import org.eclipse.gmf.runtime.common.core.command.ICommand; import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; import org.eclipse.gmf.runtime.emf.type.core.requests.SetRequest; import org.eclipse.papyrus.commands.wrappers.GMFtoEMFCommandWrapper; import org.eclipse.papyrus.extensionpoints.editors.ui.IPopupEditorHelper; import org.eclipse.papyrus.infra.core.utils.EditorUtils; import org.eclipse.papyrus.infra.services.edit.service.ElementEditServiceUtils; import org.eclipse.papyrus.infra.services.edit.service.IElementEditService; //import org.eclipse.papyrus.views.properties.runtime.modelhandler.emf.EMFUtils; //import org.eclipse.papyrus.views.properties.runtime.modelhandler.emf.TransactionUtil; import org.eclipse.papyrus.uml.textedit.property.xtext.ui.internal.UmlPropertyActivator; import org.eclipse.papyrus.uml.textedit.property.xtext.umlProperty.ModifierSpecification; import org.eclipse.papyrus.uml.textedit.property.xtext.umlProperty.PropertyRule; import org.eclipse.papyrus.uml.textedit.property.xtext.umlProperty.TypeRule; import org.eclipse.papyrus.uml.textedit.property.xtext.validation.SemanticValidator; import org.eclipse.papyrus.uml.textedit.property.xtext.validation.UmlPropertyJavaValidator; import org.eclipse.uml2.uml.Classifier; import org.eclipse.uml2.uml.Property; import org.eclipse.uml2.uml.UMLPackage; import org.eclipse.xtext.gmf.glue.PopupEditorConfiguration; import org.eclipse.xtext.gmf.glue.edit.part.IXtextEMFReconciler; import com.google.inject.Injector; /** * @author CEA LIST * * This class is used for contribution to the Papyrus extension point DirectEditor. It is used for the integration * of an xtext generated editor, for properties of UML classifiers. * */ public class PropertyPopupEditorConfigurationContribution extends PopupEditorConfiguration { private Property property; private boolean newIsDerived; private boolean newIsReadOnly; private boolean newIsUnique; private boolean newIsUnion; private boolean newIsOrdered; private int newLowerBound; private int newUpperBound; private String newDefault ; private String newName; private Classifier newType; private org.eclipse.uml2.uml.VisibilityKind newVisibility; private List<Property> newRedefines = new ArrayList<Property>() ; private List<Property> newSubsets = new ArrayList<Property>() ; /** * Default implementation of the constructor for this class */ public PropertyPopupEditorConfigurationContribution() { super(); } /* * (non-Javadoc) * * @see * org.eclipse.xtext.gmf.glue.PopupEditorConfiguration#createPopupEditorHelper(org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart) */ @Override public IPopupEditorHelper createPopupEditorHelper(Object editPart) { // resolves the edit part, and the associated semantic element IGraphicalEditPart graphicalEditPart = null; if(!(editPart instanceof IGraphicalEditPart)) { return null; } graphicalEditPart = (IGraphicalEditPart)editPart; if(!(graphicalEditPart.resolveSemanticElement() instanceof Property)) { return null; } property = (Property)graphicalEditPart.resolveSemanticElement(); UmlPropertyJavaValidator.init(property); // retrieves the XText injector Injector injector = UmlPropertyActivator.getInstance().getInjector("org.eclipse.papyrus.uml.textedit.property.xtext.UmlProperty"); // builds the text content and extension for a temporary file, to be edited by the xtext editor String textToEdit = "" + this.getTextToEdit(graphicalEditPart.resolveSemanticElement()); String fileExtension = "" + ".umlproperty"; // builds a new IXtextEMFReconciler. // Its purpose is to extract any relevant information from the textual specification, // and then merge it in the context UML model if necessary IXtextEMFReconciler reconciler = new IXtextEMFReconciler() { public void reconcile(EObject modelObject, EObject xtextObject) { // first: retrieves / determines if the xtextObject is a PropertyRule object EObject modifiedObject = xtextObject; if(!(modelObject instanceof Property)) { return; } while(xtextObject != null && !(xtextObject instanceof PropertyRule)) { modifiedObject = modifiedObject.eContainer(); } if(modifiedObject == null) { return; } PropertyRule propertyRuleObject = (PropertyRule)xtextObject; // Retrieves the information to be populated in modelObject newIsDerived = propertyRuleObject.getIsDerived() != null && propertyRuleObject.getIsDerived().equals("/"); newIsReadOnly = false; newIsUnique = false; newIsUnion = false; newIsOrdered = false; newRedefines = new ArrayList<Property>() ; newSubsets = new ArrayList<Property>() ; if(propertyRuleObject.getModifiers() != null) { for(ModifierSpecification modifier : propertyRuleObject.getModifiers().getValues()) { if (modifier.getRedefines() == null && modifier.getSubsets()==null) { switch(modifier.getValue()) { case ORDERED: newIsOrdered = true; break; case READ_ONLY: newIsReadOnly = true; break; case UNION: newIsUnion = true; break; case UNIQUE: newIsUnique = true; break; default: break; } } } for (ModifierSpecification modifier : propertyRuleObject.getModifiers().getValues()) { if (modifier.getRedefines() != null) { newRedefines.add(modifier.getRedefines().getProperty()) ; } else if (modifier.getSubsets() != null) { newSubsets.add(modifier.getSubsets().getProperty()) ; } } } newLowerBound = 1; newUpperBound = 1; if(propertyRuleObject.getMultiplicity() != null) { if(propertyRuleObject.getMultiplicity().getBounds().size() == 1) { String tempBound = propertyRuleObject.getMultiplicity().getBounds().get(0).getValue(); if(tempBound.equals("*")) { newLowerBound = 0; newUpperBound = -1; } else { newLowerBound = new Integer(tempBound).intValue(); newUpperBound = new Integer(tempBound).intValue(); } } else { //size == 2 String tempBound = propertyRuleObject.getMultiplicity().getBounds().get(0).getValue(); newLowerBound = new Integer(tempBound).intValue(); tempBound = propertyRuleObject.getMultiplicity().getBounds().get(1).getValue(); if(tempBound.equals("*")) { newUpperBound = -1; } else { newUpperBound = new Integer(tempBound).intValue(); } } } if (propertyRuleObject.getDefault() != null) { newDefault = propertyRuleObject.getDefault().getDefault() ; } else { newDefault = null ; } newName = "" + propertyRuleObject.getName(); TypeRule typeRule = propertyRuleObject.getType(); if(typeRule == null) { newType = null; } else { newType = typeRule.getType(); } newVisibility = org.eclipse.uml2.uml.VisibilityKind.PUBLIC_LITERAL; switch(propertyRuleObject.getVisibility()) { case PUBLIC: newVisibility = org.eclipse.uml2.uml.VisibilityKind.PUBLIC_LITERAL; break; case PACKAGE: newVisibility = org.eclipse.uml2.uml.VisibilityKind.PACKAGE_LITERAL; break; case PRIVATE: newVisibility = org.eclipse.uml2.uml.VisibilityKind.PRIVATE_LITERAL; break; case PROTECTED: newVisibility = org.eclipse.uml2.uml.VisibilityKind.PROTECTED_LITERAL; break; default: break; } org.eclipse.gmf.runtime.common.core.command.CompositeCommand updateCommand = getUpdateCommand(property); List<Property> editedObjects = new ArrayList<Property>(); editedObjects.add(property); TransactionalEditingDomain editingDomain =org.eclipse.emf.transaction.util.TransactionUtil.getEditingDomain(property); if(updateCommand.canExecute()) {// && !(TransactionUtil.isReadTransactionInProgress(editingDomain, true, true)) editingDomain.getCommandStack().execute(new GMFtoEMFCommandWrapper(updateCommand)); return; } } }; return super.createPopupEditorHelper(graphicalEditPart, injector, reconciler, textToEdit, fileExtension, new SemanticValidator()); } private CompositeCommand getUpdateCommand(EObject editedObject) { org.eclipse.gmf.runtime.common.core.command.CompositeCommand updateCommand = new CompositeCommand("Property update"); IElementEditService provider = ElementEditServiceUtils.getCommandProvider(editedObject); SetRequest setIsDerivedRequest = new SetRequest(editedObject, UMLPackage.eINSTANCE.getProperty_IsDerived(), newIsDerived); ICommand setIsDerivedCommand = provider.getEditCommand(setIsDerivedRequest); updateCommand.add(setIsDerivedCommand); SetRequest setIsReadOnlyRequest = new SetRequest(editedObject, UMLPackage.eINSTANCE.getStructuralFeature_IsReadOnly(), newIsReadOnly); ICommand setIsReadOnlyCommand = provider.getEditCommand(setIsReadOnlyRequest); updateCommand.add(setIsReadOnlyCommand); SetRequest setIsUniqueRequest = new SetRequest(editedObject, UMLPackage.eINSTANCE.getMultiplicityElement_IsUnique(), newIsUnique); ICommand setIsUniqueCommand = provider.getEditCommand(setIsUniqueRequest); updateCommand.add(setIsUniqueCommand); SetRequest setIsDerivedUnionRequest = new SetRequest(editedObject, UMLPackage.eINSTANCE.getProperty_IsDerivedUnion(), newIsUnion); ICommand setIsDerivedUnionCommand = provider.getEditCommand(setIsDerivedUnionRequest); updateCommand.add(setIsDerivedUnionCommand); SetRequest setIsOrderedRequest = new SetRequest(editedObject, UMLPackage.eINSTANCE.getMultiplicityElement_IsOrdered(), newIsOrdered); ICommand setIsOrderedCommand = provider.getEditCommand(setIsOrderedRequest); updateCommand.add(setIsOrderedCommand); SetRequest setLowerRequest = new SetRequest(editedObject, UMLPackage.eINSTANCE.getMultiplicityElement_Lower(), newLowerBound); ICommand setLowerCommand = provider.getEditCommand(setLowerRequest); updateCommand.add(setLowerCommand); SetRequest setUpperRequest = new SetRequest(editedObject, UMLPackage.eINSTANCE.getMultiplicityElement_Upper(), newUpperBound); ICommand setUpperCommand = provider.getEditCommand(setUpperRequest); updateCommand.add(setUpperCommand); SetRequest setNameRequest = new SetRequest(editedObject, UMLPackage.eINSTANCE.getNamedElement_Name(), newName); ICommand setNameCommand = provider.getEditCommand(setNameRequest); updateCommand.add(setNameCommand); SetRequest setTypeRequest = new SetRequest(editedObject, UMLPackage.eINSTANCE.getTypedElement_Type(), newType); ICommand setTypeCommand = provider.getEditCommand(setTypeRequest); updateCommand.add(setTypeCommand); SetRequest setVisibilityRequest = new SetRequest(editedObject, UMLPackage.eINSTANCE.getNamedElement_Visibility(), newVisibility); ICommand setVisibilityCommand = provider.getEditCommand(setVisibilityRequest); updateCommand.add(setVisibilityCommand); SetRequest setDefaultValueRequest = new SetRequest (editedObject, UMLPackage.eINSTANCE.getProperty_Default(), newDefault) ; ICommand setDefaultValueCommand = provider.getEditCommand(setDefaultValueRequest) ; updateCommand.add(setDefaultValueCommand) ; SetRequest setRedefinedPropertiesRequest = new SetRequest (editedObject, UMLPackage.eINSTANCE.getProperty_RedefinedProperty(), newRedefines) ; ICommand setRedefinedPropertiesCommand = provider.getEditCommand(setRedefinedPropertiesRequest) ; updateCommand.add(setRedefinedPropertiesCommand) ; SetRequest setSubsettedPropertiesRequest = new SetRequest (editedObject, UMLPackage.eINSTANCE.getProperty_SubsettedProperty(), newSubsets) ; ICommand setSubsettedPropertiesCommand = provider.getEditCommand(setSubsettedPropertiesRequest) ; updateCommand.add(setSubsettedPropertiesCommand) ; return updateCommand; } /* * (non-Javadoc) * * @see org.eclipse.xtext.gmf.glue.PopupEditorConfiguration#getTextToEdit(java.lang.Object) */ @Override public String getTextToEdit(Object editedObject) { if(editedObject instanceof Property) { return UMLPropertyEditorPropertyUtil.getLabel((Property)editedObject).trim(); // TODO: default values not supported by the grammar // TODO: either complete the grammar, or use another label provider } return "not a Property"; } }