de.iteratec.iteraplan.businesslogic.service.ecore.MappedEPackage.java Source code

Java tutorial

Introduction

Here is the source code for de.iteratec.iteraplan.businesslogic.service.ecore.MappedEPackage.java

Source

/*
 * iteraplan is an IT Governance web application developed by iteratec, GmbH
 * Copyright (C) 2004 - 2014 iteratec, GmbH
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License version 3 as published by
 * the Free Software Foundation with the addition of the following permission
 * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
 * WORK IN WHICH THE COPYRIGHT IS OWNED BY ITERATEC, ITERATEC DISCLAIMS THE
 * WARRANTY OF NON INFRINGEMENT  OF THIRD PARTY RIGHTS.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, see http://www.gnu.org/licenses or write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301 USA.
 *
 * You can contact iteratec GmbH headquarters at Inselkammerstr. 4
 * 82008 Munich - Unterhaching, Germany, or at email address info@iteratec.de.
 *
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU Affero General Public License version 3.
 *
 * In accordance with Section 7(b) of the GNU Affero General Public License
 * version 3, these Appropriate Legal Notices must retain the display of the
 * "iteraplan" logo. If the display of the logo is not reasonably
 * feasible for technical reasons, the Appropriate Legal Notices must display
 * the words "Powered by iteraplan".
 */
package de.iteratec.iteraplan.businesslogic.service.ecore;

import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EEnum;
import org.eclipse.emf.ecore.EEnumLiteral;
import org.eclipse.emf.ecore.EFactory;
import org.eclipse.emf.ecore.ENamedElement;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;

import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.BiMap;
import com.google.common.collect.Collections2;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import de.iteratec.iteraplan.businesslogic.exchange.xmi.exporter.ecore.Iteraplan2EMFHelper;
import de.iteratec.iteraplan.model.BuildingBlockType;
import de.iteratec.iteraplan.model.attribute.AttributeType;
import de.iteratec.iteraplan.model.attribute.DateAT;
import de.iteratec.iteraplan.model.attribute.EnumAT;
import de.iteratec.iteraplan.model.attribute.EnumAV;
import de.iteratec.iteraplan.model.attribute.MultiassignementType;
import de.iteratec.iteraplan.model.attribute.NumberAT;
import de.iteratec.iteraplan.model.attribute.ResponsibilityAT;
import de.iteratec.iteraplan.model.attribute.TextAT;

@SuppressWarnings("PMD.TooManyMethods")
public class MappedEPackage implements EPackage {

    private EPackage wrapped;
    private BiMap<EStructuralFeature, AttributeTypeInBuildingBlockType> eSFtoAT;
    private BiMap<EnumAT, EEnum> atToEEnum;
    private BiMap<BuildingBlockType, EClass> bbToEClass;
    private ListMultimap<AttributeTypeInBuildingBlockType, String> atToAVStrings;
    private static Map<Class<? extends AttributeType>, EDataType> dataTypeMapping;

    static {
        dataTypeMapping = Maps.newHashMap();
        dataTypeMapping.put(TextAT.class, EcorePackage.eINSTANCE.getEString());
        dataTypeMapping.put(ResponsibilityAT.class, EcorePackage.eINSTANCE.getEString());
        dataTypeMapping.put(NumberAT.class, EcorePackage.eINSTANCE.getEBigDecimal());
        dataTypeMapping.put(DateAT.class, EcorePackage.eINSTANCE.getEDate());
    }

    static final class AttributeTypeInBuildingBlockType {
        private AttributeType at;
        private BuildingBlockType bt;

        protected AttributeTypeInBuildingBlockType(AttributeType at, BuildingBlockType bt) {
            this.at = at;
            this.bt = bt;
        }

        @Override
        public int hashCode() {
            return at.hashCode() ^ bt.hashCode();
        }

        @Override
        public boolean equals(Object obj) {
            if (obj instanceof AttributeTypeInBuildingBlockType) {
                AttributeTypeInBuildingBlockType casted = (AttributeTypeInBuildingBlockType) obj;
                return casted.at.equals(this.at) && casted.bt.equals(this.bt);
            } else {
                return false;
            }
        }

        public AttributeType getAt() {
            return at;
        }

        public BuildingBlockType getBt() {
            return bt;
        }
    }

    public MappedEPackage(EPackage wrapped) {
        this.eSFtoAT = HashBiMap.create();
        this.atToEEnum = HashBiMap.create();
        this.bbToEClass = HashBiMap.create();
        this.atToAVStrings = LinkedListMultimap.create();
        this.wrapped = wrapped;
    }

