<commit_before>/*******************************************************************************
 * Copyright (c) 2016 Inria 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:
 *     Inria - initial API and implementation
 *******************************************************************************/
package fr.inria.diverse.trace.gemoc.traceaddon;

import java.util.Deque;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.gemoc.xdsmlframework.api.engine_addon.modelchangelistener.ModelChange;
import org.gemoc.xdsmlframework.api.engine_addon.modelchangelistener.NewObjectModelChange;
import org.gemoc.xdsmlframework.api.engine_addon.modelchangelistener.NonCollectionFieldModelChange;
import org.gemoc.xdsmlframework.api.engine_addon.modelchangelistener.PotentialCollectionFieldModelChange;
import org.gemoc.xdsmlframework.api.engine_addon.modelchangelistener.RemovedObjectModelChange;
import org.gemoc.xdsmlframework.commons.DynamicAnnotationHelper;

import fr.inria.diverse.trace.commons.model.generictrace.BooleanAttributeValue;
import fr.inria.diverse.trace.commons.model.generictrace.GenericDimension;
import fr.inria.diverse.trace.commons.model.generictrace.GenericSequentialStep;
import fr.inria.diverse.trace.commons.model.generictrace.GenericSmallStep;
import fr.inria.diverse.trace.commons.model.generictrace.GenericState;
import fr.inria.diverse.trace.commons.model.generictrace.GenericStep;
import fr.inria.diverse.trace.commons.model.generictrace.GenericTracedObject;
import fr.inria.diverse.trace.commons.model.generictrace.GenericValue;
import fr.inria.diverse.trace.commons.model.generictrace.GenerictraceFactory;
import fr.inria.diverse.trace.commons.model.generictrace.IntegerAttributeValue;
import fr.inria.diverse.trace.commons.model.generictrace.ManyReferenceValue;
import fr.inria.diverse.trace.commons.model.generictrace.SingleReferenceValue;
import fr.inria.diverse.trace.commons.model.generictrace.StringAttributeValue;
import fr.inria.diverse.trace.commons.model.launchconfiguration.LaunchConfiguration;
import fr.inria.diverse.trace.commons.model.trace.BigStep;
import fr.inria.diverse.trace.commons.model.trace.MSEModel;
import fr.inria.diverse.trace.commons.model.trace.Step;
import fr.inria.diverse.trace.commons.model.trace.Trace;
import fr.inria.diverse.trace.commons.model.trace.TracedObject;
import fr.inria.diverse.trace.gemoc.api.ITraceConstructor;

public class GenericTraceConstructor implements ITraceConstructor {

	private Trace<GenericSequentialStep, GenericTracedObject, GenericState> traceRoot;
	private Resource executedModel;
	private MSEModel mseModel;
	private Resource traceResource;
	private final Map<EObject, TracedObject<?>> exeToTraced;
	private final Deque<GenericSequentialStep> context = new LinkedList<>();
	private GenericState lastState;
	
	public GenericTraceConstructor(Resource executedModel, Resource traceResource, Map<EObject, TracedObject<?>> exeToTraced) {
		this.executedModel = executedModel;
		this.traceResource = traceResource;
		this.exeToTraced = exeToTraced;
	}
	
	private Set<Resource> getAllExecutedModelResources() {
		Set<Resource> allResources = new HashSet<>();
		allResources.add(executedModel);
		allResources.addAll(org.gemoc.commons.eclipse.emf.EMFResource.getRelatedResources(executedModel));
		allResources.removeIf(r -> r == null);
		return allResources;
	}

	private boolean addNewObjectToStateIfDynamic(EObject object, GenericState state) {
		final EClass c = object.eClass();
		final List<EStructuralFeature> mutableProperties = c.getEAllStructuralFeatures().stream()
				.filter(p -> DynamicAnnotationHelper.isDynamic(p))
				.collect(Collectors.toList());
		if (DynamicAnnotationHelper.isDynamic(object.eClass()) || !mutableProperties.isEmpty()) {
			return addNewObjectToState(object, mutableProperties, lastState);
		}
		return true;
	}
	
