de.iteratec.iteraplan.businesslogic.exchange.xmi.exporter.XmiServiceForTabReporting.java Source code

Java tutorial

Introduction

Here is the source code for de.iteratec.iteraplan.businesslogic.exchange.xmi.exporter.XmiServiceForTabReporting.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.exchange.xmi.exporter;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang.StringUtils;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.common.util.UniqueEList;
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.EEnumLiteral;
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.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.ExtendedMetaData;
import org.eclipse.emf.ecore.xmi.XMIResource;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.emf.ecore.xmi.impl.EcoreResourceFactoryImpl;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import de.iteratec.iteraplan.businesslogic.exchange.xmi.exporter.ecore.EcoreServiceForTabReporting;
import de.iteratec.iteraplan.businesslogic.exchange.xmi.exporter.ecore.Iteraplan2EMFHelper;
import de.iteratec.iteraplan.businesslogic.exchange.xmi.exporter.ecore.TabReportingEcoreData;
import de.iteratec.iteraplan.common.Logger;
import de.iteratec.iteraplan.common.UserContext;
import de.iteratec.iteraplan.common.error.IteraplanBusinessException;
import de.iteratec.iteraplan.common.error.IteraplanErrorMessages;
import de.iteratec.iteraplan.common.error.IteraplanTechnicalException;
import de.iteratec.iteraplan.common.util.Preconditions;
import de.iteratec.iteraplan.model.BuildingBlock;
import de.iteratec.iteraplan.model.BusinessMapping;
import de.iteratec.iteraplan.model.BusinessObject;
import de.iteratec.iteraplan.model.BusinessProcess;
import de.iteratec.iteraplan.model.BusinessUnit;
import de.iteratec.iteraplan.model.InformationSystemInterface;
import de.iteratec.iteraplan.model.InformationSystemRelease;
import de.iteratec.iteraplan.model.Product;
import de.iteratec.iteraplan.model.Transport;
import de.iteratec.iteraplan.model.attribute.AttributeType;
import de.iteratec.iteraplan.model.attribute.AttributeValue;
import de.iteratec.iteraplan.model.attribute.AttributeValueAssignment;
import de.iteratec.iteraplan.model.attribute.DateAV;
import de.iteratec.iteraplan.model.attribute.EnumAT;
import de.iteratec.iteraplan.model.attribute.EnumAV;
import de.iteratec.iteraplan.model.attribute.NumberAV;
import de.iteratec.iteraplan.model.attribute.ResponsibilityAV;
import de.iteratec.iteraplan.model.attribute.TextAV;
import de.iteratec.iteraplan.model.user.TypeOfFunctionalPermission;
import de.iteratec.iteraplan.model.user.User;
import de.iteratec.iteraplan.model.user.UserEntity;
import de.iteratec.iteraplan.model.user.UserGroup;

public class XmiServiceForTabReporting {
    private static final Logger LOGGER = Logger.getIteraplanLogger(XmiServiceForTabReporting.class);
    private static final Map<Class<?>, TypeOfFunctionalPermission> CLASS_TO_PERMISSIONS = getClassToPermsMap();
    private static final String RUNTIME_PERIOD = "RuntimePeriod";

    private EcoreServiceForTabReporting ecoreService;
    private SessionFactory sessionFactory;

    private static Map<Object, Object> getSaveOptions() {
        Map<Object, Object> result = Maps.newHashMap();
        result.put(XMIResource.OPTION_EXTENDED_META_DATA, ExtendedMetaData.INSTANCE);
        result.put(XMLResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE);
        return result;
    }

    public XmiServiceForTabReporting(EcoreServiceForTabReporting ecoreService, SessionFactory sessionFactory) {
        this.ecoreService = Preconditions.checkNotNull(ecoreService);
        this.sessionFactory = Preconditions.checkNotNull(sessionFactory);
    }