    public MappedEPackage createCopy(Predicate<ENamedElement> filter) {
        return new MappingEPackageCopier().copy(this, filter);
    }

    public MappedEPackage createCopy() {
        Predicate<ENamedElement> filter = Predicates.alwaysTrue();
        return new MappingEPackageCopier().copy(this, filter);
    }

    public List<String> getAttributeValueStrings(EStructuralFeature eStructuralFeature) {
        List<String> result = Lists.newLinkedList();
        if (this.eSFtoAT.containsKey(eStructuralFeature)) {
            AttributeTypeInBuildingBlockType atInBt = this.eSFtoAT.get(eStructuralFeature);
            if (this.atToAVStrings.containsKey(atInBt)) {
                result.addAll(this.atToAVStrings.get(atInBt));
            }
            if (this.atToEEnum.containsKey(atInBt.getAt())) {
                for (EEnumLiteral eLit : this.atToEEnum.get(atInBt.getAt()).getELiterals()) {
                    result.add(eLit.getName());
                }
            }
        }

        return result;
    }

    public boolean isExtended(EStructuralFeature eStructuralFeature) {
        return this.eSFtoAT.containsKey(eStructuralFeature);
    }

    public AttributeType getAttributeType(EStructuralFeature eStructuralFeature) {
        return this.eSFtoAT.get(eStructuralFeature) == null ? null : this.eSFtoAT.get(eStructuralFeature).getAt();
    }

    public EStructuralFeature getEStructuralFeature(AttributeType attributeType,
            BuildingBlockType buildingBlockType) {
        return this.eSFtoAT.inverse().get(new AttributeTypeInBuildingBlockType(attributeType, buildingBlockType));
    }

    public EnumAT getEnumerationAttributeType(EEnum eEnum) {
        return this.atToEEnum.inverse().get(eEnum);
    }

    public EEnum getEEnum(EnumAT enumAT) {
        return this.atToEEnum.get(enumAT);
    }

    final void createNewEAttribute(EnumAT at, List<EnumAV> avs, BuildingBlockType bt) {
        AttributeTypeInBuildingBlockType atInBt = new AttributeTypeInBuildingBlockType(at, bt);
        createEAttribute(atInBt).setEType(forceGetEEnum(at, avs));
    }

    final void createNewEAttribute(AttributeType at, List<String> avRanges, BuildingBlockType bt) {
        AttributeTypeInBuildingBlockType atInBt = new AttributeTypeInBuildingBlockType(at, bt);
        createEAttribute(atInBt).setEType(dataTypeMapping.get(at.getClass()));
        this.atToAVStrings.putAll(atInBt, avRanges);
    }

    private EAttribute createEAttribute(AttributeTypeInBuildingBlockType atInBt) {
        EAttribute eAtt = EcoreFactory.eINSTANCE.createEAttribute();
        Iteraplan2EMFHelper.setName(eAtt, atInBt.getAt().getName());
        eAtt.setLowerBound(atInBt.getAt().isMandatory() ? 1 : 0);
        eAtt.setUnique(false);

        if (atInBt.getAt() instanceof MultiassignementType) {
            eAtt.setUpperBound(((MultiassignementType) atInBt.getAt()).isMultiassignmenttype()
                    ? EStructuralFeature.UNBOUNDED_MULTIPLICITY
                    : 1);
        } else {
            eAtt.setUpperBound(1);
        }
        getEClass(atInBt.getBt()).getEStructuralFeatures().add(eAtt);
        this.eSFtoAT.put(eAtt, atInBt);
        return eAtt;
    }

    private EEnum forceGetEEnum(EnumAT enumAT, List<EnumAV> avs) {
        if (getEEnum(enumAT) == null) {
            EEnum newEEnum = EcoreFactory.eINSTANCE.createEEnum();
            Iteraplan2EMFHelper.setName(newEEnum, enumAT.getName());

            EEnumLiteral undefined = EcoreFactory.eINSTANCE.createEEnumLiteral();
            undefined.setValue(0);
            undefined.setLiteral("-");
            undefined.setName("UNDEFINED");
            newEEnum.getELiterals().add(undefined);
            int count = 1;
            for (EnumAV av : avs) {
                if (av != null) {
                    EEnumLiteral eLiteral = EcoreFactory.eINSTANCE.createEEnumLiteral();
                    Iteraplan2EMFHelper.setName(eLiteral, av.getName());
                    eLiteral.setValue(count);
                    eLiteral.setLiteral(av.getValue());
                    newEEnum.getELiterals().add(eLiteral);
                    count++;
                }
            }
            this.wrapped.getEClassifiers().add(newEEnum);
            this.atToEEnum.put(enumAT, newEEnum);
        }
        return getEEnum(enumAT);
    }