	@SuppressWarnings("unchecked")
	private GenericValue getGenericValue(EObject object, EStructuralFeature mutableProperty, GenericState state) {
		GenericValue result = null;
		if (mutableProperty instanceof EAttribute) {
			final EClassifier eType = mutableProperty.getEType();
			if (eType == EcorePackage.Literals.EINT) {
				final IntegerAttributeValue value = GenerictraceFactory.eINSTANCE.createIntegerAttributeValue();
				value.setAttributeValue((Integer) object.eGet(mutableProperty));
				result = value;
			} else if (eType == EcorePackage.Literals.EBOOLEAN) {
				final BooleanAttributeValue value = GenerictraceFactory.eINSTANCE.createBooleanAttributeValue();
				value.setAttributeValue((Boolean) object.eGet(mutableProperty));
				result = value;
			} else if (eType == EcorePackage.Literals.ESTRING) {
				final StringAttributeValue value = GenerictraceFactory.eINSTANCE.createStringAttributeValue();
				value.setAttributeValue((String) object.eGet(mutableProperty));
				result = value;
			}
		} else if (mutableProperty instanceof EReference) {
			if (mutableProperty.isMany()) {
				final List<EObject> modelElements = (List<EObject>) object.eGet(mutableProperty);
				final ManyReferenceValue value = GenerictraceFactory.eINSTANCE.createManyReferenceValue();
				for (EObject o : modelElements) {
					if (DynamicAnnotationHelper.isDynamic(o.eClass())) {
						value.getReferenceValues().add(exeToTraced.get(o));
					} else {
						value.getReferenceValues().add(o);
					}
				}
				result = value;
			} else {
				final EObject o = (EObject) object.eGet(mutableProperty);
				final SingleReferenceValue value = GenerictraceFactory.eINSTANCE.createSingleReferenceValue();<commit_msg>[GenericTraceConstructor] Add IntegerObject case in trace construction<commit_after>/*******************************************************************************
 * Copyright (c) 2016 Inria 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:
 *     Inria - initial API and implementation
 *******************************************************************************/
package fr.inria.diverse.trace.gemoc.traceaddon;

import java.util.Deque;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.gemoc.xdsmlframework.api.engine_addon.modelchangelistener.ModelChange;
import org.gemoc.xdsmlframework.api.engine_addon.modelchangelistener.NewObjectModelChange;
import org.gemoc.xdsmlframework.api.engine_addon.modelchangelistener.NonCollectionFieldModelChange;
import org.gemoc.xdsmlframework.api.engine_addon.modelchangelistener.PotentialCollectionFieldModelChange;
import org.gemoc.xdsmlframework.api.engine_addon.modelchangelistener.RemovedObjectModelChange;
import org.gemoc.xdsmlframework.commons.DynamicAnnotationHelper;

import fr.inria.diverse.trace.commons.model.generictrace.BooleanAttributeValue;
import fr.inria.diverse.trace.commons.model.generictrace.GenericDimension;
import fr.inria.diverse.trace.commons.model.generictrace.GenericSequentialStep;
import fr.inria.diverse.trace.commons.model.generictrace.GenericSmallStep;
import fr.inria.diverse.trace.commons.model.generictrace.GenericState;
import fr.inria.diverse.trace.commons.model.generictrace.GenericStep;
import fr.inria.diverse.trace.commons.model.generictrace.GenericTracedObject;
import fr.inria.diverse.trace.commons.model.generictrace.GenericValue;
import fr.inria.diverse.trace.commons.model.generictrace.GenerictraceFactory;
import fr.inria.diverse.trace.commons.model.generictrace.IntegerAttributeValue;
import fr.inria.diverse.trace.commons.model.generictrace.IntegerObjectAttributeValue;
import fr.inria.diverse.trace.commons.model.generictrace.ManyReferenceValue;
import fr.inria.diverse.trace.commons.model.generictrace.SingleReferenceValue;
import fr.inria.diverse.trace.commons.model.generictrace.StringAttributeValue;
import fr.inria.diverse.trace.commons.model.launchconfiguration.LaunchConfiguration;
import fr.inria.diverse.trace.commons.model.trace.BigStep;
import fr.inria.diverse.trace.commons.model.trace.MSEModel;
import fr.inria.diverse.trace.commons.model.trace.Step;
import fr.inria.diverse.trace.commons.model.trace.Trace;
import fr.inria.diverse.trace.commons.model.trace.TracedObject;
import fr.inria.diverse.trace.gemoc.api.ITraceConstructor;

public class GenericTraceConstructor implements ITraceConstructor {

	private Trace<GenericSequentialStep, GenericTracedObject, GenericState> traceRoot;
	private Resource executedModel;
	private MSEModel mseModel;
	private Resource traceResource;
	private final Map<EObject, TracedObject<?>> exeToTraced;
	private final Deque<GenericSequentialStep> context = new LinkedList<>();
	private GenericState lastState;
	
	public GenericTraceConstructor(Resource executedModel, Resource traceResource, Map<EObject, TracedObject<?>> exeToTraced) {
		this.executedModel = executedModel;
		this.traceResource = traceResource;
		this.exeToTraced = exeToTraced;
	}
	
	private Set<Resource> getAllExecutedModelResources() {
		Set<Resource> allResources = new HashSet<>();
		allResources.add(executedModel);
		allResources.addAll(org.gemoc.commons.eclipse.emf.EMFResource.getRelatedResources(executedModel));
		allResources.removeIf(r -> r == null);
		return allResources;
	}

	private boolean addNewObjectToStateIfDynamic(EObject object, GenericState state) {
		final EClass c = object.eClass();
		final List<EStructuralFeature> mutableProperties = c.getEAllStructuralFeatures().stream()
				.filter(p -> DynamicAnnotationHelper.isDynamic(p))
				.collect(Collectors.toList());
		if (DynamicAnnotationHelper.isDynamic(object.eClass()) || !mutableProperties.isEmpty()) {
			return addNewObjectToState(object, mutableProperties, lastState);
		}
		return true;
	}
	
	@SuppressWarnings("unchecked")
	private GenericValue getGenericValue(EObject object, EStructuralFeature mutableProperty, GenericState state) {
		GenericValue result = null;
		if (mutableProperty instanceof EAttribute) {
			final EClassifier eType = mutableProperty.getEType();
			if (eType == EcorePackage.Literals.EINT) {
				final IntegerAttributeValue value = GenerictraceFactory.eINSTANCE.createIntegerAttributeValue();
				value.setAttributeValue((Integer) object.eGet(mutableProperty));
				result = value;
			} else if (eType == EcorePackage.Literals.EBOOLEAN) {
				final BooleanAttributeValue value = GenerictraceFactory.eINSTANCE.createBooleanAttributeValue();
				value.setAttributeValue((Boolean) object.eGet(mutableProperty));
				result = value;
			} else if (eType == EcorePackage.Literals.ESTRING) {
				final StringAttributeValue value = GenerictraceFactory.eINSTANCE.createStringAttributeValue();
				value.setAttributeValue((String) object.eGet(mutableProperty));
				result = value;
			} else  if (eType == EcorePackage.Literals.EINTEGER_OBJECT) {
				final IntegerObjectAttributeValue value = GenerictraceFactory.eINSTANCE.createIntegerObjectAttributeValue();
				value.setAttributeValue((Integer) object.eGet(mutableProperty));
				result = value;
			}
		} else if (mutableProperty instanceof EReference) {
			if (mutableProperty.isMany()) {
				final List<EObject> modelElements = (List<EObject>) object.eGet(mutableProperty);
				final ManyReferenceValue value = GenerictraceFactory.eINSTANCE.createManyReferenceValue();
				for (EObject o : modelElements) {
					if (DynamicAnnotationHelper.isDynamic(o.eClass())) {
						value.getReferenceValues().add(exeToTraced.get(o));
					} else {
						value.getReferenceValues().add(o);
					}
				}
				result = value;
			} else {
				final EObject o = (EObject) object.eGet(mutableProperty);
				final SingleReferenceValue value = GenerictraceFactory.eINSTANCE.createSingleReferenceValue();
{'fraction_non_alphanumeric': 0.12254751686082158, 'fraction_numerical': 0.001226241569589209, 'mean_word_length': 6.213377556661139, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6993679', 'n_tokens_mistral': 4041, 'n_tokens_neox': 3822, 'n_words': 639}