blob: d11c1e817ebe38c278b680e01bd693ba9a7aaaf4 [file] [log] [blame]
/**
********************************************************************************
* Copyright (c) 2020 Eclipse APP4MC contributors.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
********************************************************************************
*/
package org.eclipse.app4mc.amalthea._import.atdb;
import java.util.AbstractMap.SimpleEntry;
import java.util.Arrays;
import java.util.List;
import java.util.Map.Entry;
import java.util.stream.Stream;
import org.eclipse.app4mc.amalthea.model.AmaltheaIndex;
import org.eclipse.app4mc.amalthea.model.INamed;
import org.eclipse.app4mc.amalthea.model.IReferable;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.util.EcoreUtil;
enum AmaltheaModelUtil {;
static <T extends INamed> T getOrAddNew(final EObject amEObject, final EReference referenceFeature,
final String name, final Class<T> clazz) {
return getOrAddNew(amEObject, referenceFeature, name, clazz, referenceFeature.getEReferenceType());
}
static <T extends INamed> T getOrAddNew(final EObject amEObject, final EReference referenceFeature,
final String name, final Class<T> clazz, final EClass eClazz) {
@SuppressWarnings("unchecked")
final List<T> values = referenceFeature.isMany()
? (List<T>) amEObject.eGet(referenceFeature)
: Arrays.asList(clazz.cast(amEObject.eGet(referenceFeature)));
final T value = values.stream().filter(p -> p.getName().equals(name)).findFirst().orElseGet(() -> {
T ret;
if (referenceFeature.isContainment()) {
ret = clazz.cast(EcoreUtil.create(eClazz));
ret.setName(name);
} else {
if (IReferable.class.isAssignableFrom(clazz)) {
ret = AmaltheaIndex.getElements(amEObject, name, clazz).stream().findFirst().orElse(null);
} else {
throw new IllegalArgumentException("For a reference the type must extend IReferable, but you gave me: " + clazz);
}
}
if (ret != null) {
if (referenceFeature.isMany()) {
values.add(ret);
} else {
amEObject.eSet(referenceFeature, ret);
}
}
return ret;
});
return value;
}
static <C extends EObject, T extends INamed> Entry<C, T> getOrAddNewWithContainer(final EObject eObject,
final EReference containerFeature, final Class<C> cClazz, final EClass cEClazz,
final EReference referenceFeature, final Class<T> rClazz, final EClass rEClazz, final String name) {
@SuppressWarnings("unchecked")
final Stream<C> allContainers = (containerFeature.isMany()
? ((List<C>) eObject.eGet(containerFeature)).stream()
: Stream.of(cClazz.cast(eObject.eGet(containerFeature)))
).filter(cClazz::isInstance);
@SuppressWarnings("unchecked")
final Stream<Entry<C, T>> allValues = allContainers.flatMap(containerEObject -> (referenceFeature.isMany()
? ((List<T>) containerEObject.eGet(referenceFeature)).stream().map(ref -> new SimpleEntry<>(containerEObject, ref))
: Stream.of(new SimpleEntry<>(containerEObject, rClazz.cast(containerEObject.eGet(referenceFeature))))
));
final Entry<C, T> value = allValues.filter(p -> rClazz.isInstance(p.getValue()) && p.getValue().getName().equals(name))
.findFirst().orElseGet(() -> {
T ret;
if (referenceFeature.isContainment()) {
ret = rClazz.cast(EcoreUtil.create(rEClazz));
ret.setName(name);
} else {
if (IReferable.class.isAssignableFrom(rClazz)) {
ret = AmaltheaIndex.getElements(eObject, name, rClazz).stream().findFirst().orElse(null);
} else {
throw new IllegalArgumentException("For a reference the type must extend IReferable, but you gave me: " + rClazz);
}
}
if (ret != null) {
// create and fill new container
final C containerEObject = cClazz.cast(EcoreUtil.create(cEClazz));
if (referenceFeature.isMany()) {
@SuppressWarnings("unchecked")
final List<T> values = (List<T>)containerEObject.eGet(referenceFeature);
values.add(ret);
} else {
containerEObject.eSet(referenceFeature, ret);
}
// add container to eObject
if (containerFeature.isMany()) {
@SuppressWarnings("unchecked")
final List<C> values = (List<C>)eObject.eGet(containerFeature);
values.add(containerEObject);
} else {
eObject.eSet(containerFeature, containerEObject);
}
return new SimpleEntry<>(containerEObject, ret);
}
return null;
});
return value;
}
}