    public EClass getEClass(BuildingBlockType buildingBlockType) {
        if (!this.bbToEClass.containsKey(buildingBlockType)) {
            EClassifier eClassifier = this.wrapped.getEClassifier(
                    buildingBlockType.getTypeOfBuildingBlock().getAssociatedClass().getSimpleName());
            if (eClassifier instanceof EClass) {
                this.bbToEClass.put(buildingBlockType, (EClass) eClassifier);
            }
        }
        return this.bbToEClass.get(buildingBlockType);
    }

    /*private static final void addSerializationAnnotation(ENamedElement eNamedElement) {
      EcoreUtil.setAnnotation(eNamedElement, ExtendedMetaData.ANNOTATION_URI, "name", eNamedElement.getName().replaceAll("[^\\w]", "_"));
    }*/

    /**
     * @see org.eclipse.emf.common.notify.Notifier#eAdapters()
     */
    public EList<Adapter> eAdapters() {
        return wrapped.eAdapters();
    }

    /**
     * @see org.eclipse.emf.ecore.EObject#eClass()
     */
    public EClass eClass() {
        return wrapped.eClass();
    }

    /**
     * @see org.eclipse.emf.ecore.EObject#eResource()
     */
    public Resource eResource() {
        return wrapped.eResource();
    }

    /**
     * @see org.eclipse.emf.ecore.EObject#eContainer()
     */
    public EObject eContainer() {
        return wrapped.eContainer();
    }

    /**
     * @see org.eclipse.emf.ecore.EObject#eContainingFeature()
     */
    public EStructuralFeature eContainingFeature() {
        return wrapped.eContainingFeature();
    }

    /**
     * @see org.eclipse.emf.ecore.EObject#eContainmentFeature()
     */
    public EReference eContainmentFeature() {
        return wrapped.eContainmentFeature();
    }

    /**
     * @see org.eclipse.emf.ecore.EObject#eContents()
     */
    public EList<EObject> eContents() {
        return wrapped.eContents();
    }

    /**
     * @see org.eclipse.emf.ecore.EObject#eAllContents()
     */
    public TreeIterator<EObject> eAllContents() {
        return wrapped.eAllContents();
    }

    /**
     * @see org.eclipse.emf.ecore.EObject#eCrossReferences()
     */
    public EList<EObject> eCrossReferences() {
        return wrapped.eCrossReferences();
    }

    /**
     * @see org.eclipse.emf.common.notify.Notifier#eDeliver()
     */
    public boolean eDeliver() {
        return wrapped.eDeliver();
    }

    /**
     * @see org.eclipse.emf.ecore.EObject#eIsProxy()
     */
    public boolean eIsProxy() {
        return wrapped.eIsProxy();
    }

    /**
     * @see org.eclipse.emf.ecore.EObject#eGet(org.eclipse.emf.ecore.EStructuralFeature)
     */
    public Object eGet(EStructuralFeature feature) {
        return wrapped.eGet(feature);
    }

    /**
     * @see org.eclipse.emf.ecore.EObject#eGet(org.eclipse.emf.ecore.EStructuralFeature, boolean)
     */
    public Object eGet(EStructuralFeature feature, boolean resolve) {
        return wrapped.eGet(feature, resolve);
    }

    /**
     * @see org.eclipse.emf.ecore.EObject#eSet(org.eclipse.emf.ecore.EStructuralFeature, java.lang.Object)
     */
    public void eSet(EStructuralFeature feature, Object newValue) {
        wrapped.eSet(feature, newValue);
    }

    /**
     * @see org.eclipse.emf.ecore.EObject#eIsSet(org.eclipse.emf.ecore.EStructuralFeature)
     */
    public boolean eIsSet(EStructuralFeature feature) {
        return wrapped.eIsSet(feature);
    }

    /**
     * @see org.eclipse.emf.ecore.EObject#eInvoke(org.eclipse.emf.ecore.EOperation, org.eclipse.emf.common.util.EList)
     */
    public Object eInvoke(EOperation operation, EList<?> arguments) throws InvocationTargetException {
        return wrapped.eInvoke(operation, arguments);
    }

    /**
     * @see org.eclipse.emf.common.notify.Notifier#eNotify(org.eclipse.emf.common.notify.Notification)
     */
    public void eNotify(Notification arg0) {
        wrapped.eNotify(arg0);
    }