    public void generateXmlExportFor(Collection<? extends BuildingBlock> buildingBlocks, OutputStream stream) {
        if (buildingBlocks.isEmpty()) {
            return;
        }

        String uri = buildingBlocks.iterator().next().getClass().getSimpleName() + "_ExportForTabReporting.xml";
        TabReportingEcoreData tabReportingEcoreData = ecoreService.getExtendedEPackge();
        Resource xmiResource = getXmiResource(uri, tabReportingEcoreData);
        xmiResource.setURI(URI.createURI(""));
        EObject exportFor = export(buildingBlocks, tabReportingEcoreData);
        xmiResource.getContents().add(exportFor);
        try {
            xmiResource.save(stream, getSaveOptions());
        } catch (IOException e) {
            throw new IteraplanTechnicalException(e);
        }
    }

    public void generateTotalXmlExport(OutputStream stream) {
        String uri = "iteraplanXMI.xml";
        TabReportingEcoreData tabReportingEcoreData = ecoreService.getExtendedEPackge();
        Resource xmiResource = getXmiResource(uri, tabReportingEcoreData);
        xmiResource.setURI(URI.createURI(""));
        EObject eContainer = exportAll(tabReportingEcoreData);
        xmiResource.getContents().add(eContainer);
        try {
            xmiResource.save(stream, getSaveOptions());
        } catch (IOException e) {
            throw new IteraplanTechnicalException(e);
        }
    }

    @SuppressWarnings("unchecked")
    private EObject exportAll(TabReportingEcoreData tabEcoreData) {
        List<BuildingBlock> buildingBlocks = Lists.newArrayList();
        EPackage model = tabEcoreData.getModelPackage();
        Session session = sessionFactory.getCurrentSession();
        for (EClassifier ec : model.getEClassifiers()) {
            if (ec instanceof EClass) {
                EClass eClass = (EClass) ec;
                String name = eClass.getName();
                if (!eClass.isAbstract() && !RUNTIME_PERIOD.equals(name)
                        && !Iteraplan2EMFHelper.CLASS_NAME_TABULARREPORTING.equals(name)) {
                    Query query = session.createQuery("select xx from " + name + " xx");
                    Iterator<Object> iterator = query.iterate();
                    while (iterator.hasNext()) {
                        Object entity = iterator.next();
                        if (entity instanceof BuildingBlock) {
                            buildingBlocks.add((BuildingBlock) entity);
                        } else {
                            LOGGER.error(entity.getClass().getName());
                        }
                    }

                } else {
                    LOGGER.debug("Ignored " + name);
                }
            }
        }

        return export(buildingBlocks, tabEcoreData);
    }

    private Resource getXmiResource(String uri, TabReportingEcoreData tabReportingEcoreData) {
        Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("xml", new EcoreResourceFactoryImpl());
        ResourceSet rs = new ResourceSetImpl();

        EPackage extendedModel = tabReportingEcoreData.getModelPackage();
        rs.getPackageRegistry().put(extendedModel.getNsURI(), extendedModel);

        return rs.createResource(URI.createURI(uri));
    }

    private EObject export(Collection<? extends BuildingBlock> buildingBlocks,
            TabReportingEcoreData tabReportingEcoreData) {
        Map<Object, EObject> objectToEObject = Maps.newLinkedHashMap();
        for (BuildingBlock bb : buildingBlocks) {
            generateEObjectFor(bb, tabReportingEcoreData, objectToEObject);
        }

        for (BuildingBlock bb : buildingBlocks) {
            setEReferencesFor(bb, tabReportingEcoreData, objectToEObject);
        }

        return getEContainerObject(objectToEObject, tabReportingEcoreData.getModelPackage());
    }

    private EObject getEContainerObject(Map<Object, EObject> objects, EPackage modelPackage) {
        Preconditions.checkNotNull(objects);
        Preconditions.checkNotNull(modelPackage);
        Collection<EObject> eObjects = Lists.newArrayList(objects.values());

        EObject eContainer = modelPackage.getEFactoryInstance()
                .create((EClass) modelPackage.getEClassifier(Iteraplan2EMFHelper.CLASS_NAME_TABULARREPORTING));
        eContainer.eSet(eContainer.eClass().getEStructuralFeature(Iteraplan2EMFHelper.EREFERENCE_NAME), eObjects);

        return eContainer;
    }

