metabup.change.trace.ChangeTrace.java Source code

Java tutorial

Introduction

Here is the source code for metabup.change.trace.ChangeTrace.java

Source

/*******************************************************************************
 * Copyright (c) 2015 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package metabup.change.trace;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import metabup.metamodel.AnnotatedElement;
import metabup.metamodel.Attribute;
import metabup.metamodel.Feature;
import metabup.metamodel.MetaClass;
import metabup.metamodel.Reference;
import metabup.preferences.*;
import History.*;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EModelElement;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.impl.EClassImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.preference.IPreferenceStore;

public class ChangeTrace {

    private List<ChangeTraceItem> index;
    private List<ChangeTraceInheritanceItem> inheritanceIndex;
    protected EPackage ePackage = null;

    public ChangeTrace(EPackage ePackage) {
        super();
        index = new ArrayList<ChangeTraceItem>();
        inheritanceIndex = new ArrayList<ChangeTraceInheritanceItem>();
        this.ePackage = ePackage;
    }

    public ChangeTrace() {
        super();
        index = new ArrayList<ChangeTraceItem>();
        inheritanceIndex = new ArrayList<ChangeTraceInheritanceItem>();
    }

    private boolean indexPut(ChangeTraceItem i) {
        return index.add(i);
    }

    private void indexRemove(ChangeTraceItem i, boolean recursive) {
        if (this.getByID(i.getMmElement().getId()) == null)
            //String id = i.getMmElement().getId();
            //if(recursive) for(Object j[] : index) if(j[3]!=null && ((String)j[3]).equals(id)) index.remove(j);
            index.remove(i);
        return;
    }

    /*private void indexRemove(List<ChangeTraceItem> old, boolean recursive){
       for(ChangeTraceItem i : old) this.indexRemove(i, true);   
       return;            
    }*/

    private boolean indexReplace(ChangeTraceItem old, ChangeTraceItem neu) {
        if (old == null || neu == null)
            return false;
        if (!index.contains(old))
            return false;
        if (!index.remove(old))
            return false;
        return index.add(neu);
    }

    /*private boolean indexReplace(List<ChangeTraceItem> old, ChangeTraceItem neu){
       if(old == null || neu == null || old.isEmpty()) return false;      
       for(ChangeTraceItem i : old) this.indexRemove(i, true);      
       return index.add(neu);      
    }*/

    public void load(AnnotatedElement ae, EModelElement eme) {
        if (isLoad(ae))
            return;

        /*AnnotatedElement copyAe = EcoreUtil.copy(ae);
        EModelElement copyEme = EcoreUtil.copy(eme);*/

        //if(copyAe.getId().equals(ae.getId())) //System.out.println("LOADING EQUAL ELEMENTS");

        if (ae != null && eme != null) {
            ChangeTraceItem in = new ChangeTraceItem("", ae, eme, null);
            this.indexPut(in);
        } else {
            //System.out.println("null element input. not loaded");
        }
    }

    public void add(AnnotatedElement ae) {
        if (ae == null)
            return;

        String re = null;
        if (ae instanceof Feature)
            re = ((MetaClass) ae.eContainer()).getId();
        ChangeTraceItem in = new ChangeTraceItem("add", ae, this.getEVersion(ae), re);

        if (this.getInitializerByID(ae.getId()) == null)
            this.indexPut(in);
        //else this.indexReplace(this.getInitializerByID(ae.getId()), in);   
    }

    public void delete(AnnotatedElement ae) {
        if (ae == null)
            return;
        ChangeTraceItem old = null;
        old = this.getInitializerByID(ae.getId());
        if (old == null)
            return;

        int op = -1;
        if (isLoad(ae))
            op = 0;
        else if (isAdd(ae))
            op = 1;

        switch (op) {
        case 0:
            this.indexPut(new ChangeTraceItem("delete", old.getMmElement(), old.getEcoreElement(),
                    old.getReferredElementId()));
            break;

        case 1:
            this.indexRemove(old, true);
            break;

        default:
            break;
        }

        old = this.getOtherByID(ae.getId());

        op = -1;
        if (isDelete(ae))
            op = 2;
        else if (isUpdate(ae))
            op = 3;

        switch (op) {
        case 2:
            // delete over an element to be deleted has no effect
            break;

        case 3:
            this.indexReplace(old, new ChangeTraceItem("delete", old.getMmElement(), old.getEcoreElement(),
                    old.getReferredElementId()));
            break;

        default:
            break;
        }

        ChangeTraceInheritanceItem ctii;
        if ((ctii = this.getInheritanceByID(ae.getId())) != null)
            this.inheritanceIndex.remove(ctii);
    }

    public void update(AnnotatedElement ae) {
        if (ae == null)
            return;
        ChangeTraceItem old = null;
        old = this.getInitializerByID(ae.getId());
        if (old == null)
            return;

        int op = -1;
        if (isLoad(ae))
            op = 0;
        else if (isAdd(ae))
            op = 1;

        switch (op) {
        case 0:
            this.indexPut(new ChangeTraceItem("update", ae, this.getEVersion(ae), old.getReferredElementId()));
            break;

        case 1:
            this.indexPut(new ChangeTraceItem("update", ae, this.getEVersion(ae), old.getReferredElementId()));
            break;

        default:
            break;
        }

        old = this.getOtherByID(ae.getId());

        op = -1;
        if (isDelete(ae))
            op = 2;
        else if (isUpdate(ae))
            op = 3;

        switch (op) {
        case 2:
            // update over an element to be deleted has no effect
            break;

        case 3:
            this.indexReplace(old,
                    new ChangeTraceItem("update", ae, this.getEVersion(ae), old.getReferredElementId()));
            break;

        default:
            break;
        }
    }

    public void addInheritance(MetaClass in[]) {
        if (in == null || in.length != 2)
            return;

        ChangeTraceInheritanceItem ctii = new ChangeTraceInheritanceItem("add", in[0], in[1]);
        if (this.getInheritanceByID(in[0].getId(), in[1].getId()) == null)
            this.inheritanceIndex.add(ctii);
    }

    public void deleteInheritance(MetaClass in[]) {
        if (in == null || in.length != 2)
            return;

        ChangeTraceInheritanceItem old = this.getInheritanceByID(in[0].getId(), in[1].getId());
        if (old != null && old.isAdd())
            this.inheritanceIndex.remove(old);
        else if (old == null) {
            ChangeTraceInheritanceItem ctii = new ChangeTraceInheritanceItem("delete", in[0], in[1]);
            if (this.getInheritanceByID(in[0].getId(), in[1].getId()) == null)
                this.inheritanceIndex.add(ctii);
        }
    }

    public void refreshIndex() {
        List<ChangeTraceItem> old = new ArrayList<ChangeTraceItem>();
        List<ChangeTraceItem> neu = new ArrayList<ChangeTraceItem>();

        for (ChangeTraceItem i : index) {
            if (i.getReferredElementId() == null && i.getMmElement() instanceof Feature) {
                for (ChangeTraceItem j : index) {
                    if (j.getMmElement() instanceof MetaClass) {
                        MetaClass mc = (MetaClass) j.getMmElement();

                        for (Feature f : mc.getFeatures()) {
                            if (f.getId().equals(((Feature) i.getMmElement()).getId())) {
                                old.add(i);
                                ChangeTraceItem newi = new ChangeTraceItem(i.getOp(), i.getMmElement(),
                                        i.getEcoreElement(), mc.getId());
                                neu.add(newi);
                            }
                        }
                    }
                }
            }
        }

        for (int i = 0; i < old.size(); i++)
            this.indexReplace(old.get(i), neu.get(i));
    }

    private List<ChangeTraceItem> getLoads() {
        List<ChangeTraceItem> loads = new ArrayList<ChangeTraceItem>();
        for (ChangeTraceItem i : index)
            if (i.getOp().equals(""))
                loads.add(i);
        return loads;
    }

    private boolean isLoad(AnnotatedElement ae) {
        for (ChangeTraceItem i : index)
            if (i.getOp().equals("") && i.getMmElement().getId().equals(ae.getId()))
                return true;
        return false;
    }

    private EModelElement getEVersion(AnnotatedElement ae) {
        EModelElement eme = null;

        if (ae instanceof MetaClass)
            eme = MetaClass2EClass((MetaClass) ae);
        else if (ae instanceof Reference)
            eme = Reference2EReference((Reference) ae);
        else if (ae instanceof Attribute)
            eme = Attribute2EAttribute((Attribute) ae);

        return eme;
    }

    protected List<ChangeTraceItem> getAdds() {
        List<ChangeTraceItem> adds = new ArrayList<ChangeTraceItem>();
        for (ChangeTraceItem i : index)
            if (i.getOp().equals("add"))
                adds.add(i);
        return adds;
    }

    private boolean isAdd(AnnotatedElement ae) {
        for (ChangeTraceItem i : index)
            if (i.getOp().equals("add") && i.getMmElement().getId().equals(ae.getId()))
                return true;
        return false;
    }

    protected List<ChangeTraceItem> getDeletes() {
        List<ChangeTraceItem> adds = new ArrayList<ChangeTraceItem>();
        for (ChangeTraceItem i : index)
            if (i.getOp().equals("delete"))
                adds.add(i);
        return adds;
    }

    private boolean isDelete(AnnotatedElement ae) {
        for (ChangeTraceItem i : index)
            if (i.getOp().equals("delete") && i.getMmElement().getId().equals(ae.getId()))
                return true;
        return false;
    }

    protected List<ChangeTraceItem> getUpdates() {
        List<ChangeTraceItem> adds = new ArrayList<ChangeTraceItem>();
        for (ChangeTraceItem i : index)
            if (i.getOp().equals("update"))
                adds.add(i);
        return adds;
    }

    private boolean isUpdate(AnnotatedElement ae) {
        for (ChangeTraceItem i : index)
            if (i.getOp().equals("update") && i.getMmElement().getId().equals(ae.getId()))
                return true;
        return false;
    }

    protected List<ChangeTraceInheritanceItem> getInheritanceAdds() {
        List<ChangeTraceInheritanceItem> inhAdds = new ArrayList<ChangeTraceInheritanceItem>();
        for (ChangeTraceInheritanceItem i : inheritanceIndex)
            if (i.getOp().equals("add"))
                inhAdds.add(i);
        return inhAdds;
    }

    private List<ChangeTraceInheritanceItem> getInheritanceDeletes() {
        List<ChangeTraceInheritanceItem> inhDeletes = new ArrayList<ChangeTraceInheritanceItem>();
        for (ChangeTraceInheritanceItem i : inheritanceIndex)
            if (i.getOp().equals("delete"))
                inhDeletes.add(i);
        return inhDeletes;
    }

    public void exportToCollaboro(IFile chFile) {
        ResourceSetImpl rs = new ResourceSetImpl();
        rs.getResourceFactoryRegistry().getExtensionToFactoryMap().put(Resource.Factory.Registry.DEFAULT_EXTENSION,
                new XMIResourceFactoryImpl());
        Resource chResource = new XMIResourceImpl(URI.createURI(chFile.getLocationURI().toString()));

        //IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
        IProject project = chFile.getProject();
        IFile ecoreFile = project.getFile(chFile.getName().substring(0, chFile.getName().indexOf(".")) + ".ecore");
        Resource ecoreResource = null;

        if (ecoreFile.exists()) {
            ecoreResource = new XMIResourceImpl(URI.createURI(ecoreFile.getLocationURI().toString()));
            rs.getResources().add(ecoreResource);
        } else //System.out.println("No ecore file found. It might carry future problems with serialization");

            rs.getResources().add(chResource);

        if (!chFile.exists()) {
            History collHistory = HistoryFactory.eINSTANCE.createHistory();

            String username = PreferenceConstants.P_COLLABORO_USERNAME;

            if (username.equals("")) {
                InputDialog ipDialog = new InputDialog(null, "Collaboro username required",
                        "Enter your collaboro username: ", PreferenceConstants.P_COLLABORO_USERNAME, null);
                if (ipDialog.open() == InputDialog.OK) {
                    username = ipDialog.getValue();
                    IPreferenceStore store = metabup.preferences.Activator.getDefault().getPreferenceStore();
                    store.setDefault(PreferenceConstants.P_COLLABORO_USERNAME, username);
                }
            }

            User user = HistoryFactory.eINSTANCE.createUser();
            user.setId(username);

            VersionHistory vh = HistoryFactory.eINSTANCE.createVersionHistory();
            vh.setType(VersionHistoryType.TRUNK);

            Version version = HistoryFactory.eINSTANCE.createVersion();
            version.setId("1.0");

            Proposal proposal = HistoryFactory.eINSTANCE.createProposal();
            proposal.setProposedBy(user);
            proposal.setRationale("metabup-based proposal");
            proposal.setId("n0");

            Solution solution = HistoryFactory.eINSTANCE.createSolution();
            solution.setProposedBy(user);

            /* root ePackage generation in case there's no one available */
            if (ePackage == null) {
                InputDialog ipDialog = new InputDialog(null, "Main EPackage name required",
                        "Name the EPackage that will contain your Metaclasses",
                        chFile.getName().substring(0, chFile.getName().lastIndexOf(".")), null);
                if (ipDialog.open() == InputDialog.OK) {
                    ePackage = EcoreFactory.eINSTANCE.createEPackage();
                    ePackage.setName(ipDialog.getValue());

                    Add add = HistoryFactory.eINSTANCE.createAdd();

                    NewAbstractSyntaxElement nase = HistoryFactory.eINSTANCE.createNewAbstractSyntaxElement();
                    nase.setElement(ePackage);
                    add.setTarget(nase);

                    add.setSolution(solution);
                    solution.getChanges().add(add);
                }
            }

            solution.getChanges().addAll(this.getCollaboroAdds(solution));
            solution.getChanges().addAll(this.getCollaboroDeletes(solution));
            solution.getChanges().addAll(this.getCollaboroUpdates(solution));

            proposal.getSols().add(solution);
            version.getProposals().add(proposal);
            vh.getVersions().add(version);
            collHistory.getUsers().add(user);
            collHistory.getHistories().add(vh);

            chResource.getContents().add(collHistory);

            try {
                chFile.create(null, true, null);
                chFile.refreshLocal(1, null);
                chResource.save(null);
            } catch (CoreException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } else {
            //WindowDialog.openError();
            //System.out.println("The file already exists");
        }
    }

    private List<Add> getCollaboroAdds(Solution solution) {
        List<Add> adds = new ArrayList<Add>();

        for (ChangeTraceItem i : this.getAdds()) {
            Add add = HistoryFactory.eINSTANCE.createAdd();
            EModelElement eme = null;
            ExistingAbstractSyntaxElement ease = HistoryFactory.eINSTANCE.createExistingAbstractSyntaxElement();

            /* EClass elements addition */
            if (i.getEcoreElement() instanceof EClass) {
                eme = EcoreFactory.eINSTANCE.createEClass();
                eme = (EClass) i.getEcoreElement();

                ease.setElement(ePackage);
                add.setReferredElement(ease);
            } else {
                EClass contClass = EcoreFactory.eINSTANCE.createEClass();

                if (i.getEcoreElement() instanceof EReference) {
                    eme = EcoreFactory.eINSTANCE.createEReference();
                    eme = (EReference) i.getEcoreElement();
                    ((EReference) eme).setEType(
                            (EClass) this.getInitializerByID(((Reference) i.getMmElement()).getReference().getId())
                                    .getEcoreElement());
                } else {
                    if (i.getEcoreElement() instanceof EAttribute) {
                        eme = EcoreFactory.eINSTANCE.createEAttribute();
                        eme = (EAttribute) i.getEcoreElement();
                    }
                }

                // assign the container metaclass as the referred element
                contClass = (EClass) this.getInitializerByID(((String) i.getReferredElementId())).getEcoreElement();
                ease.setElement(contClass);
                add.setReferredElement(ease);

            }

            NewAbstractSyntaxElement nase = HistoryFactory.eINSTANCE.createNewAbstractSyntaxElement();
            nase.setElement(eme);
            add.setTarget(nase);

            add.setSolution(solution);
            adds.add(add);
        }

        return adds;
    }

    private List<Delete> getCollaboroDeletes(Solution solution) {
        List<Delete> dels = new ArrayList<Delete>();

        for (ChangeTraceItem i : this.getDeletes()) {
            Delete del = HistoryFactory.eINSTANCE.createDelete();
            EModelElement eme = null;
            ExistingAbstractSyntaxElement ease = HistoryFactory.eINSTANCE.createExistingAbstractSyntaxElement();

            /* EClass elements deletion */
            if (i.getEcoreElement() instanceof EClass) {
                eme = EcoreFactory.eINSTANCE.createEClass();
                eme = (EClass) i.getEcoreElement();

                ease.setElement(ePackage);
                del.setReferredElement(ease);
            } else {
                EClass contClass = EcoreFactory.eINSTANCE.createEClass();

                if (i.getEcoreElement() instanceof EReference) {
                    eme = EcoreFactory.eINSTANCE.createEReference();
                    eme = (EReference) i.getEcoreElement();
                    ((EReference) eme).setEType(
                            (EClass) this.getInitializerByID(((Reference) i.getMmElement()).getReference().getId())
                                    .getEcoreElement());
                } else {
                    if (i.getEcoreElement() instanceof EAttribute) {
                        eme = EcoreFactory.eINSTANCE.createEAttribute();
                        eme = (EAttribute) i.getEcoreElement();
                    }
                }

                // assign the container metaclass as the referred element                                                    
                contClass = (EClass) this.getInitializerByID(((String) i.getReferredElementId())).getEcoreElement();
                ease.setElement(contClass);
                del.setReferredElement(ease);
            }

            ExistingAbstractSyntaxElement tarEase = HistoryFactory.eINSTANCE.createExistingAbstractSyntaxElement();
            tarEase.setElement(eme);
            del.setTarget(tarEase);

            del.setSolution(solution);
            dels.add(del);
        }

        return dels;
    }

    private List<Update> getCollaboroUpdates(Solution solution) {
        List<Update> upds = new ArrayList<Update>();

        for (ChangeTraceItem i : this.getUpdates()) {
            Update upd = HistoryFactory.eINSTANCE.createUpdate();
            EModelElement eme2 = null;
            ExistingAbstractSyntaxElement ease = HistoryFactory.eINSTANCE.createExistingAbstractSyntaxElement();

            /* EClass elements update */
            if (i.getEcoreElement() instanceof EClass) {
                eme2 = EcoreFactory.eINSTANCE.createEClass();
                eme2 = (EClass) i.getEcoreElement();

                ease.setElement(ePackage);
                upd.setReferredElement(ease);
            } else {
                EClass contClass = EcoreFactory.eINSTANCE.createEClass();

                if (i.getEcoreElement() instanceof EReference) {
                    eme2 = EcoreFactory.eINSTANCE.createEReference();
                    eme2 = (EReference) i.getEcoreElement();
                    ((EReference) eme2).setEType(
                            (EClass) this.getInitializerByID(((Reference) i.getMmElement()).getReference().getId())
                                    .getEcoreElement());
                } else {
                    if (i.getEcoreElement() instanceof EAttribute) {
                        eme2 = EcoreFactory.eINSTANCE.createEAttribute();
                        eme2 = (EAttribute) i.getEcoreElement();
                    }
                }

                // assign the container metaclass as the referred element
                contClass = (EClass) this.getInitializerByID(((String) i.getReferredElementId())).getEcoreElement();
                ease.setElement(contClass);
                upd.setReferredElement(ease);

            }

            NewAbstractSyntaxElement nase = HistoryFactory.eINSTANCE.createNewAbstractSyntaxElement();
            nase.setElement(eme2);
            upd.setTarget(nase);

            upd.setSolution(solution);
            upds.add(upd);
        }

        for (ChangeTraceInheritanceItem i : this.getInheritanceAdds()) {
            Update upd = HistoryFactory.eINSTANCE.createUpdate();

            ExistingAbstractSyntaxElement ease = HistoryFactory.eINSTANCE.createExistingAbstractSyntaxElement();
            ease.setElement(this.getInitializerByID(i.getSource().getId()).getEcoreElement().eClass()
                    .getEStructuralFeature("eSuperTypes"));
            upd.setReferredElement(ease);

            EClass eSource = (EClass) this.getInitializerByID(i.getSource().getId()).getEcoreElement();

            if (this.getInitializerByID(i.getSource().getId()).isLoad()) {
                ExistingAbstractSyntaxElement ease2 = HistoryFactory.eINSTANCE
                        .createExistingAbstractSyntaxElement();
                ease2.setElement(eSource);
                upd.setSource(ease2);
            } else {
                NewAbstractSyntaxElement ease2 = HistoryFactory.eINSTANCE.createNewAbstractSyntaxElement();
                ease2.setElement(eSource);
                upd.setSource(ease2);
            }

            EClass eTarget = (EClass) this.getInitializerByID(i.getTarget().getId()).getEcoreElement();

            //System.out.println("TARGET: " + this.getInitializerByID(i.getTarget().getId()).getOp());

            if (this.getInitializerByID(i.getTarget().getId()).isLoad()) {
                ExistingAbstractSyntaxElement ease2 = HistoryFactory.eINSTANCE
                        .createExistingAbstractSyntaxElement();
                ease2.setElement(eTarget);
                upd.setTarget(ease2);
            } else {
                NewAbstractSyntaxElement ease2 = HistoryFactory.eINSTANCE.createNewAbstractSyntaxElement();
                ease2.setElement(eTarget);
                upd.setTarget(ease2);
            }

            upd.setSolution(solution);
            upds.add(upd);
        }

        return upds;
    }

    /*private List<Object[]> getUpdatedProperties(ChangeTraceItem src, ChangeTraceItem tar){
       List<Object[]> properties = new ArrayList<Object[]>();
           
       if(src!= null && tar != null && src.getMmElement() instanceof MetaClass && tar.getMmElement() instanceof MetaClass){         
     List<MetaClass> srcSupers = ((MetaClass)src.getMmElement()).getSupers();
     List<MetaClass> tarSupers = ((MetaClass)tar.getMmElement()).getSupers();                  
         
     for(MetaClass tarSup : tarSupers){
        boolean found = false;
            
        for(MetaClass srcSup : srcSupers) if(tarSup.getId().equals(srcSup.getId())) found = true;            
            
        if(!found){
           Object prop[] = {src.getEcoreElement().eClass().getEStructuralFeature("eSuperTypes"), src, this.getInitializerByID(tarSup.getId())};
           properties.add(prop);
        }
     }
       }
       return properties;      
    }*/

    private List<ChangeTraceItem> getByID(String id) {
        List<ChangeTraceItem> list = new ArrayList<ChangeTraceItem>();
        for (ChangeTraceItem i : index)
            if (i.getMmElement().getId().equals(id))
                list.add(i);
        if (list.isEmpty())
            return null;
        return list;
    }

    protected ChangeTraceItem getInitializerByID(String id) {
        for (ChangeTraceItem i : index)
            if (i.getMmElement().getId().equals(id) && (i.isLoad() || i.isAdd()))
                return i;
        return null;
    }

    private ChangeTraceItem getOtherByID(String id) {
        for (ChangeTraceItem i : index)
            if (i.getMmElement().getId().equals(id) && (i.isDelete() || i.isUpdate()))
                return i;
        return null;
    }

    private ChangeTraceInheritanceItem getInheritanceByID(String srcId, String tarId) {
        for (ChangeTraceInheritanceItem i : this.inheritanceIndex)
            if (i.getSource().getId().equals(srcId) && i.getTarget().getId().equals(tarId))
                return i;
        return null;
    }

    private ChangeTraceInheritanceItem getInheritanceByID(String id) {
        for (ChangeTraceInheritanceItem i : this.inheritanceIndex)
            if (i.getSource().getId().equals(id) || i.getTarget().getId().equals(id))
                return i;
        return null;
    }

    public EClass MetaClass2EClass(MetaClass mc) {
        EClass ec = EcoreFactory.eINSTANCE.createEClass();
        ec.setName(mc.getName());
        ec.setAbstract(mc.getIsAbstract());
        return ec;
    }

    public EReference Reference2EReference(Reference ref) {
        EReference eref = EcoreFactory.eINSTANCE.createEReference();
        eref.setName(ref.getName());
        eref.setLowerBound(ref.getMin());
        eref.setUpperBound(ref.getMax());
        eref.setEType(MetaClass2EClass(ref.getReference()));
        return eref;
    }

    public EAttribute Attribute2EAttribute(Attribute att) {
        EAttribute eatt = EcoreFactory.eINSTANCE.createEAttribute();
        eatt.setName(att.getName());
        eatt.setLowerBound(att.getMin());
        eatt.setUpperBound(att.getMax());

        String typename = att.getPrimitiveType();

        if (typename.equals("StringType"))
            eatt.setEType(EcorePackage.eINSTANCE.getEString());
        else if (typename.equals("IntType"))
            eatt.setEType(EcorePackage.eINSTANCE.getEInt());
        else if (typename.equals("DoubleType"))
            eatt.setEType(EcorePackage.eINSTANCE.getEDouble());
        else if (typename.equals("BooleanType"))
            eatt.setEType(EcorePackage.eINSTANCE.getEBoolean());
        else
            eatt.setEType(EcorePackage.eINSTANCE.getEString());

        return eatt;
    }

    public void printIndex() {
        for (ChangeTraceItem i : index) {
            String name = "", ename = "", type = "";
            if (i.getMmElement() instanceof MetaClass) {
                name = ((MetaClass) i.getMmElement()).getName();
                ename = ((EClass) i.getEcoreElement()).getName();
                type = "MetaClass";
            } else {
                if (i.getMmElement() instanceof Reference) {
                    name = ((Reference) i.getMmElement()).getName();
                    ename = ((EReference) i.getEcoreElement()).getName();
                    type = "Reference";
                } else {
                    if (i.getMmElement() instanceof Attribute) {
                        name = ((Attribute) i.getMmElement()).getName();
                        ename = ((EAttribute) i.getEcoreElement()).getName();
                        type = "Attribute";
                    }
                }
            }

            //System.out.println("\n" + i.getOp() + "\t" + name + "\t" + ename + "\t" + type);
        }
    }
}