    /**
     * @see org.eclipse.emf.common.notify.Notifier#eSetDeliver(boolean)
     */
    public void eSetDeliver(boolean arg0) {
        wrapped.eSetDeliver(arg0);
    }

    /**
     * @see org.eclipse.emf.ecore.EModelElement#getEAnnotations()
     */
    public EList<EAnnotation> getEAnnotations() {
        return wrapped.getEAnnotations();
    }

    /**
     * @see org.eclipse.emf.ecore.ENamedElement#getName()
     */
    public String getName() {
        return wrapped.getName();
    }

    /**
     * @see org.eclipse.emf.ecore.ENamedElement#setName(java.lang.String)
     */
    public void setName(String value) {
        wrapped.setName(value);
    }

    /**
     * @see org.eclipse.emf.ecore.EModelElement#getEAnnotation(java.lang.String)
     */
    public EAnnotation getEAnnotation(String source) {
        return wrapped.getEAnnotation(source);
    }

    /**
     * @see org.eclipse.emf.ecore.EPackage#getNsURI()
     */
    public String getNsURI() {
        return wrapped.getNsURI();
    }

    /**
     * @see org.eclipse.emf.ecore.EPackage#setNsURI(java.lang.String)
     */
    public void setNsURI(String value) {
        wrapped.setNsURI(value);
    }

    /**
     * @see org.eclipse.emf.ecore.EPackage#getNsPrefix()
     */
    public String getNsPrefix() {
        return wrapped.getNsPrefix();
    }

    /**
     * @see org.eclipse.emf.ecore.EPackage#setNsPrefix(java.lang.String)
     */
    public void setNsPrefix(String value) {
        wrapped.setNsPrefix(value);
    }

    /**
     * @see org.eclipse.emf.ecore.EPackage#getEFactoryInstance()
     */
    public EFactory getEFactoryInstance() {
        return wrapped.getEFactoryInstance();
    }

    /**
     * @see org.eclipse.emf.ecore.EPackage#setEFactoryInstance(org.eclipse.emf.ecore.EFactory)
     */
    public void setEFactoryInstance(EFactory value) {
        wrapped.setEFactoryInstance(value);
    }

    /**
     * @see org.eclipse.emf.ecore.EPackage#getEClassifiers()
     */
    public EList<EClassifier> getEClassifiers() {
        return wrapped.getEClassifiers();
    }

    /**
     * @see org.eclipse.emf.ecore.EPackage#getESubpackages()
     */
    public EList<EPackage> getESubpackages() {
        return wrapped.getESubpackages();
    }

    /**
     * @see org.eclipse.emf.ecore.EPackage#getESuperPackage()
     */
    public EPackage getESuperPackage() {
        return wrapped.getESuperPackage();
    }

    /**
     * @see org.eclipse.emf.ecore.EPackage#getEClassifier(java.lang.String)
     */
    public EClassifier getEClassifier(String name) {
        return wrapped.getEClassifier(name);
    }

    /**
     * @see org.eclipse.emf.ecore.EObject#eUnset(org.eclipse.emf.ecore.EStructuralFeature)
     */
    public void eUnset(EStructuralFeature feature) {
        wrapped.eUnset(feature);
    }

    private static class MappingEPackageCopier {
        private BiMap<ENamedElement, ENamedElement> orig2copy;

        MappingEPackageCopier() {
            this.orig2copy = HashBiMap.create();
        }

