/**
* <copyright>
* </copyright>
*
*
*/
package org.dresdenocl.language.ocl.resource.ocl.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
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.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
/**
* A helper class that is able to create minimal model instances for Ecore models.
*/
public class OclMinimalModelHelper {
private final static org.dresdenocl.language.ocl.resource.ocl.util.OclEClassUtil eClassUtil = new org.dresdenocl.language.ocl.resource.ocl.util.OclEClassUtil();
public EObject getMinimalModel(EClass eClass, Collection<EClass> allAvailableClasses) {
return getMinimalModel(eClass, allAvailableClasses.toArray(new EClass[allAvailableClasses.size()]), null);
}
public EObject getMinimalModel(EClass eClass, EClass[] allAvailableClasses) {
return getMinimalModel(eClass, allAvailableClasses, null);
}
public EObject getMinimalModel(EClass eClass, EClass[] allAvailableClasses, String name) {
if (!contains(allAvailableClasses, eClass)) {
return null;
}
EPackage ePackage = eClass.getEPackage();
if (ePackage == null) {
return null;
}
EObject root = ePackage.getEFactoryInstance().create(eClass);
List<EStructuralFeature> features = eClass.getEAllStructuralFeatures();
for (EStructuralFeature feature : features) {
if (feature instanceof EReference) {
EReference reference = (EReference) feature;
if (reference.isUnsettable()) {
continue;
}
if (!reference.isChangeable()) {
continue;
}
EClassifier type = reference.getEType();
if (type instanceof EClass) {
EClass typeClass = (EClass) type;
if (eClassUtil.isNotConcrete(typeClass)) {
// find subclasses
List<EClass> subClasses = eClassUtil.getSubClasses(typeClass, allAvailableClasses);
if (subClasses.size() == 0) {
continue;
} else {
// pick the first subclass
typeClass = subClasses.get(0);
}
}
int lowerBound = reference.getLowerBound();
for (int i = 0; i < lowerBound; i++) {
EObject subModel = null;
if (reference.isContainment()) {
EClass[] unusedClasses = getArraySubset(allAvailableClasses, eClass);
subModel = getMinimalModel(typeClass, unusedClasses);
}
else {
subModel = typeClass.getEPackage().getEFactoryInstance().create(typeClass);
// set some proxy URI to make this object a proxy
String initialValue = "#some" + org.dresdenocl.language.ocl.resource.ocl.util.OclStringUtil.capitalize(typeClass.getName());
URI proxyURI = URI.createURI(initialValue);
((InternalEObject) subModel).eSetProxyURI(proxyURI);
}
if (subModel == null) {
continue;
}
Object value = root.eGet(reference);
if (value instanceof List<?>) {
List<EObject> list = org.dresdenocl.language.ocl.resource.ocl.util.OclListUtil.castListUnchecked(value);
list.add(subModel);
} else {
root.eSet(reference, subModel);
}
}
}
} else if (feature instanceof EAttribute) {
EAttribute attribute = (EAttribute) feature;
if ("EString".equals(attribute.getEType().getName())) {
String initialValue;
if (attribute.getName().equals("name") && name != null) {
initialValue = name;
}
else {
initialValue = "some" + org.dresdenocl.language.ocl.resource.ocl.util.OclStringUtil.capitalize(attribute.getName());
}
Object value = root.eGet(attribute);
if (value instanceof List<?>) {
List<String> list = org.dresdenocl.language.ocl.resource.ocl.util.OclListUtil.castListUnchecked(value);
list.add(initialValue);
} else {
root.eSet(attribute, initialValue);
}
}
}
}
return root;
}
private boolean contains(EClass[] allAvailableClasses, EClass eClass) {
for (EClass nextClass : allAvailableClasses) {
if (eClass == nextClass) {
return true;
}
}
return false;
}
private EClass[] getArraySubset(EClass[] allClasses, EClass eClassToRemove) {
List<EClass> subset = new ArrayList<EClass>();
for (EClass eClass : allClasses) {
if (eClass != eClassToRemove) {
subset.add(eClass);
}
}
return subset.toArray(new EClass[subset.size()]);
}
}