| /** |
| ******************************************************************************** |
| * 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; |
| } |
| |
| } |