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 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.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; import History.*; import metabup.metamodel.AnnotatedElement; import metabup.metamodel.Attribute; import metabup.metamodel.Feature; import metabup.metamodel.MetaClass; import metabup.metamodel.Reference; public class ChangeTracer { private List<Object[]> index; private EPackage ePackage = null; public ChangeTracer(EPackage ePackage) { super(); index = new ArrayList<Object[]>(); this.ePackage = ePackage; } public ChangeTracer() { super(); index = new ArrayList<Object[]>(); } private boolean indexPut(Object i[]) { if (i.length != 4) return false; if (i[0] instanceof String) { String op = ((String) i[0]); if (!op.equals("") && !op.equals("add") && !op.equals("delete") && !op.equals("update")) return false; } else return false; if (!(i[1] instanceof AnnotatedElement)) return false; if (!(i[2] instanceof EModelElement)) return false; return index.add(i); } private void indexRemove(Object i[], boolean recursive) { if (this.getByID(((AnnotatedElement) i[1]).getId()) == null) return; String id = ((AnnotatedElement) i[1]).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(String id, boolean recursive){ if(this.getByID(id) == null) return; if(recursive) for(Object j[] : index) if(((String)j[3]).equals(id)) index.remove(j); for(Object i[] : index) if(((AnnotatedElement)i[1]).getId().equals(id)) index.remove(i); return; }*/ /*private boolean indexRemove(String id, String op){ for(Object i[] : index) if(((String)i[0]).equals(op) && ((AnnotatedElement)i[1]).getId().equals(id)){ return index.remove(i); } return false; }*/ private boolean indexReplace(Object old[], Object neu[]) { if (old == null || neu == null) return false; if (!index.contains(old)) return false; if (neu.length != 4) return false; if (!(neu[0] instanceof String)) return false; if (!(neu[1] instanceof AnnotatedElement)) return false; if (!(neu[2] instanceof EModelElement)) return false; String op = (String) neu[0]; if (!op.equals("") && !op.equals("add") && !op.equals("delete") && !op.equals("update")) return false; if (!index.remove(old)) return false; return index.add(neu); } public static Object[] wrap(String op, AnnotatedElement ae, EModelElement eme, String re) { if (!op.equals("") && !op.equals("add") && !op.equals("delete") && !op.equals("update")) return null; if (ae == null || eme == null) return null; Object i[] = new Object[4]; i[0] = op; i[1] = ae; i[2] = eme; i[3] = re; return i; } public void load(AnnotatedElement ae, EModelElement eme) { if (isLoad(ae)) return; if (ae != null && eme != null) { Object in[] = { "", ae, eme, null }; /*if(ae instanceof Feature){ in[3] = ((MetaClass)ae.eContainer()).getId(); } else in[3] = null;*/ this.indexPut(in); } else { //System.out.println("null element input. not loaded"); } } public void refreshIndex() { List<Object[]> old = new ArrayList<Object[]>(); List<Object[]> neu = new ArrayList<Object[]>(); for (Object[] i : index) { if (i[3] == null && i[1] instanceof Feature) { for (Object[] j : index) { if (j[1] instanceof MetaClass) { MetaClass mc = (MetaClass) j[1]; for (Feature f : mc.getFeatures()) { if (f.getId().equals(((Feature) i[1]).getId())) { old.add(i); Object newi[] = { i[0], i[1], i[2], mc.getId() }; neu.add(newi); } } } } } } for (int i = 0; i < old.size(); i++) { this.indexReplace(old.get(i), neu.get(i)); } } private List<Object[]> getLoads() { List<Object[]> loads = new ArrayList<Object[]>(); for (Object i[] : index) if (((String) i[0]).equals("")) loads.add(i); return loads; } private boolean isLoad(AnnotatedElement ae) { for (Object i[] : index) if (((String) i[0]).equals("") && ((AnnotatedElement) i[1]).getId().equals(ae.getId())) return true; return false; } public void add(AnnotatedElement ae) { if (ae == null) return; Object in[] = new Object[4]; in[0] = "add"; in[1] = ae; in[2] = this.getEVersion(ae); if (ae instanceof Feature) { in[3] = ((MetaClass) ae.eContainer()).getId(); ////System.out.println("Referred element located: " + ((MetaClass)ae.eContainer()).getId()); } else in[3] = null; if (this.getByID(ae.getId()) == null) { this.indexPut(in); // //System.out.println("insert by addition " + ae); } else { this.indexReplace(this.getByID(ae.getId()), in); // //System.out.println("insert by replacement " + ae); } } 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; } private List<Object[]> getAdds() { List<Object[]> adds = new ArrayList<Object[]>(); for (Object i[] : index) if (((String) i[0]).equals("add")) adds.add(i); return adds; } private boolean isAdd(AnnotatedElement ae) { for (Object i[] : index) if (((String) i[0]).equals("add") && ((AnnotatedElement) i[1]).getId().equals(ae.getId())) return true; return false; } public void delete(AnnotatedElement ae) { if (ae == null) return; Object old[] = this.getByID(ae.getId()); if (old == null) return; int op = -1; if (isLoad(ae)) op = 0; else if (isAdd(ae)) op = 1; else if (isDelete(ae)) op = 2; else if (isUpdate(ae)) op = 3; switch (op) { case 0: this.indexReplace(old, wrap("delete", (AnnotatedElement) old[1], (EModelElement) old[2], (String) old[3])); break; case 1: this.indexRemove(old, true); break; case 2: // delete over an element to be deleted has no effect break; case 3: this.indexReplace(old, wrap("delete", (AnnotatedElement) old[1], (EModelElement) old[2], (String) old[3])); break; default: break; } } private List<Object[]> getDeletes() { List<Object[]> adds = new ArrayList<Object[]>(); for (Object i[] : index) if (((String) i[0]).equals("delete")) adds.add(i); return adds; } private boolean isDelete(AnnotatedElement ae) { for (Object i[] : index) if (((String) i[0]).equals("delete") && ((AnnotatedElement) i[1]).getId().equals(ae.getId())) return true; return false; } public void update(AnnotatedElement ae) { if (ae == null) return; Object old[] = this.getByID(ae.getId()); if (old == null) return; int op = -1; if (isLoad(ae)) op = 0; else if (isAdd(ae)) op = 1; else if (isDelete(ae)) op = 2; else if (isUpdate(ae)) op = 3; switch (op) { case 0: this.indexReplace(old, wrap("update", ae, this.getEVersion(ae), (String) old[3])); break; case 1: this.indexReplace(old, wrap("add", ae, this.getEVersion(ae), (String) old[3])); break; case 2: // update over an element to be deleted has no effect break; case 3: this.indexReplace(old, wrap("update", ae, this.getEVersion(ae), (String) old[3])); break; default: break; } } private List<Object[]> getUpdates() { List<Object[]> adds = new ArrayList<Object[]>(); for (Object i[] : index) if (((String) i[0]).equals("update")) adds.add(i); return adds; } private boolean isUpdate(AnnotatedElement ae) { for (Object i[] : index) if (((String) i[0]).equals("update") && ((AnnotatedElement) i[1]).getId().equals(ae.getId())) return true; return false; } 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 = metabup.preferences.PreferenceConstants.P_COLLABORO_USERNAME; if (username.equals("")) { InputDialog ipDialog = new InputDialog(null, "Collaboro username required", "Enter your collaboro username: ", metabup.preferences.PreferenceConstants.P_COLLABORO_USERNAME, null); if (ipDialog.open() == InputDialog.OK) { username = ipDialog.getValue(); IPreferenceStore store = metabup.preferences.Activator.getDefault().getPreferenceStore(); store.setDefault(metabup.preferences.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 (Object i[] : this.getAdds()) { Add add = HistoryFactory.eINSTANCE.createAdd(); EModelElement eme2 = null; ExistingAbstractSyntaxElement ease = HistoryFactory.eINSTANCE.createExistingAbstractSyntaxElement(); ; /* EClass elements addition */ if (i[2] instanceof EClass) { eme2 = EcoreFactory.eINSTANCE.createEClass(); eme2 = (EClass) i[2]; ease.setElement(ePackage); add.setReferredElement(ease); } else { EClass contClass = EcoreFactory.eINSTANCE.createEClass(); if (i[2] instanceof EReference) { eme2 = EcoreFactory.eINSTANCE.createEReference(); eme2 = (EReference) i[2]; ((EReference) eme2) .setEType((EClass) this.getByID(((Reference) i[1]).getReference().getId())[2]); } else { if (i[2] instanceof EAttribute) { eme2 = EcoreFactory.eINSTANCE.createEAttribute(); eme2 = (EAttribute) i[2]; } } // assign the container metaclass as the referred element contClass = (EClass) this.getByID(((String) i[3]))[2]; ease.setElement(contClass); add.setReferredElement(ease); } NewAbstractSyntaxElement nase = HistoryFactory.eINSTANCE.createNewAbstractSyntaxElement(); nase.setElement(eme2); add.setTarget(nase); add.setSolution(solution); adds.add(add); } return adds; } private List<Delete> getCollaboroDeletes(Solution solution) { List<Delete> dels = new ArrayList<Delete>(); for (Object i[] : this.getDeletes()) { Delete del = HistoryFactory.eINSTANCE.createDelete(); EModelElement eme2 = null; ExistingAbstractSyntaxElement ease = HistoryFactory.eINSTANCE.createExistingAbstractSyntaxElement(); ; /* EClass elements deletion */ if (i[2] instanceof EClass) { eme2 = EcoreFactory.eINSTANCE.createEClass(); eme2 = (EClass) i[2]; ease.setElement(ePackage); del.setReferredElement(ease); } else { EClass contClass = EcoreFactory.eINSTANCE.createEClass(); if (i[2] instanceof EReference) { eme2 = EcoreFactory.eINSTANCE.createEReference(); eme2 = (EReference) i[2]; ((EReference) eme2) .setEType((EClass) this.getByID(((Reference) i[1]).getReference().getId())[2]); } else { if (i[2] instanceof EAttribute) { eme2 = EcoreFactory.eINSTANCE.createEAttribute(); eme2 = (EAttribute) i[2]; } } // assign the container metaclass as the referred element contClass = (EClass) this.getByID(((String) i[3]))[2]; ease.setElement(contClass); del.setReferredElement(ease); } NewAbstractSyntaxElement nase = HistoryFactory.eINSTANCE.createNewAbstractSyntaxElement(); nase.setElement(eme2); del.setTarget(nase); del.setSolution(solution); dels.add(del); } return dels; } private List<Update> getCollaboroUpdates(Solution solution) { List<Update> upds = new ArrayList<Update>(); for (Object i[] : this.getUpdates()) { Update upd = HistoryFactory.eINSTANCE.createUpdate(); EModelElement eme2 = null; ExistingAbstractSyntaxElement ease = HistoryFactory.eINSTANCE.createExistingAbstractSyntaxElement(); /* EClass elements update */ if (i[2] instanceof EClass) { eme2 = EcoreFactory.eINSTANCE.createEClass(); eme2 = (EClass) i[2]; ease.setElement(ePackage); upd.setReferredElement(ease); } else { EClass contClass = EcoreFactory.eINSTANCE.createEClass(); if (i[2] instanceof EReference) { eme2 = EcoreFactory.eINSTANCE.createEReference(); eme2 = (EReference) i[2]; ((EReference) eme2) .setEType((EClass) this.getByID(((Reference) i[1]).getReference().getId())[2]); } else { if (i[2] instanceof EAttribute) { eme2 = EcoreFactory.eINSTANCE.createEAttribute(); eme2 = (EAttribute) i[2]; } } // assign the container metaclass as the referred element contClass = (EClass) this.getByID(((String) i[3]))[2]; ease.setElement(contClass); upd.setReferredElement(ease); } NewAbstractSyntaxElement nase = HistoryFactory.eINSTANCE.createNewAbstractSyntaxElement(); nase.setElement(eme2); upd.setTarget(nase); upd.setSolution(solution); upds.add(upd); } return upds; } private Object[] getByID(String id) { for (Object i[] : index) { if (((AnnotatedElement) (i[1])).getId().equals(id)) return i; } return null; } private Object[] getFeatureContainer(Object[] f) { if (f == null) return null; if (!(f[1] instanceof Feature)) return null; for (Object[] i : index) { if (i[0].equals("") || i[0].equals("add")) if (i[1] instanceof MetaClass) { MetaClass mc = (MetaClass) i[1]; for (Feature mcf : mc.getFeatures()) { if (((Feature) f[1]).getId().equals(mcf.getId())) return i; } } } return null; } public EClass MetaClass2EClass(MetaClass mc) { /* seek the EClass in the original ePackage */ /*if(this.ePackage != null){ for(EObject eo : ePackage.eContents()){ if(eo instanceof EClass){ EClass ec = (EClass)eo; if(ec.getName().equals(mc.getName())) return ec; } } }*/ /* create a new one if not found before */ EClass ec = EcoreFactory.eINSTANCE.createEClass(); ec.setName(mc.getName()); ec.setAbstract(mc.getIsAbstract()); return ec; } public EReference Reference2EReference(Reference ref) { /*if(this.ePackage != null){ for(EObject eo : ePackage.eContents()){ if(eo instanceof EReference){ EReference er = (EReference)eo; if(er.getName().equals(ref.getName())){ if(er.eContainer() instanceof EClass){ if(((EClass)er.eContainer()).getName().equals(((MetaClass)ref.eContainer()).getName())) return er; } } } } }*/ 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) { /*if(this.ePackage != null){ for(EObject eo : ePackage.eContents()){ if(eo instanceof EAttribute){ EAttribute ea = (EAttribute)eo; if(ea.getName().equals(att.getName())){ if(ea.eContainer() instanceof EClass){ if(((EClass)ea.eContainer()).getName().equals(((MetaClass)att.eContainer()).getName())) return ea; } } } } }*/ 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 (Object i[] : index) { String name = "", ename = "", type = ""; if (i[1] instanceof MetaClass) { name = ((MetaClass) i[1]).getName(); ename = ((EClass) i[2]).getName(); type = "MetaClass"; } else { if (i[1] instanceof Reference) { name = ((Reference) i[1]).getName(); ename = ((EReference) i[2]).getName(); type = "Reference"; } else { if (i[1] instanceof Attribute) { name = ((Attribute) i[1]).getName(); ename = ((EAttribute) i[2]).getName(); type = "Attribute"; } } } //System.out.println("\n" + i[0] + "\t" + name + "\t" + ename + "\t" + type); } } }