/******************************************************************************* * Copyright (c) 2009, 2010 SAP AG and others. * 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: * 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; } }