/******************************************************************************* * Copyright (c) 2011, 2012 University of Mannheim: Chair for Software Engineering * 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: * Ralph Gerbig - initial API and implementation and initial documentation *******************************************************************************/ package de.uni_mannheim.informatik.swt.mlm.emendation.service; import java.util.Collection; import java.util.HashSet; import java.util.Set; import org.eclipse.emf.common.command.Command; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.transaction.NotificationFilter; import org.eclipse.emf.transaction.ResourceSetChangeEvent; import org.eclipse.emf.transaction.ResourceSetListener; import org.eclipse.emf.transaction.RollbackException; import org.eclipse.emf.transaction.TransactionalEditingDomain; import org.eclipse.emf.transaction.util.TransactionUtil; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import de.uni_mannheim.informatik.swt.mlm.emendation.service.commands.EmendAddAttributeCommand; import de.uni_mannheim.informatik.swt.mlm.emendation.service.commands.EmendChangeClabjectTraitCommand; import de.uni_mannheim.informatik.swt.mlm.emendation.service.commands.EmendChangeFeatureTraitCommand; import de.uni_mannheim.informatik.swt.mlm.emendation.service.commands.EmendMoveAttributeCommand; import de.uni_mannheim.informatik.swt.mlm.emendation.service.commands.EmendRemoveAttributeCommand; import de.uni_mannheim.informatik.swt.mlm.workbench.interfaces.IEmendationService; import de.uni_mannheim.informatik.swt.mlm.workbench.preferences.PreferenceConstants; import de.uni_mannheim.informatik.swt.models.plm.PLM.Attribute; import de.uni_mannheim.informatik.swt.models.plm.PLM.Clabject; import de.uni_mannheim.informatik.swt.models.plm.PLM.DomainElement; import de.uni_mannheim.informatik.swt.models.plm.PLM.Element; import de.uni_mannheim.informatik.swt.models.plm.PLM.Feature; import de.uni_mannheim.informatik.swt.models.plm.PLM.Model; public class EmendationService implements IEmendationService, ResourceSetListener { public static String ID = "de.uni_mannheim.informatik.swt.mlm.emendation.service"; private boolean runService; Set<EObject> emendedObjects = new HashSet<EObject>(); private void listenForActivateEmendationServicePropertyChange(){ runService = de.uni_mannheim.informatik.swt.mlm.workbench.Activator.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.P_EMENDATION_ENGINE_ACTIVATED); de.uni_mannheim.informatik.swt.mlm.workbench.Activator.getDefault().getPreferenceStore().addPropertyChangeListener( new IPropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent event) { if(event.getProperty().equals(PreferenceConstants.P_EMENDATION_ENGINE_ACTIVATED)) runService = ((Boolean)event.getNewValue()).booleanValue(); } }); } @Override public void startListening(EObject modelRoot) { //modelRoot.eAdapters().add(this); //The user shall switch on/off the service listenForActivateEmendationServicePropertyChange(); TransactionalEditingDomain domain = TransactionUtil.getEditingDomain(modelRoot); domain.addResourceSetListener(this); } @Override public void stopListening(EObject modelRoot) { //modelRoot.eAdapters().remove(this); TransactionalEditingDomain domain = TransactionUtil.getEditingDomain(modelRoot); domain.removeResourceSetListener(this); } @Override public NotificationFilter getFilter() { return null; } @Override public Command transactionAboutToCommit(ResourceSetChangeEvent event) throws RollbackException { //The user switched off to run the service. if (!runService) return null; boolean entityAddedToModel = false; Notification addNotification = null; Notification removeNotification = null; //***********************************as*** //Check if move operation //************************************** for(Notification notification : event.getNotifications()){ if (notification.getEventType() == Notification.REMOVE && notification.getNotifier() instanceof Element) removeNotification = notification; else if(notification.getEventType() == Notification.ADD && notification.getNotifier() instanceof Element) addNotification = notification; } if (removeNotification != null && addNotification != null && removeNotification.getOldValue() == addNotification.getNewValue()){ if (emendedObjects.contains(addNotification.getNotifier())){ emendedObjects.remove(addNotification.getNotifier()); emendedObjects.clear(); return null; } ImpactAnalyzer analyzer = new ImpactAnalyzer(); //Collection<EObject> effectedModelElements = analyzer.getEffectedModelElementsForMoveFeatureOperation((Clabject)removeNotification.getNotifier(), (Clabject)addNotification.getNotifier(), (Feature)addNotification.getNewValue()); EmendMoveAttributeCommand emendCommand = new EmendMoveAttributeCommand(); Command command = emendCommand.run((Clabject)removeNotification.getNotifier(), (Clabject)addNotification.getNotifier(), (Feature)addNotification.getNewValue()); emendedObjects.clear(); emendedObjects.addAll(emendCommand.getEmendedObjects()); return command; } //Check if Entity is added to model for (Notification n : event.getNotifications()){ entityAddedToModel = n.getNotifier() instanceof Model; if (entityAddedToModel) return null; } //********************************************* // Model trait change //********************************************* for (Notification notification : event.getNotifications()) //NO DELETE if (notification.getNotifier() instanceof DomainElement && notification.getNewValue() != null ) { //********************************************* // Emend Feature Trait Change //********************************************* if (notification.getFeature() instanceof EStructuralFeature && notification.getNotifier() instanceof Feature && ( ((EStructuralFeature)notification.getFeature()).getName().equals("name") || ((EStructuralFeature)notification.getFeature()).getName().equals("durability") || ((EStructuralFeature)notification.getFeature()).getName().equals("mutability") //|| ((EStructuralFeature)notification.getFeature()).getName().equals("value") ) ) { if (emendedObjects.contains(notification.getNotifier())){ emendedObjects.remove(notification.getNotifier()); continue; } ImpactAnalyzer analyzer = new ImpactAnalyzer(); Collection<Feature> effectedModelElements = analyzer.getEffectedModelElementsForChangeTraitFeatureOperation((Feature)notification.getNotifier(), notification.getOldStringValue(), (EStructuralFeature)notification.getFeature()); if (effectedModelElements.size() > 0){ EmendChangeFeatureTraitCommand emendCommand = new EmendChangeFeatureTraitCommand(); Command command = emendCommand.run((Feature)notification.getNotifier(), (EStructuralFeature)notification.getFeature(), notification.getOldStringValue(), notification.getNewStringValue()); emendedObjects.clear(); //In case command is null no objects will be emended if (command != null) emendedObjects.addAll(emendCommand.getEmendedObjects()); return command; } } //********************************************* // Emend Clabject Trait change //********************************************* else if (notification.getFeature() instanceof EStructuralFeature && ((EStructuralFeature)notification.getFeature()).getName().equals("potency") && notification.getOldIntValue() != notification.getNewIntValue() ) { if (emendedObjects.contains(notification.getNotifier())){ emendedObjects.remove(notification.getNotifier()); continue; } ImpactAnalyzer analyzer = new ImpactAnalyzer(); Collection<Clabject> effectedModelElements = analyzer.getEffectedModelElementsForChangeTraitClabjectOperation((Clabject)notification.getNotifier(), notification.getOldStringValue(), (EStructuralFeature)notification.getFeature(), true); if (effectedModelElements.size() > 0){ EmendChangeClabjectTraitCommand emendCommand = new EmendChangeClabjectTraitCommand(); Command command = emendCommand.run((Clabject)notification.getNotifier(), (EStructuralFeature)notification.getFeature(), notification.getOldStringValue(), notification.getNewStringValue()); emendedObjects.clear(); //In case command is null no objects will be emended if (command != null) emendedObjects.addAll(emendCommand.getEmendedObjects()); return command; } } //********************************************* // Emend Clabject feature change (ADD) //********************************************* //Feature is added else if (notification.getFeature() instanceof EStructuralFeature && ((EStructuralFeature)notification.getFeature()).getName().equals("feature") && notification.getNewValue() instanceof Attribute) { if (emendedObjects.contains(notification.getNotifier())){ emendedObjects.remove(notification.getNotifier()); continue; } ImpactAnalyzer analyzer = new ImpactAnalyzer(); Collection<Clabject> effectedModelElements = analyzer.getEffectedModelElementsForAddFeatureOperation((Clabject)notification.getNotifier(), (Feature)notification.getNewValue()); if (effectedModelElements.size() > 0){ EmendAddAttributeCommand emendCommand = new EmendAddAttributeCommand(); Command command = emendCommand.run((Clabject)notification.getNotifier(), (Feature)notification.getNewValue()); //In case command is null no objects will be emended if (command != null) emendedObjects.addAll(emendCommand.getEmendedObjects()); return command; } } } //********************************************* //DELETE OPERATIONS //********************************************* else if (notification.getNotifier() instanceof DomainElement && notification.getNewValue() == null){ //********************************************* // Emend Clabject feature change (DELETE) //********************************************* if (notification.getFeature() instanceof EStructuralFeature && ((EStructuralFeature)notification.getFeature()).getName().equals("feature") && notification.getNewValue() == null){ if (emendedObjects.contains(notification.getOldValue())){ emendedObjects.remove(notification.getNotifier()); continue; } ImpactAnalyzer analyzer = new ImpactAnalyzer(); Collection<Feature> effectedModelElements = analyzer.getEffectedModelElementsForDeleteFeatureOperation((Feature)notification.getOldValue(), (Clabject)notification.getNotifier()); if (effectedModelElements.size() > 0){ EmendRemoveAttributeCommand emendCommand = new EmendRemoveAttributeCommand(); Command command = emendCommand.run((Clabject)notification.getNotifier(), (Feature)notification.getOldValue()); emendedObjects.clear(); //In case command is null no objects will be emended if (command != null) emendedObjects.addAll(emendCommand.getEmendedObjects()); return command; } } } return null; } @Override public void resourceSetChanged(ResourceSetChangeEvent event) { } @Override public boolean isAggregatePrecommitListener() { return false; } @Override public boolean isPrecommitOnly() { return true; } @Override public boolean isPostcommitOnly() { return false; } }