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