/*******************************************************************************
* 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;
}
}