diff --git a/org.eclipse.emf.emfstore.client.test/src/org/eclipse/emf/emfstore/client/test/server/ModelGeneratorTest.java b/org.eclipse.emf.emfstore.client.test/src/org/eclipse/emf/emfstore/client/test/server/ModelGeneratorTest.java
index 019c223..245a98d 100644
--- a/org.eclipse.emf.emfstore.client.test/src/org/eclipse/emf/emfstore/client/test/server/ModelGeneratorTest.java
+++ b/org.eclipse.emf.emfstore.client.test/src/org/eclipse/emf/emfstore/client/test/server/ModelGeneratorTest.java
@@ -12,13 +12,11 @@
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
-import org.eclipse.emf.ecore.resource.ResourceSet;
-import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.emfstore.client.model.ProjectSpace;
import org.eclipse.emf.emfstore.client.model.Usersession;
+import org.eclipse.emf.emfstore.client.model.WorkspaceManager;
import org.eclipse.emf.emfstore.client.test.SetupHelper;
import org.eclipse.emf.emfstore.common.model.Project;
-import org.eclipse.emf.emfstore.common.model.util.ModelUtil;
import org.eclipse.emf.emfstore.modelgenerator.ModelGenerator;
import org.eclipse.emf.emfstore.modelgenerator.common.ModelGeneratorConfiguration;
import org.eclipse.emf.emfstore.modelgenerator.common.ModelGeneratorUtil;
@@ -46,15 +44,8 @@ public class ModelGeneratorTest extends ServerTests {
public void beforeTest() throws EmfStoreException {
super.beforeTest();
- projectSpace = org.eclipse.emf.emfstore.client.model.ModelFactory.eINSTANCE.createProjectSpace();
- projectSpace.setProject(org.eclipse.emf.emfstore.common.model.ModelFactory.eINSTANCE.createProject());
- projectSpace.setProjectName(projectName);
- projectSpace.setProjectDescription(projectDescription);
- projectSpace.setLocalOperations(org.eclipse.emf.emfstore.client.model.ModelFactory.eINSTANCE
- .createOperationComposite());
- ResourceSet resourceSet = new ResourceSetImpl();
- resourceSet.getLoadOptions().putAll(ModelUtil.getResourceLoadOptions());
- projectSpace.initResources(resourceSet);
+ projectSpace = WorkspaceManager.getInstance().getCurrentWorkspace()
+ .createLocalProject(projectName, projectDescription);
Usersession session = org.eclipse.emf.emfstore.client.model.ModelFactory.eINSTANCE.createUsersession();
session.setServerInfo(SetupHelper.getServerInfo());
diff --git a/org.eclipse.emf.emfstore.modelgenerator.common/META-INF/MANIFEST.MF b/org.eclipse.emf.emfstore.modelgenerator.common/META-INF/MANIFEST.MF
index f6d92c9..e6d1bb0 100644
--- a/org.eclipse.emf.emfstore.modelgenerator.common/META-INF/MANIFEST.MF
+++ b/org.eclipse.emf.emfstore.modelgenerator.common/META-INF/MANIFEST.MF
@@ -1,12 +1,13 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: Modelgenerator Common
-Bundle-SymbolicName: org.eclipse.emf.emfstore.modelgenerator.common
-Bundle-Version: 0.8.9.M9
-Bundle-RequiredExecutionEnvironment: J2SE-1.5
-Export-Package: org.eclipse.emf.emfstore.modelgenerator.common,
- org.eclipse.emf.emfstore.modelgenerator.common.attribute
-Require-Bundle: org.eclipse.emf.ecore,
- org.eclipse.emf.edit
-Bundle-ActivationPolicy: lazy
-Bundle-Vendor: Eclipse Modeling Project
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Modelgenerator Common
+Bundle-SymbolicName: org.eclipse.emf.emfstore.modelgenerator.common
+Bundle-Version: 0.8.9.M9
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Export-Package: org.eclipse.emf.emfstore.modelgenerator.common,
+ org.eclipse.emf.emfstore.modelgenerator.common.attribute
+Require-Bundle: org.eclipse.emf.ecore,
+ org.eclipse.emf.edit,
+ org.eclipse.emf.emfstore.client;bundle-version="0.8.9"
+Bundle-ActivationPolicy: lazy
+Bundle-Vendor: Eclipse Modeling Project
diff --git a/org.eclipse.emf.emfstore.modelgenerator.common/src/org/eclipse/emf/emfstore/modelgenerator/common/ModelGeneratorUtil.java b/org.eclipse.emf.emfstore.modelgenerator.common/src/org/eclipse/emf/emfstore/modelgenerator/common/ModelGeneratorUtil.java
index 8b072a0..2cd1559 100644
--- a/org.eclipse.emf.emfstore.modelgenerator.common/src/org/eclipse/emf/emfstore/modelgenerator/common/ModelGeneratorUtil.java
+++ b/org.eclipse.emf.emfstore.modelgenerator.common/src/org/eclipse/emf/emfstore/modelgenerator/common/ModelGeneratorUtil.java
@@ -1,668 +1,681 @@
-/**
- * Copyright (c) 2008-2009 Jonas Helming, Maximilian Koegel. 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
- */
-package org.eclipse.emf.emfstore.modelgenerator.common;
-
-import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.Set;
-import java.util.Map.Entry;
-
-import org.eclipse.emf.common.util.TreeIterator;
-import org.eclipse.emf.ecore.EAttribute;
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EClassifier;
-import org.eclipse.emf.ecore.EEnum;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EPackage;
-import org.eclipse.emf.ecore.EStructuralFeature;
-import org.eclipse.emf.ecore.EPackage.Registry;
-import org.eclipse.emf.ecore.EReference;
-import org.eclipse.emf.ecore.EcorePackage;
-import org.eclipse.emf.ecore.util.EcoreUtil;
-import org.eclipse.emf.edit.command.AddCommand;
-import org.eclipse.emf.edit.command.RemoveCommand;
-import org.eclipse.emf.edit.command.SetCommand;
-import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
-import org.eclipse.emf.edit.domain.EditingDomain;
-import org.eclipse.emf.emfstore.modelgenerator.common.attribute.AttributeHandler;
-import org.eclipse.emf.emfstore.modelgenerator.common.attribute.IAttributeSetter;
-
-/**
- * Utility class to generate and change Ecore models.
- * All methods should be accessed in a static way,
- * therefore the constructor is not visible.
- */
-public final class ModelGeneratorUtil {
-
- /**
- * Set of all EClasses that are contained in EPackages that are
- * currently registered in the EPackage registry.
- *
- * @see #getAllEClasses()
- */
- private static List allEClasses;
-
- /**
- * Set of all EPackages that are currently registered in the
- * EPackage registry and not contained in any other package.
- *
- * @see #getAllRootEPackages()
- */
- private static Set rootModelPackages;
-
- /**
- * Map that maps EPackages to a set of all their contained EClasses.
- *
- * @see #getAllEClasses(EPackage)
- */
- private static Map> packageToModelElementEClasses = new LinkedHashMap>();
-
- /**
- * Map that maps EReferences to all possible EClasses that can be contained
- * when using them.
- *
- * @see #getAllEContainments(EReference)
- */
- private static Map> allEContainments = new LinkedHashMap>();
-
- /**
- * Map that maps EClasses to their subclasses.
- *
- * @see #getAllSubEClasses(EClass)
- */
- private static Map> eClassToSubEClasses = new LinkedHashMap>();
-
- /**
- * Private constructor.
- */
- private ModelGeneratorUtil() {
- // all methods should be accessed in a static way
- }
-
- /**
- * Returns the EPackage to the specified nsURI.
- *
- * @param nsURI the NsUri of the EPackage to get
- * @return the EPackage belonging to nsURI
- * @see Registry#getEPackage(String)
- */
- public static EPackage getEPackage(String nsURI) {
- return EPackage.Registry.INSTANCE.getEPackage(nsURI);
- }
-
- /**
- * Returns all EPackages on the root level that are currently
- * registered in the registry.
- *
- * @return a Set of all root EPackages
- * @see Registry
- */
- public static Set getAllRootEPackages() {
- // were the root packages computed before?
- if(rootModelPackages != null) {
- return rootModelPackages;
- }
- rootModelPackages = new LinkedHashSet();
- Registry registry = EPackage.Registry.INSTANCE;
-
- for (Entry entry : registry.entrySet()) {
- EPackage ePackage = registry.getEPackage(entry.getKey());
- // is the current EPackage a root package?
- if (ePackage.getESuperPackage() == null){
- rootModelPackages.add(ePackage);
- }
- }
- return rootModelPackages;
- }
-
- /**
- * Retrieve all EClasses that are contained in ePackage.
- *
- * @param ePackage the package to get contained EClasses from
- * @return a set of EClasses contained in ePackage
- */
- public static List getAllEClasses(EPackage ePackage) {
- if(packageToModelElementEClasses.containsKey(ePackage)) {
- return packageToModelElementEClasses.get(ePackage);
- }
- if(ePackage == null) {
- packageToModelElementEClasses.put(ePackage, new LinkedList());
- return packageToModelElementEClasses.get(ePackage);
- }
- List result = new LinkedList();
- // obtain all EClasses from sub packages
- for(EPackage subPackage : ePackage.getESubpackages()) {
- result.addAll(getAllEClasses(subPackage));
- }
- // obtain all EClasses that are direct contents of the EPackage
- for(EClassifier classifier : ePackage.getEClassifiers()) {
- if(classifier instanceof EClass) {
- result.add((EClass) classifier);
- }
- }
- // save the result for upcoming method calls
- packageToModelElementEClasses.put(ePackage, result);
- return result;
- }
-
- /**
- * Iterates over all registered EPackages in order to retrieve all available
- * EClasses, excluding abstract classes and interfaces, and returns them as a Set.
- *
- * @return a set of all EClasses that are contained in registered EPackages
- * @see Registry
- */
- public static List getAllEClasses() {
- // were all EClasses computed before?
- if (allEClasses != null) {
- return allEClasses;
- }
- allEClasses = new LinkedList();
- Registry registry = EPackage.Registry.INSTANCE;
- // for all registered EPackages
- for (Entry entry : registry.entrySet()) {
- EPackage ePackage = registry.getEPackage(entry.getKey());
- for(EClass eClass : getAllEClasses(ePackage)) {
- // no abstracts or interfaces
- if(canHaveInstance(eClass)) {
- allEClasses.add(eClass);
- }
- }
- }
- return allEClasses;
- }
-
- /**
- * Returns all possible EClasses, excluding abstract classes and interfaces,
- * that can be contained when using reference.
- *
- * @param reference the EReference to get containable EClasses for
- * @return a set of all EClasses that can be contained when using reference
- */
- public static List getAllEContainments(EReference reference) {
- if(allEContainments.containsKey(reference)) {
- return allEContainments.get(reference);
- }
- if(reference == null) {
- allEContainments.put(reference, new LinkedList());
- return allEContainments.get(reference);
- }
- List result = new LinkedList();
- EClass referenceType = reference.getEReferenceType();
- // no abstracts or interfaces
- if(canHaveInstance(referenceType)) {
- result.add(referenceType);
- }
- // 'referenceType: EObject' allows all kinds of EObjects
- if(EcorePackage.eINSTANCE.getEObject().equals(referenceType)) {
- return getAllEClasses();
- }
- // all sub EClasses can be referenced as well
- result.addAll(getAllSubEClasses(referenceType));
- // save the result for upcoming method calls
- allEContainments.put(reference, result);
- return result;
- }
-
- /**
- * Returns whether eClass can be instantiated or not.
- * An EClass can be instantiated, if it is neither an interface nor abstract.
- *
- * @param eClass the EClass in question
- * @return whether eClass can be instantiated or not.
- */
- public static boolean canHaveInstance(EClass eClass) {
- return !eClass.isInterface() && !eClass.isAbstract();
- }
-
- /**
- * Returns all subclasses of an EClass, excluding abstract classes
- * and interfaces.
- *
- * @param eClass the EClass to get subclasses for
- * @return all subclasses of eClass
- */
- public static List getAllSubEClasses(EClass eClass) {
- if(eClassToSubEClasses.containsKey(eClass)) {
- return eClassToSubEClasses.get(eClass);
- }
- if(eClass == null) {
- eClassToSubEClasses.put(eClass, new LinkedList());
- return eClassToSubEClasses.get(eClass);
- }
- List allEClasses = getAllEClasses();
- List result = new LinkedList();
- for (EClass possibleSubClass : allEClasses) {
- // is the EClass really a subClass, while not being abstract or an interface?
- if (eClass.isSuperTypeOf(possibleSubClass) && canHaveInstance(possibleSubClass)) {
- result.add(possibleSubClass);
- }
- }
- // save the result for upcoming method calls
- eClassToSubEClasses.put(eClass, result);
- return result;
- }
-
- /**
- * Returns all containing references where parentClass is
- * the container and childClass the containment.
- *
- * @param childClass the EClass which shall be contained
- * @param parentClass the EClass to get containment references from
- * @return all possible container-references as a set
- */
- public static Set getAllPossibleContainingReferences(EClass childClass, EClass parentClass) {
- List allReferences = parentClass.getEAllContainments();
- Set result = new LinkedHashSet();
- for(EReference reference : allReferences) {
- EClass referenceType = reference.getEReferenceType();
- if(referenceType == null) {
- continue;
- }
- // is the reference type a perfect match?
- if(referenceType.equals(childClass)) {
- result.add(reference);
- // is the reference type either EObject or a super type?
- } else if (referenceType.equals(EcorePackage.eINSTANCE.getEObject())
- || referenceType.isSuperTypeOf(childClass)) {
- result.add(reference);
- }
- }
- return result;
- }
-
- /**
- * Returns all direct and indirect contents of rootObject as a map.
- * All EObjects that appear in these contents are mapped to their corresponding
- * EClass.
- *
- * @param rootObject the EObject to get contents for
- * @return all contents as a map from EClass to lists of EObjects
- */
- public static Map> getAllClassesAndObjects(EObject rootObject) {
- // initialize the computation process
- Map> result = new LinkedHashMap>();
- TreeIterator allContents = rootObject.eAllContents();
- List newList = new LinkedList();
- newList.add(rootObject);
- result.put(rootObject.eClass(), newList);
- // iterate over all direct and indirect contents
- while(allContents.hasNext()) {
- EObject eObject = allContents.next();
- // did this EObject's EClass appear before?
- if(result.containsKey(eObject.eClass())) {
- result.get(eObject.eClass()).add(eObject);
- } else {
- newList = new LinkedList();
- newList.add(eObject);
- result.put(eObject.eClass(), newList);
- }
- }
- return result;
- }
-
- /**
- * Returns all valid references for an EObject. This excludes container/containment references.
- * A reference is valid if it is neither derived nor volatile and if it is changeable and
- * either many-valued or not already set.
- *
- * @param eObject the EObject to get references for
- * @param exceptionLog the current log of exceptions
- * @param ignoreAndLog should exceptions be ignored and added to exceptionLog?
- * @return all valid references as a list
- */
- public static List getValidReferences(EObject eObject,
- Set exceptionLog, boolean ignoreAndLog) {
- List result = new LinkedList();
- for(EReference reference : eObject.eClass().getEAllReferences()) {
- if(!reference.isContainer() && !reference.isContainment() && isValid(reference, eObject, exceptionLog, ignoreAndLog)
- && (reference.isMany() || !eObject.eIsSet(reference))) {
- result.add(reference);
- }
- }
- return result;
- }
-
- /**
- * Returns whether an EStructuralFeature is valid for an EObject or not.
- * A reference is valid, if it can be set or added to.
- *
- * @param feature the EStructuralFeature in question
- * @param eObject the EObject to check the feature for
- * @param exceptionLog the current log of exceptions
- * @param ignoreAndLog should exceptions be ignored and added to exceptionLog?
- * @return if the feature can be set or added to
- */
- public static boolean isValid(EStructuralFeature feature, EObject eObject,
- Set exceptionLog, boolean ignoreAndLog) {
- boolean result = false;
- try {
- if(feature.isMany()) {
- // has the maximum amount of referenced objects been reached?
- Collection> referencedItems = (Collection>) eObject.eGet(feature);
- if(feature.getUpperBound() >= 0 && referencedItems.size() >= feature.getUpperBound()) {
- return false;
- }
- }
- // can the feature be changed reflectively?
- result = feature.isChangeable() && !feature.isVolatile() && !feature.isDerived();
- } catch(RuntimeException e) {
- handle(e, exceptionLog, ignoreAndLog);
- }
- return result;
- }
-
- /**
- * Handles exception, meaning it is thrown if ignoreAndLog
- * is false. Otherwise exception is ignored and added to
- * exceptionLog.
- *
- * @param exception the exception to handle
- * @param exceptionLog the current log of exceptions
- * @param ignoreAndLog should exceptions be ignored and added to exceptionLog?
- */
- private static void handle(RuntimeException exception, Set exceptionLog,
- boolean ignoreAndLog) {
- if(ignoreAndLog) {
- exceptionLog.add(exception);
- } else {
- throw exception;
- }
- }
-
- /**
- * Sets a feature between eObject and newValue
- * using a SetCommand. Exceptions are caught if ignoreAndLog is
- * true, otherwise a RuntimeException might be thrown if the command fails.
- *
- * @param eObject the EObject for which feature shall be set
- * @param feature the EStructuralFeature that shall be set
- * @param newValue the Object that shall be set as a feature in parentEObject
- * @param exceptionLog the current log of exceptions
- * @param ignoreAndLog should exceptions be ignored and added to exceptionLog?
- * @return newValue if the SetCommand was performed successful
- * or null if it failed
- * @see SetCommand
- */
- public static EObject setPerCommand(EObject eObject, EStructuralFeature feature, Object newValue,
- Set exceptionLog, boolean ignoreAndLog) {
- EditingDomain domain = AdapterFactoryEditingDomain.getEditingDomainFor(eObject);
- // no new value to set? -> unset the feature
- if(newValue==null) {
- newValue = SetCommand.UNSET_VALUE;
- }
- try {
- new SetCommand(domain, eObject, feature, newValue).doExecute();
- if(newValue instanceof EObject) {
- return (EObject) newValue;
- } else {
- return null;
- }
- } catch(RuntimeException e){
- handle(e, exceptionLog, ignoreAndLog);
- return null;
- }
- }
-
- /**
- * Adds newValue to the many-valued feature of
- * eObject using an AddCommand.
- * Exceptions are caught if ignoreAndLog is
- * true, otherwise a RuntimeException might be thrown if the command fails.
- *
- * @param eObject the EObject to which newObject shall be added
- * @param feature the EStructuralFeature that newObject shall be added to
- * @param newValue the Object that shall be added to feature
- * @param exceptionLog the current log of exceptions
- * @param ignoreAndLog should exceptions be ignored and added to exceptionLog?
- * @return newValue if the AddCommand was performed successful
- * or null if it failed
- * @see AddCommand#AddCommand(EditingDomain, EObject, EStructuralFeature, Object)
- */
- public static EObject addPerCommand(EObject eObject, EStructuralFeature feature, Object newValue,
- Set exceptionLog, boolean ignoreAndLog) {
- EditingDomain domain = AdapterFactoryEditingDomain.getEditingDomainFor(eObject);
- try {
- if(feature.isUnique() && ((Collection>) eObject.eGet(feature)).contains(newValue)) {
- // unique feature already contains object -> nothing to do
- return null;
- }
- new AddCommand(domain, eObject, feature, newValue).doExecute();
- if(newValue instanceof EObject) {
- return (EObject) newValue;
- } else {
- return null;
- }
- } catch(RuntimeException e){
- handle(e, exceptionLog, ignoreAndLog);
- return null;
- }
- }
-
- /**
- * Adds all objects to the many-valued feature of
- * eObject using an AddCommand.
- * Exceptions are caught if ignoreAndLog is
- * true, otherwise a RuntimeException might be thrown if the command fails.
- *
- * @param eObject the EObject to which objects shall be added
- * @param feature the EReference that objects shall be added to
- * @param objects collection of objects that shall be added to feature
- * @param exceptionLog the current log of exceptions
- * @param ignoreAndLog should exceptions be ignored and added to exceptionLog?
- */
- public static void addPerCommand(EObject eObject, EStructuralFeature feature, Collection> objects,
- Set exceptionLog, boolean ignoreAndLog) {
- EditingDomain domain = AdapterFactoryEditingDomain.getEditingDomainFor(eObject);
- try {
- for(Object object : objects) {
- if(feature.isUnique() && ((Collection>) eObject.eGet(feature)).contains(object)) {
- // object already exists in unique feature, don't add it again
- objects.remove(object);
- }
- }
- // no objects to add left
- if(objects.isEmpty()) {
- return;
- }
- new AddCommand(domain, eObject, feature, objects).doExecute();
- } catch(RuntimeException e) {
- handle(e, exceptionLog, ignoreAndLog);
- }
- }
-
- /**
- * Removes objects from a feature of eObject
- * using a RemoveCommand. Exceptions are caught if ignoreAndLog is
- * true, otherwise a RuntimeException might be thrown if the command fails.
- *
- * @param eObject the EObject to remove objects from
- * @param feature the EStructuralFeature objects shall be removed from
- * @param objects collection of Objects that shall be removed
- * @param exceptionLog the current log of exceptions
- * @param ignoreAndLog should exceptions be ignored and added to exceptionLog?
- * @see RemoveCommand
- */
- public static void removePerCommand(EObject eObject, EStructuralFeature feature, Collection> objects,
- Set exceptionLog, boolean ignoreAndLog) {
- EditingDomain domain = AdapterFactoryEditingDomain.getEditingDomainFor(eObject);
- try {
- new RemoveCommand(domain, eObject, feature, objects).doExecute();
- } catch(RuntimeException e){
- handle(e, exceptionLog, ignoreAndLog);
- }
- }
-
- /**
- * Retrieves all EClasses from allEClasses that can possibly be
- * referenced by reference and returns them as a list.
- *
- * @param reference the EReference to get EClasses for
- * @param allEClasses set of all possible EClasses
- * @return list of all EClasses that can be referenced by reference
- */
- public static Set getReferenceClasses(EReference reference, Set allEClasses) {
- Set result = new LinkedHashSet();
- EClass referenceType = reference.getEReferenceType();
- // 'referenceType: EObject' allows all kinds of EObjects
- if(referenceType.equals(EcorePackage.eINSTANCE.getEObject())) {
- return allEClasses;
- }
- for(EClass eClass : allEClasses) {
- // can eClass be referenced by reference
- if(referenceType.equals(eClass) || referenceType.isSuperTypeOf(eClass)) {
- result.add(eClass);
- }
- }
- return result;
- }
-
- /**
- * Sets or adds to a reference for an EObject with any generated instance
- * of referenceClass using SetCommand/AddCommand. If the reference is
- * not required, random decides whether the reference is set or how
- * many EObjects are added to it.
- *
- * @param eObject the EObject to set the reference for
- * @param referenceClass the EClass all referenced EObject shall be instances of
- * @param reference the reference to set
- * @param random the Random-object that randomizes EObjects and their amount
- * @param exceptionLog the current log of exceptions
- * @param ignoreAndLog should exceptions be ignored and added to exceptionLog?
- * @param allEObjects all existing EObjects mapped to their EClass
- *
- * @see #addPerCommand(EObject, EStructuralFeature, Collection, Set, boolean)
- * @see #addPerCommand(EObject, EStructuralFeature, Object, Set, boolean)
- * @see #setPerCommand(EObject, EStructuralFeature, Object, Set, boolean)
- */
- public static void setReference(EObject eObject, EClass referenceClass, EReference reference,
- Random random, Set exceptionLog, boolean ignoreAndLog, Map> allEObjects) {
- List possibleReferenceObjects = allEObjects.get(referenceClass);
- Collections.shuffle(possibleReferenceObjects, random);
- if(!possibleReferenceObjects.isEmpty()) {
- int index = 0;
- if(reference.isMany()) {
- int numberOfReferences = computeFeatureAmount(reference, random);
- for(int i = 0; i < numberOfReferences; i++) {
- ModelGeneratorUtil.addPerCommand(eObject, reference, possibleReferenceObjects.get(index),
- exceptionLog, ignoreAndLog);
- // ensures every EObject is set at most once
- if(++index==possibleReferenceObjects.size()) {
- break;
- }
- }
- //Change of referencing
- // Delete reference.isRequired() in order to set 0..1 references
- //} else if (reference.isRequired() || random.nextBoolean()){
- } else if (random.nextBoolean()) {
- ModelGeneratorUtil.setPerCommand(eObject, reference, possibleReferenceObjects.get(index),
- exceptionLog, ignoreAndLog);
- }
- }
- }
-
- /**
- * Sets all possible attributes of known types to random values using {@link IAttributeSetter}
- * and SetCommands/AddCommands.
- *
- * @param eObject the EObject to set attributes for
- * @param random the Random object used to determine the creation of attributes
- * @param exceptionLog the current log of exceptions
- * @param ignoreAndLog should exceptions be ignored and added to exceptionLog?
- * @see IAttributeSetter
- * @see AttributeHandler
- * @see #addPerCommand(EObject, EStructuralFeature, Collection, Set, boolean)
- * @see #addPerCommand(EObject, EStructuralFeature, Object, Set, boolean)
- * @see #setPerCommand(EObject, EStructuralFeature, Object, Set, boolean)
- */
- public static void setEObjectAttributes(EObject eObject, Random random,
- Set exceptionLog, boolean ignoreAndLog) {
- Map> attributeSetters = AttributeHandler.getAttributeSetters();
-
- for(EAttribute attribute : eObject.eClass().getEAllAttributes()) {
- EClassifier attributeType = attribute.getEAttributeType();
-
- if(!isValid(attribute, eObject, exceptionLog, ignoreAndLog)) {
- continue;
- }
-
- // the attribute setter used to create new attributes
- IAttributeSetter> attributeSetter = null;
-
- // is there a setter for this attribute?
- if(attributeSetters.containsKey(attributeType)) {
- attributeSetter = attributeSetters.get(attributeType);
- } else if(isEnum(attributeType)) {
- attributeSetter = AttributeHandler.getEEnumSetter((EEnum) attributeType);
- }
-
- // was there a fitting attribute setter?
- if(attributeSetter != null) {
- if (attribute.isMany()) {
- int numberOfAttributes = computeFeatureAmount(attribute, random);
- addPerCommand(eObject, attribute,
- attributeSetter.createNewAttributes(numberOfAttributes), exceptionLog, ignoreAndLog);
- } else {
- setPerCommand(eObject, attribute,
- attributeSetter.createNewAttribute(), exceptionLog, ignoreAndLog);
- }
- }
- }
- }
-
- /**
- * Returns whether attributeType is an instance of EEnum.
- *
- * @param attributeType the EClassifier in question
- * @return is attributeType an instance of EEnum?
- */
- private static boolean isEnum(EClassifier attributeType) {
- return EcorePackage.eINSTANCE.getEEnum().isInstance(attributeType);
- }
-
- /**
- * Computes the random amount of objects to add to a feature.
- *
- * @param feature the feature to compute the amount of objects for
- * @param random the Random object used to obtain random values
- * @return 1 if the feature is single valued,
- * a random value from 0 to 10 if the feature is many-valued and has no upper bound,
- * a random value between the feature's lower and upper bound otherwise
- */
- private static int computeFeatureAmount(EStructuralFeature feature, Random random) {
- if(!feature.isMany()) {
- return 1;
- }
- if(feature.getUpperBound() < feature.getLowerBound()) {
- return random.nextInt(10);
- }
- return feature.getLowerBound() + random.nextInt(feature.getUpperBound() - feature.getLowerBound() + 1);
- }
-
- /**
- * Deletes an EObject, while exceptions are handled with the values specified.
- *
- * @param eObject the EObject to delete
- * @param exceptionLog the current log of exceptions
- * @param ignoreAndLog should exceptions be ignored and added to exceptionLog?
- * @see EcoreUtil#delete(EObject)
- */
- public static void delete(EObject eObject, Set exceptionLog, boolean ignoreAndLog) {
- try {
- EcoreUtil.delete(eObject,true);
-
- } catch(RuntimeException e) {
- handle(e, exceptionLog, ignoreAndLog);
- }
- }
-}
+/**
+ * Copyright (c) 2008-2009 Jonas Helming, Maximilian Koegel. 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
+ */
+package org.eclipse.emf.emfstore.modelgenerator.common;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Random;
+import java.util.Set;
+
+import org.eclipse.emf.common.command.AbstractCommand;
+import org.eclipse.emf.common.util.TreeIterator;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EEnum;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EPackage.Registry;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.edit.command.AddCommand;
+import org.eclipse.emf.edit.command.RemoveCommand;
+import org.eclipse.emf.edit.command.SetCommand;
+import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.emf.emfstore.client.model.Configuration;
+import org.eclipse.emf.emfstore.modelgenerator.common.attribute.AttributeHandler;
+import org.eclipse.emf.emfstore.modelgenerator.common.attribute.IAttributeSetter;
+
+/**
+ * Utility class to generate and change Ecore models.
+ * All methods should be accessed in a static way,
+ * therefore the constructor is not visible.
+ */
+public final class ModelGeneratorUtil {
+
+ /**
+ * Set of all EClasses that are contained in EPackages that are
+ * currently registered in the EPackage registry.
+ *
+ * @see #getAllEClasses()
+ */
+ private static List allEClasses;
+
+ /**
+ * Set of all EPackages that are currently registered in the
+ * EPackage registry and not contained in any other package.
+ *
+ * @see #getAllRootEPackages()
+ */
+ private static Set rootModelPackages;
+
+ /**
+ * Map that maps EPackages to a set of all their contained EClasses.
+ *
+ * @see #getAllEClasses(EPackage)
+ */
+ private static Map> packageToModelElementEClasses = new LinkedHashMap>();
+
+ /**
+ * Map that maps EReferences to all possible EClasses that can be contained
+ * when using them.
+ *
+ * @see #getAllEContainments(EReference)
+ */
+ private static Map> allEContainments = new LinkedHashMap>();
+
+ /**
+ * Map that maps EClasses to their subclasses.
+ *
+ * @see #getAllSubEClasses(EClass)
+ */
+ private static Map> eClassToSubEClasses = new LinkedHashMap>();
+
+ /**
+ * Private constructor.
+ */
+ private ModelGeneratorUtil() {
+ // all methods should be accessed in a static way
+ }
+
+ /**
+ * Returns the EPackage to the specified nsURI.
+ *
+ * @param nsURI the NsUri of the EPackage to get
+ * @return the EPackage belonging to nsURI
+ * @see Registry#getEPackage(String)
+ */
+ public static EPackage getEPackage(String nsURI) {
+ return EPackage.Registry.INSTANCE.getEPackage(nsURI);
+ }
+
+ /**
+ * Returns all EPackages on the root level that are currently
+ * registered in the registry.
+ *
+ * @return a Set of all root EPackages
+ * @see Registry
+ */
+ public static Set getAllRootEPackages() {
+ // were the root packages computed before?
+ if(rootModelPackages != null) {
+ return rootModelPackages;
+ }
+ rootModelPackages = new LinkedHashSet();
+ Registry registry = EPackage.Registry.INSTANCE;
+
+ for (Entry entry : registry.entrySet()) {
+ EPackage ePackage = registry.getEPackage(entry.getKey());
+ // is the current EPackage a root package?
+ if (ePackage.getESuperPackage() == null){
+ rootModelPackages.add(ePackage);
+ }
+ }
+ return rootModelPackages;
+ }
+
+ /**
+ * Retrieve all EClasses that are contained in ePackage.
+ *
+ * @param ePackage the package to get contained EClasses from
+ * @return a set of EClasses contained in ePackage
+ */
+ public static List getAllEClasses(EPackage ePackage) {
+ if(packageToModelElementEClasses.containsKey(ePackage)) {
+ return packageToModelElementEClasses.get(ePackage);
+ }
+ if(ePackage == null) {
+ packageToModelElementEClasses.put(ePackage, new LinkedList());
+ return packageToModelElementEClasses.get(ePackage);
+ }
+ List result = new LinkedList();
+ // obtain all EClasses from sub packages
+ for(EPackage subPackage : ePackage.getESubpackages()) {
+ result.addAll(getAllEClasses(subPackage));
+ }
+ // obtain all EClasses that are direct contents of the EPackage
+ for(EClassifier classifier : ePackage.getEClassifiers()) {
+ if(classifier instanceof EClass) {
+ result.add((EClass) classifier);
+ }
+ }
+ // save the result for upcoming method calls
+ packageToModelElementEClasses.put(ePackage, result);
+ return result;
+ }
+
+ /**
+ * Iterates over all registered EPackages in order to retrieve all available
+ * EClasses, excluding abstract classes and interfaces, and returns them as a Set.
+ *
+ * @return a set of all EClasses that are contained in registered EPackages
+ * @see Registry
+ */
+ public static List getAllEClasses() {
+ // were all EClasses computed before?
+ if (allEClasses != null) {
+ return allEClasses;
+ }
+ allEClasses = new LinkedList();
+ Registry registry = EPackage.Registry.INSTANCE;
+ // for all registered EPackages
+ for (Entry entry : registry.entrySet()) {
+ EPackage ePackage = registry.getEPackage(entry.getKey());
+ for(EClass eClass : getAllEClasses(ePackage)) {
+ // no abstracts or interfaces
+ if(canHaveInstance(eClass)) {
+ allEClasses.add(eClass);
+ }
+ }
+ }
+ return allEClasses;
+ }
+
+ /**
+ * Returns all possible EClasses, excluding abstract classes and interfaces,
+ * that can be contained when using reference.
+ *
+ * @param reference the EReference to get containable EClasses for
+ * @return a set of all EClasses that can be contained when using reference
+ */
+ public static List getAllEContainments(EReference reference) {
+ if(allEContainments.containsKey(reference)) {
+ return allEContainments.get(reference);
+ }
+ if(reference == null) {
+ allEContainments.put(reference, new LinkedList());
+ return allEContainments.get(reference);
+ }
+ List result = new LinkedList();
+ EClass referenceType = reference.getEReferenceType();
+ // no abstracts or interfaces
+ if(canHaveInstance(referenceType)) {
+ result.add(referenceType);
+ }
+ // 'referenceType: EObject' allows all kinds of EObjects
+ if(EcorePackage.eINSTANCE.getEObject().equals(referenceType)) {
+ return getAllEClasses();
+ }
+ // all sub EClasses can be referenced as well
+ result.addAll(getAllSubEClasses(referenceType));
+ // save the result for upcoming method calls
+ allEContainments.put(reference, result);
+ return result;
+ }
+
+ /**
+ * Returns whether eClass can be instantiated or not.
+ * An EClass can be instantiated, if it is neither an interface nor abstract.
+ *
+ * @param eClass the EClass in question
+ * @return whether eClass can be instantiated or not.
+ */
+ public static boolean canHaveInstance(EClass eClass) {
+ return !eClass.isInterface() && !eClass.isAbstract();
+ }
+
+ /**
+ * Returns all subclasses of an EClass, excluding abstract classes
+ * and interfaces.
+ *
+ * @param eClass the EClass to get subclasses for
+ * @return all subclasses of eClass
+ */
+ public static List getAllSubEClasses(EClass eClass) {
+ if(eClassToSubEClasses.containsKey(eClass)) {
+ return eClassToSubEClasses.get(eClass);
+ }
+ if(eClass == null) {
+ eClassToSubEClasses.put(eClass, new LinkedList());
+ return eClassToSubEClasses.get(eClass);
+ }
+ List allEClasses = getAllEClasses();
+ List result = new LinkedList();
+ for (EClass possibleSubClass : allEClasses) {
+ // is the EClass really a subClass, while not being abstract or an interface?
+ if (eClass.isSuperTypeOf(possibleSubClass) && canHaveInstance(possibleSubClass)) {
+ result.add(possibleSubClass);
+ }
+ }
+ // save the result for upcoming method calls
+ eClassToSubEClasses.put(eClass, result);
+ return result;
+ }
+
+ /**
+ * Returns all containing references where parentClass is
+ * the container and childClass the containment.
+ *
+ * @param childClass the EClass which shall be contained
+ * @param parentClass the EClass to get containment references from
+ * @return all possible container-references as a set
+ */
+ public static Set getAllPossibleContainingReferences(EClass childClass, EClass parentClass) {
+ List allReferences = parentClass.getEAllContainments();
+ Set result = new LinkedHashSet();
+ for(EReference reference : allReferences) {
+ EClass referenceType = reference.getEReferenceType();
+ if(referenceType == null) {
+ continue;
+ }
+ // is the reference type a perfect match?
+ if(referenceType.equals(childClass)) {
+ result.add(reference);
+ // is the reference type either EObject or a super type?
+ } else if (referenceType.equals(EcorePackage.eINSTANCE.getEObject())
+ || referenceType.isSuperTypeOf(childClass)) {
+ result.add(reference);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns all direct and indirect contents of rootObject as a map.
+ * All EObjects that appear in these contents are mapped to their corresponding
+ * EClass.
+ *
+ * @param rootObject the EObject to get contents for
+ * @return all contents as a map from EClass to lists of EObjects
+ */
+ public static Map> getAllClassesAndObjects(EObject rootObject) {
+ // initialize the computation process
+ Map> result = new LinkedHashMap>();
+ TreeIterator allContents = rootObject.eAllContents();
+ List newList = new LinkedList();
+ newList.add(rootObject);
+ result.put(rootObject.eClass(), newList);
+ // iterate over all direct and indirect contents
+ while(allContents.hasNext()) {
+ EObject eObject = allContents.next();
+ // did this EObject's EClass appear before?
+ if(result.containsKey(eObject.eClass())) {
+ result.get(eObject.eClass()).add(eObject);
+ } else {
+ newList = new LinkedList();
+ newList.add(eObject);
+ result.put(eObject.eClass(), newList);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns all valid references for an EObject. This excludes container/containment references.
+ * A reference is valid if it is neither derived nor volatile and if it is changeable and
+ * either many-valued or not already set.
+ *
+ * @param eObject the EObject to get references for
+ * @param exceptionLog the current log of exceptions
+ * @param ignoreAndLog should exceptions be ignored and added to exceptionLog?
+ * @return all valid references as a list
+ */
+ public static List getValidReferences(EObject eObject,
+ Set exceptionLog, boolean ignoreAndLog) {
+ List result = new LinkedList();
+ for(EReference reference : eObject.eClass().getEAllReferences()) {
+ if(!reference.isContainer() && !reference.isContainment() && isValid(reference, eObject, exceptionLog, ignoreAndLog)
+ && (reference.isMany() || !eObject.eIsSet(reference))) {
+ result.add(reference);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns whether an EStructuralFeature is valid for an EObject or not.
+ * A reference is valid, if it can be set or added to.
+ *
+ * @param feature the EStructuralFeature in question
+ * @param eObject the EObject to check the feature for
+ * @param exceptionLog the current log of exceptions
+ * @param ignoreAndLog should exceptions be ignored and added to exceptionLog?
+ * @return if the feature can be set or added to
+ */
+ public static boolean isValid(EStructuralFeature feature, EObject eObject,
+ Set exceptionLog, boolean ignoreAndLog) {
+ boolean result = false;
+ try {
+ if(feature.isMany()) {
+ // has the maximum amount of referenced objects been reached?
+ Collection> referencedItems = (Collection>) eObject.eGet(feature);
+ if(feature.getUpperBound() >= 0 && referencedItems.size() >= feature.getUpperBound()) {
+ return false;
+ }
+ }
+ // can the feature be changed reflectively?
+ result = feature.isChangeable() && !feature.isVolatile() && !feature.isDerived();
+ } catch(RuntimeException e) {
+ handle(e, exceptionLog, ignoreAndLog);
+ }
+ return result;
+ }
+
+ /**
+ * Handles exception, meaning it is thrown if ignoreAndLog
+ * is false. Otherwise exception is ignored and added to
+ * exceptionLog.
+ *
+ * @param exception the exception to handle
+ * @param exceptionLog the current log of exceptions
+ * @param ignoreAndLog should exceptions be ignored and added to exceptionLog?
+ */
+ private static void handle(RuntimeException exception, Set exceptionLog,
+ boolean ignoreAndLog) {
+ if(ignoreAndLog) {
+ exceptionLog.add(exception);
+ } else {
+ throw exception;
+ }
+ }
+
+ /**
+ * Sets a feature between eObject and newValue
+ * using a SetCommand. Exceptions are caught if ignoreAndLog is
+ * true, otherwise a RuntimeException might be thrown if the command fails.
+ *
+ * @param eObject the EObject for which feature shall be set
+ * @param feature the EStructuralFeature that shall be set
+ * @param newValue the Object that shall be set as a feature in parentEObject
+ * @param exceptionLog the current log of exceptions
+ * @param ignoreAndLog should exceptions be ignored and added to exceptionLog?
+ * @return newValue if the SetCommand was performed successful
+ * or null if it failed
+ * @see SetCommand
+ */
+ public static EObject setPerCommand(EObject eObject, EStructuralFeature feature, Object newValue,
+ Set exceptionLog, boolean ignoreAndLog) {
+ EditingDomain domain = AdapterFactoryEditingDomain.getEditingDomainFor(eObject);
+ // no new value to set? -> unset the feature
+ if(newValue==null) {
+ newValue = SetCommand.UNSET_VALUE;
+ }
+ try {
+ new SetCommand(domain, eObject, feature, newValue).doExecute();
+ if(newValue instanceof EObject) {
+ return (EObject) newValue;
+ } else {
+ return null;
+ }
+ } catch(RuntimeException e){
+ handle(e, exceptionLog, ignoreAndLog);
+ return null;
+ }
+ }
+
+ /**
+ * Adds newValue to the many-valued feature of
+ * eObject using an AddCommand.
+ * Exceptions are caught if ignoreAndLog is
+ * true, otherwise a RuntimeException might be thrown if the command fails.
+ *
+ * @param eObject the EObject to which newObject shall be added
+ * @param feature the EStructuralFeature that newObject shall be added to
+ * @param newValue the Object that shall be added to feature
+ * @param exceptionLog the current log of exceptions
+ * @param ignoreAndLog should exceptions be ignored and added to exceptionLog?
+ * @return newValue if the AddCommand was performed successful
+ * or null if it failed
+ * @see AddCommand#AddCommand(EditingDomain, EObject, EStructuralFeature, Object)
+ */
+ public static EObject addPerCommand(EObject eObject, EStructuralFeature feature, Object newValue,
+ Set exceptionLog, boolean ignoreAndLog) {
+ EditingDomain domain = AdapterFactoryEditingDomain.getEditingDomainFor(eObject);
+ try {
+ if(feature.isUnique() && ((Collection>) eObject.eGet(feature)).contains(newValue)) {
+ // unique feature already contains object -> nothing to do
+ return null;
+ }
+ new AddCommand(domain, eObject, feature, newValue).doExecute();
+ if(newValue instanceof EObject) {
+ return (EObject) newValue;
+ } else {
+ return null;
+ }
+ } catch(RuntimeException e){
+ handle(e, exceptionLog, ignoreAndLog);
+ return null;
+ }
+ }
+
+ /**
+ * Adds all objects to the many-valued feature of
+ * eObject using an AddCommand.
+ * Exceptions are caught if ignoreAndLog is
+ * true, otherwise a RuntimeException might be thrown if the command fails.
+ *
+ * @param eObject the EObject to which objects shall be added
+ * @param feature the EReference that objects shall be added to
+ * @param objects collection of objects that shall be added to feature
+ * @param exceptionLog the current log of exceptions
+ * @param ignoreAndLog should exceptions be ignored and added to exceptionLog?
+ */
+ public static void addPerCommand(EObject eObject, EStructuralFeature feature, Collection> objects,
+ Set exceptionLog, boolean ignoreAndLog) {
+ EditingDomain domain = AdapterFactoryEditingDomain.getEditingDomainFor(eObject);
+ try {
+ for(Object object : objects) {
+ if(feature.isUnique() && ((Collection>) eObject.eGet(feature)).contains(object)) {
+ // object already exists in unique feature, don't add it again
+ objects.remove(object);
+ }
+ }
+ // no objects to add left
+ if(objects.isEmpty()) {
+ return;
+ }
+ new AddCommand(domain, eObject, feature, objects).doExecute();
+ } catch(RuntimeException e) {
+ handle(e, exceptionLog, ignoreAndLog);
+ }
+ }
+
+ /**
+ * Removes objects from a feature of eObject
+ * using a RemoveCommand. Exceptions are caught if ignoreAndLog is
+ * true, otherwise a RuntimeException might be thrown if the command fails.
+ *
+ * @param eObject the EObject to remove objects from
+ * @param feature the EStructuralFeature objects shall be removed from
+ * @param objects collection of Objects that shall be removed
+ * @param exceptionLog the current log of exceptions
+ * @param ignoreAndLog should exceptions be ignored and added to exceptionLog?
+ * @see RemoveCommand
+ */
+ public static void removePerCommand(EObject eObject, EStructuralFeature feature, Collection> objects,
+ Set exceptionLog, boolean ignoreAndLog) {
+ EditingDomain domain = AdapterFactoryEditingDomain.getEditingDomainFor(eObject);
+ try {
+ new RemoveCommand(domain, eObject, feature, objects).doExecute();
+ } catch(RuntimeException e){
+ handle(e, exceptionLog, ignoreAndLog);
+ }
+ }
+
+ /**
+ * Retrieves all EClasses from allEClasses that can possibly be
+ * referenced by reference and returns them as a list.
+ *
+ * @param reference the EReference to get EClasses for
+ * @param allEClasses set of all possible EClasses
+ * @return list of all EClasses that can be referenced by reference
+ */
+ public static Set getReferenceClasses(EReference reference, Set allEClasses) {
+ Set result = new LinkedHashSet();
+ EClass referenceType = reference.getEReferenceType();
+ // 'referenceType: EObject' allows all kinds of EObjects
+ if(referenceType.equals(EcorePackage.eINSTANCE.getEObject())) {
+ return allEClasses;
+ }
+ for(EClass eClass : allEClasses) {
+ // can eClass be referenced by reference
+ if(referenceType.equals(eClass) || referenceType.isSuperTypeOf(eClass)) {
+ result.add(eClass);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Sets or adds to a reference for an EObject with any generated instance
+ * of referenceClass using SetCommand/AddCommand. If the reference is
+ * not required, random decides whether the reference is set or how
+ * many EObjects are added to it.
+ *
+ * @param eObject the EObject to set the reference for
+ * @param referenceClass the EClass all referenced EObject shall be instances of
+ * @param reference the reference to set
+ * @param random the Random-object that randomizes EObjects and their amount
+ * @param exceptionLog the current log of exceptions
+ * @param ignoreAndLog should exceptions be ignored and added to exceptionLog?
+ * @param allEObjects all existing EObjects mapped to their EClass
+ *
+ * @see #addPerCommand(EObject, EStructuralFeature, Collection, Set, boolean)
+ * @see #addPerCommand(EObject, EStructuralFeature, Object, Set, boolean)
+ * @see #setPerCommand(EObject, EStructuralFeature, Object, Set, boolean)
+ */
+ public static void setReference(EObject eObject, EClass referenceClass, EReference reference,
+ Random random, Set exceptionLog, boolean ignoreAndLog, Map> allEObjects) {
+ List possibleReferenceObjects = allEObjects.get(referenceClass);
+ Collections.shuffle(possibleReferenceObjects, random);
+ if(!possibleReferenceObjects.isEmpty()) {
+ int index = 0;
+ if(reference.isMany()) {
+ int numberOfReferences = computeFeatureAmount(reference, random);
+ for(int i = 0; i < numberOfReferences; i++) {
+ ModelGeneratorUtil.addPerCommand(eObject, reference, possibleReferenceObjects.get(index),
+ exceptionLog, ignoreAndLog);
+ // ensures every EObject is set at most once
+ if(++index==possibleReferenceObjects.size()) {
+ break;
+ }
+ }
+ //Change of referencing
+ // Delete reference.isRequired() in order to set 0..1 references
+ //} else if (reference.isRequired() || random.nextBoolean()){
+ } else if (random.nextBoolean()) {
+ ModelGeneratorUtil.setPerCommand(eObject, reference, possibleReferenceObjects.get(index),
+ exceptionLog, ignoreAndLog);
+ }
+ }
+ }
+
+ /**
+ * Sets all possible attributes of known types to random values using {@link IAttributeSetter}
+ * and SetCommands/AddCommands.
+ *
+ * @param eObject the EObject to set attributes for
+ * @param random the Random object used to determine the creation of attributes
+ * @param exceptionLog the current log of exceptions
+ * @param ignoreAndLog should exceptions be ignored and added to exceptionLog?
+ * @see IAttributeSetter
+ * @see AttributeHandler
+ * @see #addPerCommand(EObject, EStructuralFeature, Collection, Set, boolean)
+ * @see #addPerCommand(EObject, EStructuralFeature, Object, Set, boolean)
+ * @see #setPerCommand(EObject, EStructuralFeature, Object, Set, boolean)
+ */
+ public static void setEObjectAttributes(EObject eObject, Random random,
+ Set exceptionLog, boolean ignoreAndLog) {
+ Map> attributeSetters = AttributeHandler.getAttributeSetters();
+
+ for(EAttribute attribute : eObject.eClass().getEAllAttributes()) {
+ EClassifier attributeType = attribute.getEAttributeType();
+
+ if(!isValid(attribute, eObject, exceptionLog, ignoreAndLog)) {
+ continue;
+ }
+
+ // the attribute setter used to create new attributes
+ IAttributeSetter> attributeSetter = null;
+
+ // is there a setter for this attribute?
+ if(attributeSetters.containsKey(attributeType)) {
+ attributeSetter = attributeSetters.get(attributeType);
+ } else if(isEnum(attributeType)) {
+ attributeSetter = AttributeHandler.getEEnumSetter((EEnum) attributeType);
+ }
+
+ // was there a fitting attribute setter?
+ if(attributeSetter != null) {
+ if (attribute.isMany()) {
+ int numberOfAttributes = computeFeatureAmount(attribute, random);
+ addPerCommand(eObject, attribute,
+ attributeSetter.createNewAttributes(numberOfAttributes), exceptionLog, ignoreAndLog);
+ } else {
+ setPerCommand(eObject, attribute,
+ attributeSetter.createNewAttribute(), exceptionLog, ignoreAndLog);
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns whether attributeType is an instance of EEnum.
+ *
+ * @param attributeType the EClassifier in question
+ * @return is attributeType an instance of EEnum?
+ */
+ private static boolean isEnum(EClassifier attributeType) {
+ return EcorePackage.eINSTANCE.getEEnum().isInstance(attributeType);
+ }
+
+ /**
+ * Computes the random amount of objects to add to a feature.
+ *
+ * @param feature the feature to compute the amount of objects for
+ * @param random the Random object used to obtain random values
+ * @return 1 if the feature is single valued,
+ * a random value from 0 to 10 if the feature is many-valued and has no upper bound,
+ * a random value between the feature's lower and upper bound otherwise
+ */
+ private static int computeFeatureAmount(EStructuralFeature feature, Random random) {
+ if(!feature.isMany()) {
+ return 1;
+ }
+ if(feature.getUpperBound() < feature.getLowerBound()) {
+ return random.nextInt(10);
+ }
+ return feature.getLowerBound() + random.nextInt(feature.getUpperBound() - feature.getLowerBound() + 1);
+ }
+
+ /**
+ * Deletes an EObject, while exceptions are handled with the values specified.
+ *
+ * @param eObject the EObject to delete
+ * @param exceptionLog the current log of exceptions
+ * @param ignoreAndLog should exceptions be ignored and added to exceptionLog?
+ * @see EcoreUtil#delete(EObject)
+ */
+ public static void delete(final EObject eObject, Set exceptionLog, boolean ignoreAndLog) {
+
+ Configuration.getEditingDomain().getCommandStack().execute(new AbstractCommand() {
+
+ @Override
+ public void redo() {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public void execute() {
+ EcoreUtil.delete(eObject, true);
+ }
+
+ @Override
+ public boolean canExecute() {
+ return true;
+ }
+ });
+ }
+}