    private void setEReferencesFor(BuildingBlock bb, TabReportingEcoreData tabReportingEcoreData,
            Map<Object, EObject> objectToEObject) {
        EObject eBB = objectToEObject.get(bb);
        for (EReference eReference : eBB.eClass().getEAllReferences()) {
            Object value = getReferenceValue(eBB, eReference, bb, tabReportingEcoreData, objectToEObject);
            if (value != null) {
                eBB.eSet(eReference, value);
            }
        }
    }

    private EObject generateEObjectFor(Object bb, TabReportingEcoreData tabReportingEcoreData,
            Map<Object, EObject> objectToEObject) {
        if (!userHasRights(bb.getClass())) {
            throw new IteraplanBusinessException(IteraplanErrorMessages.AUTHORISATION_REQUIRED);
        }

        EPackage extendedModel = tabReportingEcoreData.getModelPackage();
        EClass eClassifier = (EClass) extendedModel.getEClassifier(bb.getClass().getSimpleName());
        EObject eBB = extendedModel.getEFactoryInstance().create(eClassifier);
        for (EAttribute eAtt : eBB.eClass().getEAllAttributes()) {
            Object attributeValue = getAttributeValue(eBB, eAtt, bb, tabReportingEcoreData);
            if (attributeValue != null) {
                eBB.eSet(eAtt, attributeValue);
            }
        }
        objectToEObject.put(bb, eBB);

        return eBB;
    }

    private Object getAttributeValue(EObject eBB, EAttribute eAttribute, Object bb,
            TabReportingEcoreData tabReportingEcoreData) {
        boolean bbExtended = isExtended(eAttribute, tabReportingEcoreData);

        if (bbExtended) {
            return getValueForExtendedAttribute(eBB, eAttribute, bb, tabReportingEcoreData);
        } else {
            return getStandardAttributeValue(eAttribute, bb);
        }
    }

    private Object getReferenceValue(EObject eBB, EReference esf, Object bb,
            TabReportingEcoreData tabReportingEcoreData, Map<Object, EObject> objectToEObject) {
        boolean bbExtended = isExtended(esf, tabReportingEcoreData);

        if (bbExtended) {
            return getValueForExtendedReference(eBB, esf, (BuildingBlock) bb);
        } else {
            return getStandardReferenceValue(eBB, esf, bb, tabReportingEcoreData, objectToEObject);
        }
    }

    private Object getValueForExtendedReference(EObject eBB, EReference eRef, BuildingBlock bb) {
        if (eBB == null || eRef == null || bb == null || eRef.getEContainingClass() != eBB.eClass()) {
            return null;
        }

        if (eRef.getName().equals("owningUserEntities") && userHasRights(User.class)) {
            for (UserEntity ue : bb.getOwningUserEntities()) {
                if (ue instanceof User) {
                    addEValueToEList(eBB, eRef, ((User) ue).getLoginName());
                } else {
                    addEValueToEList(eBB, eRef, ((UserGroup) ue).getName());
                }
            }
        }

        return null;
    }

    @SuppressWarnings({ "rawtypes" })
    private Object getStandardReferenceValue(EObject eBB, EReference eRef, Object bb,
            TabReportingEcoreData tabReportingEcoreData, Map<Object, EObject> objectToEObject) {
        Object referencedValue = getReferencedValue(eRef, bb);
        if (referencedValue == null) {
            return null;
        }

        EReference eOpposite = eRef.getEOpposite();
        if (eRef.getUpperBound() == 1) {
            if (!objectToEObject.containsKey(referencedValue)) {
                if (userHasRights(referencedValue.getClass())) {
                    generateEObjectFor(referencedValue, tabReportingEcoreData, objectToEObject);
                } else {
                    return null;
                }
            }

            EObject referencedEObject = objectToEObject.get(referencedValue);
            if (eOpposite != null && eOpposite.getUpperBound() == 1) {
                referencedEObject.eSet(eOpposite, eBB);
            } else if (eOpposite != null) {
                addEValueToEList(referencedEObject, eOpposite, eBB);
            }

            return referencedEObject;
        } else {
            //TODO remove this if block
            if (!(referencedValue instanceof Iterable)) {
                LOGGER.error(
                        "ESF: " + eRef.getEContainingClass().getName() + "." + eRef.getName() + " behaves strange");
                referencedValue = Lists.newArrayList(referencedValue);
            }
            for (Object val : (Iterable) referencedValue) {
                if (val instanceof BusinessMapping) {
                    manageBusinessMapping((BusinessMapping) val, tabReportingEcoreData, objectToEObject);
                } else if (val instanceof Transport) {
                    manageTransport((Transport) val, tabReportingEcoreData, objectToEObject);
                } else {
                    if (!objectToEObject.containsKey(val)) {
                        if (userHasRights(val.getClass())) {
                            generateEObjectFor(val, tabReportingEcoreData, objectToEObject);
                        } else {
                            return null;
                        }
                    }

                    addEValueToEList(eBB, eRef, objectToEObject.get(val));
                    if (eOpposite != null && eOpposite.getUpperBound() == 1) {
                        objectToEObject.get(val).eSet(eOpposite, eBB);
                    } else if (eOpposite != null) {
                        addEValueToEList(objectToEObject.get(val), eOpposite, eBB);
                    }
                }
            }
        }

        return null;
    }

