blob: bdeff52fb9b5e33a43bf48d537daaa6588ab7e99 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2018 SAP AG and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* SAP AG - initial API and implementation
******************************************************************************/
package org.eclipse.ocl.examples.impactanalyzer.benchmark.preparation.notifications;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Map;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.impl.EEnumImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.xmi.XMLResource;
public class RawNotification {
public final static String LINK_ADD_EVENT = "LinkAddEvent";
public final static String LINK_REMOVE_EVENT = "LinkRemoveEvent";
public final static String ATTRIBUTE_VALUE_CHANGE_EVENT = "AttributeValueChangeEvent";
public final static String ELEMENT_DELETE_EVENT = "ElementDeleteEvent";
public final static String ELEMENT_CREATE_EVENT ="ElementCreateEvent";
private final String eventType;
private final Map<String, String> attributeMap;
private int splitNumber = -1;
public RawNotification(String eventType, Map<String, String> attributeMap){
this.eventType = eventType;
this.attributeMap = attributeMap;
// TODO Auto-generated constructor stub
}
public String getEventType() {
return eventType;
}
public Map<String, String> getAttributeMap() {
return attributeMap;
}
public boolean isSplitCandidate(){
return getEventType().equals(LINK_ADD_EVENT) || getEventType().equals(LINK_REMOVE_EVENT);
}
public boolean wasSplitted(){
return isSplitCandidate() && splitNumber >= 0;
}
public int getSplitNumber(){
assert wasSplitted();
return splitNumber;
}
private void setSplitNumber(int i){
assert isSplitCandidate();
splitNumber = i;
}
public ArrayList<RawNotification> split(){
if(!isSplitCandidate()) {
throw new RuntimeException("This notification cannot be splitted");
}
ArrayList<RawNotification> result = new ArrayList<RawNotification>();
if(getEventType().equals(LINK_ADD_EVENT) || getEventType().equals(LINK_REMOVE_EVENT)){
for(int i = 0; i < 2; i++){
RawNotification noti = new RawNotification(getEventType(), getAttributeMap());
noti.setSplitNumber(i);
result.add(noti);
}
}
return result;
}
public Notification convertToNotification(Resource resource){
// FIXME: Conversion only works for AttributeValueChanges at the moment. Add support for all event types
// FIXME: By adding support for more events the following if condition must be refactored
if (getEventType().equals(ATTRIBUTE_VALUE_CHANGE_EVENT)) {
//System.out.println("AttributeValueChangeEvent");
String mofId = getAttributeMap().get("MRI").split("#")[1];
EObject obj = resource.getEObject(mofId);
EAttribute attribute = null;
if (obj != null) {
for (EObject contentObject : obj.eClass().getEAllAttributes()) {
if (contentObject instanceof EAttribute) {
if (((EAttribute) contentObject).getName().equals(getAttributeMap().get("attribute"))) {
attribute = (EAttribute) contentObject;
}
}
}
if(attribute != null){
String oldValue = getAttributeMap().get("oldValue");
String newValue = getAttributeMap().get("newValue");
Object oldValueParsed = null;
Object newValueParsed = null;
if (oldValue.equalsIgnoreCase("true") || oldValue.equalsIgnoreCase("false")) {
oldValueParsed = Boolean.parseBoolean(oldValue);
newValueParsed = Boolean.parseBoolean(newValue);
}
if (oldValueParsed == null || newValueParsed == null) {
try {
oldValueParsed = Integer.parseInt(oldValue);
newValueParsed = Integer.parseInt(newValue);
} catch (NumberFormatException e) {
}
}
if (oldValueParsed == null || newValueParsed == null) {
oldValueParsed = oldValue;
newValueParsed = newValue;
}
if(attribute.getEAttributeType() instanceof EEnumImpl){
EEnumImpl enumType = (EEnumImpl)attribute.getEAttributeType();
Class<?> enumClass = enumType.getInstanceClass();
for(Object constant : enumClass.getEnumConstants()){
if(constant.toString().equals(oldValue)){
oldValueParsed = constant;
}
if(constant.toString().equals(newValue)){
newValueParsed = constant;
}
}
if(oldValue.equals("null")){
oldValueParsed = null;
}
if(newValue.equals("null")){
newValueParsed = null;
}
}
return NotificationHelper.createAttributeChangeNotification(obj, attribute, oldValueParsed, newValueParsed);
}
}else{
//System.out.println("Element with MOFID: " + mofId + " cannot be found in Resource");
}
}else if(getEventType().equals(LINK_REMOVE_EVENT)){
//System.out.println("LinkRemoveEvent");
String mofId1 = getAttributeMap().get("MRI1").split("#")[1];
EObject obj1 = resource.getEObject(mofId1);
String mofId2 = getAttributeMap().get("MRI2").split("#")[1];
EObject obj2 = resource.getEObject(mofId2);
if(obj1 != null && obj2 != null){
// System.out.println("Both not null");
if(wasSplitted() && getSplitNumber() == 0) {
// System.out.println("Split" + 0);
return createLinkRemoveNotification(obj1, obj2);
} else if(wasSplitted() && getSplitNumber() == 1) {
// System.out.println("Split" + 1);
return createLinkRemoveNotification(obj2, obj1);
} else {
return null;
}
}
}else if(getEventType().equals(LINK_ADD_EVENT)){
//System.out.println("LinkAddEvent");
String mofId1 = getAttributeMap().get("MRI1").split("#")[1];
EObject obj1 = resource.getEObject(mofId1);
String mofId2 = getAttributeMap().get("MRI2").split("#")[1];
EObject obj2 = resource.getEObject(mofId2);
String rolename1 = getAttributeMap().get("AE2");
String rolename2 = getAttributeMap().get("AE3");
if(obj1 != null && obj2 != null){
// System.out.println("Both not null");
if(wasSplitted() && getSplitNumber() == 0) {
// System.out.println("Split" + 0);
return createLinkAddNotification(obj1, obj2, rolename1, rolename2);
} else if(wasSplitted() && getSplitNumber() == 1) {
// System.out.println("Split" + 1);
return createLinkAddNotification(obj2, obj1, rolename2, rolename1);
} else {
return null;
}
}
}else if(getEventType().equals(ELEMENT_DELETE_EVENT)){
//System.out.println("ElementDeleteEvent");
String mofId = getAttributeMap().get("MRI").split("#")[1];
EObject obj = resource.getEObject(mofId);
if (obj != null) {
return NotificationHelper.createElementDeleteNotification(obj);
}
}else if(getEventType().equals(ELEMENT_CREATE_EVENT)){
//System.out.println("ElementCreateEvent");
//FIXME: Change
ClassLoader classLoader = RealWorldReplayNotificationProducer.class.getClassLoader();
try {
String type = getAttributeMap().get("type");
String[] splittedType = type.split("\\.");
String clazz = splittedType[splittedType.length - 1];
String packagePath = type.split(clazz)[0];
String fullPackagePath = packagePath.toLowerCase() + splittedType[splittedType.length - 2].substring(0,1).toUpperCase() + splittedType[splittedType.length - 2].substring(1).toLowerCase() + "Package";
Class<?> aClass = classLoader.loadClass(fullPackagePath);
Field instance = aClass.getField("eINSTANCE");
EPackage pack= (EPackage)instance.get(null);
Method thisMethod = pack.getClass().getDeclaredMethod("get" + clazz);
// call the method
EClass classToCreate = (EClass)thisMethod.invoke(pack);
EObject obj = pack.getEFactoryInstance().create(classToCreate);
Notification res = NotificationHelper.createNewElementAddToResourceNotification(obj, resource);
((XMLResource)resource).setID(obj, getAttributeMap().get("MRI").split("#")[1]);
return res;
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
private Notification createLinkRemoveNotification(EObject obj1, EObject obj2) {
for(EReference reference : obj1.eClass().getEAllReferences()){
if(obj1.eGet(reference) != null){
if(obj1.eGet(reference) instanceof EList<?>){
@SuppressWarnings("unchecked")
EList<EObject> eObjectList = (EList<EObject>)obj1.eGet(reference);
for(EObject referencedObj : eObjectList){
if(referencedObj.equals(obj2)) {
return NotificationHelper.createReferenceRemoveNotification(obj1, reference, obj2);
}
}
}else if(obj1.eGet(reference).equals(obj2)) {
return NotificationHelper.createReferenceRemoveNotification(obj1, reference, obj2);
}
}
}
return null;
}
private Notification createLinkAddNotification(EObject obj1, EObject obj2, String rolename1, String rolename2) {
Notification result = null;
for(EReference reference : obj1.eClass().getEAllReferences()){
if(reference.getEType().isInstance(obj2)){
//System.out.println("Match1");
if(reference.getName().equals(rolename1) || reference.getName().equals(rolename2)){
//System.out.println("Match2");
result = NotificationHelper.createReferenceAddNotification(obj1, reference, obj2);
}
}
}
return result;
}
}