        MappedEPackage copy(MappedEPackage oldEPackage, Predicate<ENamedElement> filter) {
            EPackage newEPackage = EcoreFactory.eINSTANCE.createEPackage();
            MappedEPackage result = new MappedEPackage(newEPackage);
            newEPackage.setName(oldEPackage.getName());
            newEPackage.setNsPrefix(oldEPackage.getNsPrefix());
            newEPackage.setNsURI(oldEPackage.getNsURI());

            copyAllEDataTypes(oldEPackage, result, filter);

            for (EClassifier oldEClassifier : Collections2.filter(oldEPackage.getEClassifiers(),
                    eClassAnd(filter))) {
                EClass oldEClass = (EClass) oldEClassifier;
                EClass newEClass = copyEClassifier(oldEClass);
                newEPackage.getEClassifiers().add(newEClass);
                result.bbToEClass.put(oldEPackage.bbToEClass.inverse().get(oldEClass), newEClass);
                newEClass.getEStructuralFeatures().clear();
                for (EAttribute oldEAttribute : Collections2.filter(oldEClass.getEAttributes(), filter)) {
                    EAttribute newEAttribute = copyEStructuralFeature(oldEAttribute);
                    if (newEAttribute != null) {
                        if (oldEPackage.eSFtoAT.containsKey(oldEAttribute)) {
                            result.eSFtoAT.put(newEAttribute, oldEPackage.eSFtoAT.get(oldEAttribute));
                        }
                        newEClass.getEStructuralFeatures().add(newEAttribute);
                    }
                }
            }
            for (EClassifier oldEClassifier : Collections2.filter(oldEPackage.getEClassifiers(),
                    eClassAnd(filter))) {
                EClass oldEClass = (EClass) oldEClassifier;
                EClass newEClass = (EClass) this.orig2copy.get(oldEClass);
                for (EClass oldSuperEClass : Collections2.filter(oldEClass.getESuperTypes(), filter)) {
                    newEClass.getESuperTypes().add((EClass) this.orig2copy.get(oldSuperEClass));
                }
                for (EReference oldEReference : Collections2.filter(oldEClass.getEReferences(), filter)) {
                    EReference newEReference = copyEStructuralFeature(oldEReference);
                    if (newEReference != null) {
                        if (oldEPackage.eSFtoAT.containsKey(oldEReference)) {
                            result.eSFtoAT.put(newEReference, oldEPackage.eSFtoAT.get(oldEReference));
                        }
                        newEClass.getEStructuralFeatures().add(newEReference);
                    }
                }
            }
            result.atToAVStrings.putAll(oldEPackage.atToAVStrings);

            return result;
        }

        private void copyAllEDataTypes(MappedEPackage oldEPackage, MappedEPackage result,
                Predicate<ENamedElement> filter) {
            for (EClassifier oldEClassifier : Collections2.filter(oldEPackage.getEClassifiers(),
                    eDataTypeAnd(filter))) {
                EClassifier newEClassifier = copyEClassifier(oldEClassifier);
                result.getEFactoryInstance().getEPackage().getEClassifiers().add(newEClassifier);
                if (oldEClassifier instanceof EEnum) {
                    EEnum oldEEnum = (EEnum) oldEClassifier;
                    if (oldEPackage.atToEEnum.containsValue(oldEClassifier)) {
                        result.atToEEnum.put(oldEPackage.atToEEnum.inverse().get(oldEEnum), (EEnum) newEClassifier);
                    }
                }
            }
        }

        private <T extends EStructuralFeature> T copyEStructuralFeature(T oldEStructuralFeature) {
            T newEStructuralFeature = EcoreUtil.copy(oldEStructuralFeature);
            if (this.orig2copy.containsKey(oldEStructuralFeature.getEType())) {
                newEStructuralFeature.setEType((EClassifier) this.orig2copy.get(oldEStructuralFeature.getEType()));
            } else if (oldEStructuralFeature.getEType() instanceof EDataType) {
                newEStructuralFeature.setEType(oldEStructuralFeature.getEType());
            } else {
                return null;
            }
            if (oldEStructuralFeature instanceof EReference) {
                EReference oldEReference = (EReference) oldEStructuralFeature;
                if (this.orig2copy.containsKey(oldEReference.getEOpposite())) {
                    ((EReference) newEStructuralFeature)
                            .setEOpposite((EReference) this.orig2copy.get(oldEReference.getEOpposite()));
                }
            }

            this.orig2copy.put(oldEStructuralFeature, newEStructuralFeature);
            return newEStructuralFeature;
        }

        private <T extends EClassifier> T copyEClassifier(T oldEClassifier) {
            T newEClassifier = EcoreUtil.copy(oldEClassifier);
            if (oldEClassifier instanceof EEnum) {
                ((EEnum) newEClassifier).getELiterals().clear();
                for (EEnumLiteral oldELiteral : ((EEnum) oldEClassifier).getELiterals()) {
                    EEnumLiteral newELiteral = EcoreUtil.copy(oldELiteral);
                    this.orig2copy.put(oldELiteral, newELiteral);
                }
            }
            this.orig2copy.put(oldEClassifier, newEClassifier);
            return newEClassifier;
        }

        private static Predicate<ENamedElement> eDataTypeAnd(Predicate<ENamedElement> filter) {
            return Predicates.and(new Predicate<ENamedElement>() {
                public boolean apply(ENamedElement arg0) {
                    return arg0 instanceof EDataType;
                }
            }, filter);
        }

        private static Predicate<ENamedElement> eClassAnd(Predicate<ENamedElement> filter) {
            return Predicates.and(new Predicate<ENamedElement>() {
                public boolean apply(ENamedElement arg0) {
                    return arg0 instanceof EClass;
                }
            }, filter);
        }
    }
}