    private Object getReferencedValue(EReference eRef, Object bb) {
        try {
            Method method = findMethodForStandardAttribute(eRef.getName(), bb);
            if (method == null) {
                LOGGER.warn("The method for the reference {0} not found", eRef.getName());
                return null;
            }

            return method.invoke(bb);
        } catch (IllegalArgumentException e) {
            throw new IteraplanTechnicalException(IteraplanErrorMessages.INTERNAL_ERROR, e);
        } catch (IllegalAccessException e) {
            throw new IteraplanTechnicalException(IteraplanErrorMessages.INTERNAL_ERROR, e);
        } catch (InvocationTargetException e) {
            throw new IteraplanTechnicalException(IteraplanErrorMessages.INTERNAL_ERROR, e);
        }
    }

    private void manageTransport(Transport tp, TabReportingEcoreData tabReportingEcoreData,
            Map<Object, EObject> objectToEObject) {
        if (!userHasRights(BusinessObject.class) || !userHasRights(InformationSystemInterface.class)) {
            return;
        }

        if (!objectToEObject.containsKey(tp)) {
            generateEObjectFor(tp, tabReportingEcoreData, objectToEObject);
        }

        BusinessObject businessObject = tp.getBusinessObject();
        if (!objectToEObject.containsKey(businessObject)) {
            generateEObjectFor(businessObject, tabReportingEcoreData, objectToEObject);
        }

        EObject tpEObject = objectToEObject.get(tp);
        EObject boEObject = objectToEObject.get(businessObject);
        tpEObject.eSet(tpEObject.eClass().getEStructuralFeature("businessObject"), boEObject);
        addEValueToEList(boEObject, boEObject.eClass().getEStructuralFeature("transports"), tpEObject);

        InformationSystemInterface isi = tp.getInformationSystemInterface();
        if (!objectToEObject.containsKey(isi)) {
            generateEObjectFor(isi, tabReportingEcoreData, objectToEObject);
        }

        EObject isiEObject = objectToEObject.get(isi);
        tpEObject.eSet(tpEObject.eClass().getEStructuralFeature("informationSystemInterface"), isiEObject);
        addEValueToEList(isiEObject, isiEObject.eClass().getEStructuralFeature("transports"), tpEObject);
    }

    private void manageBusinessMapping(BusinessMapping bm, TabReportingEcoreData tabReportingEcoreData,
            Map<Object, EObject> objectToEObject) {
        InformationSystemRelease isr = bm.getInformationSystemRelease();

        if (!objectToEObject.containsKey(bm)) {
            generateEObjectFor(bm, tabReportingEcoreData, objectToEObject);
            EObject eBm = objectToEObject.get(bm);

            BusinessProcess businessProcess = bm.getBusinessProcess();
            if (userHasRights(BusinessProcess.class) && businessProcess != null) {
                if (!objectToEObject.containsKey(businessProcess)) {
                    generateEObjectFor(businessProcess, tabReportingEcoreData, objectToEObject);
                }
                eBm.eSet(eBm.eClass().getEStructuralFeature("businessProcess"),
                        objectToEObject.get(businessProcess));
            }

            if (userHasRights(InformationSystemRelease.class) && isr != null) {
                if (!objectToEObject.containsKey(isr)) {
                    generateEObjectFor(isr, tabReportingEcoreData, objectToEObject);
                }
                eBm.eSet(eBm.eClass().getEStructuralFeature("informationSystemRelease"), objectToEObject.get(isr));
            }

            BusinessUnit businessUnit = bm.getBusinessUnit();
            if (userHasRights(BusinessUnit.class) && businessUnit != null) {
                if (!objectToEObject.containsKey(businessUnit)) {
                    generateEObjectFor(businessUnit, tabReportingEcoreData, objectToEObject);
                }
                eBm.eSet(eBm.eClass().getEStructuralFeature("businessUnit"), objectToEObject.get(businessUnit));
            }

            Product product = bm.getProduct();
            if (userHasRights(Product.class) && product != null) {
                if (!objectToEObject.containsKey(product)) {
                    generateEObjectFor(product, tabReportingEcoreData, objectToEObject);
                }
                eBm.eSet(eBm.eClass().getEStructuralFeature("product"), objectToEObject.get(product));
            }
        }

    }

    private Object getStandardAttributeValue(EAttribute eAtt, Object bb) {
        Method method = findMethodForStandardAttribute(eAtt.getName(), bb);
        if (method == null) {
            LOGGER.warn("The method for the attribute {0} for class {1} not found", eAtt.getName(), bb.getClass());
            return null;
        }

        Object result = invokeMethod(bb, method);

        if (!(eAtt.getEType() instanceof EEnum)) {
            if (eAtt.isID()) {
                return eAtt.getEContainingClass().getName() + "_" + ((Integer) result).intValue();
            }
            return result;
        }

        if (result == null) {
            return null;
        }

        EEnum eEnum = (EEnum) eAtt.getEType();
        for (EEnumLiteral eLiteral : eEnum.getELiterals()) {
            if (result.toString().equals(eLiteral.getLiteral())) {
                return eLiteral;
            }
        }

        return null;
    }

    private Object invokeMethod(Object bb, Method method) {
        try {
            return method.invoke(bb);
        } catch (IllegalArgumentException e) {
            throw new IteraplanTechnicalException(IteraplanErrorMessages.INTERNAL_ERROR, e);
        } catch (IllegalAccessException e) {
            throw new IteraplanTechnicalException(IteraplanErrorMessages.INTERNAL_ERROR, e);
        } catch (InvocationTargetException e) {
            throw new IteraplanTechnicalException(IteraplanErrorMessages.INTERNAL_ERROR, e);
        }
    }

    private Method findMethodForStandardAttribute(String name, Object bb) {
        String keyGet = "get" + capitalize(name);
        String keyIs = "is" + capitalize(name);

        Method[] methodsOfBBClass = bb.getClass().getMethods();
        for (Method m : methodsOfBBClass) {
            if (m.getName().equals(keyGet) || m.getName().equals(keyIs)) {
                return m;
            }
        }

        return null;
    }

    private Object getValueForExtendedAttribute(EObject eBB, EAttribute eAtt, Object ob,
            TabReportingEcoreData tabReportingEcoreData) {
        BuildingBlock bb = (BuildingBlock) ob;

        AttributeType attributeType = tabReportingEcoreData.getAttributeTypeForFeature(eAtt);
        if (attributeType != null) {
            for (AttributeValueAssignment ava : bb.getAttributeValueAssignments()) {
                AttributeValue attributeValue = ava.getAttributeValue();

                if (attributeValue.getAbstractAttributeType().equals(attributeType)) {
                    if (attributeValue instanceof NumberAV) {
                        NumberAV nAV = (NumberAV) attributeValue;
                        return nAV.getValue();
                    }
                    if (attributeValue instanceof DateAV) {
                        DateAV dAV = (DateAV) attributeValue;
                        return dAV.getValue();
                    }
                    if (attributeValue instanceof TextAV) {
                        TextAV tAV = (TextAV) attributeValue;
                        return tAV.getValue();
                    }
                    if (attributeValue instanceof ResponsibilityAV) {
                        ResponsibilityAV rAV = (ResponsibilityAV) attributeValue;
                        if (eAtt.getUpperBound() == 1) {
                            return rAV.getUserEntity().getIdentityString();
                        } else {
                            addEValueToEList(eBB, eAtt, rAV.getUserEntity().getIdentityString());
                        }
                    }

                    if (attributeValue instanceof EnumAV) {
                        EnumAV eAV = (EnumAV) attributeValue;
                        EnumAT attributeType2 = eAV.getAttributeType();
                        for (EEnumLiteral eLiteral : tabReportingEcoreData.getEEnumForAttributeType(attributeType2)
                                .getELiterals()) {
                            if (eLiteral.getLiteral().equals(eAV.getValue())) {
                                if (eAtt.getUpperBound() == 1) {
                                    return eLiteral;
                                } else {
                                    addEValueToEList(eBB, eAtt, eLiteral);
                                }
                            }
                        }
                    }
                }
            }
        } else if (eAtt.getName().equals("owningUserEntities") && bb.getOwningUserEntities() != null) {
            EList<Object> eUsers = new UniqueEList<Object>();
            for (UserEntity ue : bb.getOwningUserEntities()) {
                eUsers.add(ue.getIdentityString());
            }
            eBB.eSet(eAtt, eUsers);
        }

        return null;
    }

    @SuppressWarnings("unchecked")
    private void addEValueToEList(EObject eObject, EStructuralFeature esf, Object eValue) {
        if (eObject == null || esf == null || esf.getUpperBound() != EStructuralFeature.UNBOUNDED_MULTIPLICITY
                || !esf.getEContainingClass().equals(eObject.eClass())) {
            return;
        }

        List<Object> eList = (List<Object>) eObject.eGet(esf);
        if (eList == null) {
            return;
        }

        eList.add(eValue);
    }

    private boolean userHasRights(Class<?> clazz) {
        TypeOfFunctionalPermission permission = CLASS_TO_PERMISSIONS.get(clazz);
        if (permission != null) {
            return UserContext.getCurrentPerms().userHasFunctionalPermission(permission);
        }
        //since we have functional permissions for all BuildingBlock classes except AbstractAssociation subclasses,
        //one can expect, that the return true will only be used when the rights for one of thes classes is checked
        return true;
    }

    private static Map<Class<?>, TypeOfFunctionalPermission> getClassToPermsMap() {
        Map<Class<?>, TypeOfFunctionalPermission> result = Maps.newHashMap();

        for (Entry<TypeOfFunctionalPermission, Class<?>> entry : TypeOfFunctionalPermission.PERMISSION_TO_CLASS_MAP
                .entrySet()) {
            result.put(entry.getValue(), entry.getKey());
        }

        return result;
    }

    private String capitalize(String s) {
        return StringUtils.capitalize(s);
    }

    public void saveExtendedEPackge(OutputStream outStream) {
        Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("ecore", new EcoreResourceFactoryImpl());
        ResourceSet rs = new ResourceSetImpl();
        Resource r = rs.createResource(URI.createURI("IteraplanModelForTabularReporting_extended.ecore"));

        TabReportingEcoreData tabReportingEcoreData = ecoreService.getExtendedEPackge();
        EPackage modelPackage = tabReportingEcoreData.getModelPackage();
        modelPackage.setNsURI(modelPackage.getNsURI().replaceAll(".ecore", "_extended.ecore"));

        r.setURI(URI.createURI(""));
        r.getContents().add(modelPackage);
        rs.getPackageRegistry().put(modelPackage.getNsURI(), modelPackage);
        rs.getPackageRegistry().put(modelPackage.getName(), modelPackage);
        try {
            r.save(outStream, getSaveOptions());
        } catch (IOException e) {
            throw new IteraplanTechnicalException(e);
        }
    }

    private boolean isExtended(EStructuralFeature esf, TabReportingEcoreData tabReportingEcoreData) {
        if (esf.getName().equals("owningUserEntities")) {
            return true;
        }
        return tabReportingEcoreData.containsStructuralFeature(esf);
    }
}