com.bluexml.side.Integration.eclipse.branding.enterprise.actions.ModelMigrationHelper.java Source code

Java tutorial

Introduction

Here is the source code for com.bluexml.side.Integration.eclipse.branding.enterprise.actions.ModelMigrationHelper.java

Source

/*
Copyright (C) 2007-20013  BlueXML - www.bluexml.com
    
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
    
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 Affero 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/>.
*/
package com.bluexml.side.Integration.eclipse.branding.enterprise.actions;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.util.EObjectEList;
import org.eclipse.emf.ecore.util.EcoreUtil;

import com.bluexml.side.application.Application;
import com.bluexml.side.application.ComponantConfiguration;
import com.bluexml.side.application.ConfigurationParameters;
import com.bluexml.side.application.GeneratorConfiguration;
import com.bluexml.side.application.Model;
import com.bluexml.side.application.ModuleConstraint;
import com.bluexml.side.application.ui.action.utils.ApplicationUtil;
import com.bluexml.side.clazz.Enumeration;
import com.bluexml.side.clazz.EnumerationLiteral;
import com.bluexml.side.common.ModelElement;
import com.bluexml.side.common.NameSpace;
import com.bluexml.side.common.NamedModelElement;
import com.bluexml.side.integration.eclipse.builder.settings.SIDEBuilderConfiguration;
import com.bluexml.side.portal.Column;
import com.bluexml.side.portal.HavePortlet;
import com.bluexml.side.portal.InstanciatePortletType;
import com.bluexml.side.portal.Page;
import com.bluexml.side.portal.Portlet;
import com.bluexml.side.portal.PortletAttribute;
import com.bluexml.side.portal.PortletType;
import com.bluexml.side.util.alfresco.tools.ModelLibrary;
import com.bluexml.side.util.antrunner.AntFileGeneratorAction;
import com.bluexml.side.util.libs.FileHelper;
import com.bluexml.side.util.libs.IFileHelper;
import com.bluexml.side.util.libs.ecore.EResourceUtils;

public class ModelMigrationHelper {

    List<File> loadedFiles = new ArrayList<File>();

    List<ComparableEObject> index = new ArrayList<ModelMigrationHelper.ComparableEObject>();

    Map<File, List<ComparableEObject>> map = new HashMap<File, List<ComparableEObject>>();

    public IFile getApplication(IProject project) {

        SIDEBuilderConfiguration sideconf = new SIDEBuilderConfiguration(project);
        if (sideconf.load()) {
            return sideconf.getApplicationFile();
        }
        return null;
    }

    public void updateProject(final IProject source, IProject target, String libraryId, boolean makeCopy,
            IProgressMonitor monitor2) throws Exception {
        System.out.println("ModelMigrationHelper.updateProject() source :" + source.getName());
        System.out.println("ModelMigrationHelper.updateProject() target :" + target.getName());
        List<File> models = getModels(source);
        List<File> diagrams = getDiagrams(source);
        List<File> applicationModels = getApplicationModels(source);

        List<File> mavenModules = getMavenModules(source);

        List<File> modelsTarget = getModels(target);

        //      System.out.println("ModelMigrationHelper.updateProject() models :" + models.size());
        //      System.out.println("ModelMigrationHelper.updateProject() diagrams :" + diagrams.size());
        //      System.out.println("ModelMigrationHelper.updateProject() applicationModels :" + applicationModels.size());
        //      System.out.println("ModelMigrationHelper.updateProject() mavenModules :" + mavenModules.size());
        //      System.out.println("ModelMigrationHelper.updateProject() targetModels :" + modelsTarget.size());

        monitor2.beginTask("updating project",
                models.size() + applicationModels.size() + mavenModules.size() + diagrams.size());
        // System.out.println("ModelMigrationHelper.updateProject() models to update :" + models.size());
        monitor2.subTask("models references");
        for (File file : models) {
            if (monitor2.isCanceled()) {
                return;
            }
            updateModel(file, modelsTarget, monitor2);
            monitor2.worked(1);
        }

        monitor2.subTask("diagrams references");
        for (File file : diagrams) {
            if (monitor2.isCanceled()) {
                return;
            }
            updateModel(file, modelsTarget, monitor2);
            monitor2.worked(1);
        }

        monitor2.subTask("application model");
        for (File file : applicationModels) {
            if (monitor2.isCanceled()) {
                return;
            }
            if (makeCopy) {
                updateApplicationModel(file, libraryId, source);
            } else {
                updateApplicationModel(file, libraryId, null);
            }
            AntFileGeneratorAction.generate(IFileHelper.getIFile(file));
            monitor2.worked(1);
        }

        if (makeCopy) {
            // check update project configuration
            SIDEBuilderConfiguration conf = new SIDEBuilderConfiguration(source);
            conf.load();
            String applicationRessourcePath = conf.getApplicationRessourcePath();
            String match = "(" + Pattern.quote("${workspace_loc:/") + ")" + "([^/]*)" + "(" + Pattern.quote("/")
                    + ".*" + Pattern.quote("}") + ")";
            if (applicationRessourcePath.matches(match)) {
                Pattern p = Pattern.compile(match);
                Matcher matcher = p.matcher(applicationRessourcePath);
                matcher.find();
                String group1 = matcher.group(1);
                String group3 = matcher.group(3);
                String replace = group1 + source.getName() + group3;
                conf.setApplicationRessourcePath(replace);
                conf.reload();
                conf.persist();
            } else {

            }
        }

        monitor2.subTask("maven modules");
        ModelLibrary modellib = new ModelLibrary(libraryId);
        for (File file : mavenModules) {
            if (!monitor2.isCanceled()) {
                return;
            }
            String newVersion = modellib.getMavenFrameworkVersion();
            String newClassifier = modellib.getMavenFrameworkClassifier();

            String[] groupIds = modellib.getMavenFrameworkGroup().split(",");
            if (StringUtils.trimToNull(newClassifier) != null && StringUtils.trimToNull(newVersion) != null
                    && StringUtils.trimToNull(libraryId) != null) {
                PomMigrationHelper.updateMavenPom(file, groupIds, newVersion, newClassifier);
            }
        }
    }

    /**
     * we make the assumption that componentId are somethings like
     * &lt;id&gt;&lt;version&gt;, and version start by a digit
     * 
     * @param componentsId
     * @param currentId
     * @return
     */
    protected String getTargetComponentId(List<String> componentsId, String currentId) {
        String root = currentId.replaceFirst("[0-9]+.*", "");
        for (String string : componentsId) {
            String prefix = string.replaceFirst("[0-9]+.*", "");
            if (root.equals(prefix)) {
                //            System.out.println("ModelMigrationHelper.getTargetComponentId() matchs :" + currentId + " -> " + string);
                return string;
            }
        }

        return null;
    }

    /**
     * 
     * @param file
     * @param libraryId
     * @param source, can be null if project copy is disabled
     * @throws IOException
     * @throws CoreException
     * @throws Exception
     */
    protected void updateApplicationModel(File file, String libraryId, IProject source)
            throws IOException, CoreException, Exception {

        IFile model = IFileHelper.getIFile(file);
        EList<EObject> openModel = EResourceUtils.openModel(model);
        EObject eObject = openModel.get(0);
        TreeIterator<EObject> eAllContents = eObject.eAllContents();
        while (eAllContents.hasNext()) {
            EObject eObject2 = (EObject) eAllContents.next();

            if (eObject2 instanceof ComponantConfiguration) {
                List<String> availableComponents = ApplicationUtil.getAvailableComponents(libraryId);
                ComponantConfiguration generatorConfiguration = (ComponantConfiguration) eObject2;
                String id = generatorConfiguration.getId();
                String targetComponentId = getTargetComponentId(availableComponents, id);
                if (targetComponentId != null) {
                    generatorConfiguration.setId(targetComponentId);
                }
                if (eObject2 instanceof GeneratorConfiguration && id.equals("side.customModules")) {
                    // need to update the techVersion
                    GeneratorConfiguration gen = (GeneratorConfiguration) eObject2;
                    EList<ModuleConstraint> moduleContraints = gen.getModuleContraints();
                    for (ModuleConstraint moduleConstraint : moduleContraints) {
                        moduleConstraint.setTechnologyVersion(libraryId);
                    }
                }
            } else if (eObject2 instanceof Model && source != null) {
                // check models list 
                // disabled models are not renamed
                Model modelItem = (Model) eObject2;
                String file2 = modelItem.getFile();
                String[] split = file2.split("/");
                String toreplace = split[1];

                modelItem.setFile(file2.replaceFirst(toreplace, source.getName()));
            } else if (eObject2 instanceof ConfigurationParameters && source != null) {
                ConfigurationParameters conf = (ConfigurationParameters) eObject2;
                if ("generation.options.logPath".equals(conf.getKey())
                        || "generation.options.destinationPath".equals(conf.getKey())) {
                    String val = conf.getValue().split("/")[1];
                    conf.setValue(conf.getValue().replaceFirst(val, source.getName()));
                }
            }
        }

        EResourceUtils.saveModel(model, eObject);
        // apply autoUpdate that check and fix options and modules according to componentId
        ApplicationUtil.updateApplicationFromExtensionPoint((Application) eObject, model);

    }

    public static List<File> getModels(IProject source) {
        String[] accepted = { ".dt", ".portal", ".form", ".view", ".workflow" };
        return getModels(source, accepted);
    }

    public static List<File> getDiagrams(IProject source) {
        String[] accepted = { ".dtdi", ".portaldi", ".workflowdi" };
        return getModels(source, accepted);
    }

    public static List<File> getApplicationModels(IProject source) {
        String[] accepted = { ".application" };
        return getModels(source, accepted);
    }

    public static List<File> getMavenModules(IProject source) {
        String[] accepted = { "pom.xml" };
        return getModels(source, accepted);
    }

    public static List<File> getModels(IProject source, final String[] fileExt) {
        File projectHome = IFileHelper.convertIRessourceToFile(source);
        FilenameFilter filter = new FilenameFilter() {
            public boolean accept(File file, String name) {
                boolean ok = false;

                for (String string : fileExt) {
                    if (name.endsWith(string)) {
                        ok = true;
                        break;
                    }
                }
                return file.isFile() && ok;
            }
        };
        List<File> files = FileHelper.listAll(projectHome);
        List<File> models = new ArrayList<File>();
        for (File file : files) {
            if (filter.accept(file, file.getName())) {
                models.add(file);
            }
        }
        return models;
    }

    public void updateModel(File file, List<File> modelsTarget, IProgressMonitor monitor2) throws Exception {
        // System.out.println("ModelMigrationHelper.updateModel() on " + file);
        // load ECore resource
        IFile model = IFileHelper.getIFile(file);
        EList<EObject> openModel = EResourceUtils.openModel(model);
        EObject eObject = openModel.get(0);

        // System.out.println("ModelMigrationHelper.updateModel() model root :" + eObject);
        TreeIterator<EObject> eAllContents = eObject.eAllContents();

        while (eAllContents.hasNext()) {
            EObject eObject2 = (EObject) eAllContents.next();
            // System.out.println("ModelMigrationHelper.updateModel() " + eObject2);
            for (EStructuralFeature esf : eObject2.eClass().getEAllStructuralFeatures()) {

                // System.out.println("ModelMigrationHelper.updateModel() search on feature " + esf.getName());
                Object o = eObject2.eGet(esf, false);
                Object o_resolved = eObject2.eGet(esf, true);
                try {
                    if (o != null || o_resolved != null) {
                        if (o instanceof List<?>) {
                            if (o instanceof EObjectEList) {

                                //                        System.out.println("ModelMigrationHelper.updateModel() le truc est une list de truc");
                                EObjectEList<EObject> l = (EObjectEList<EObject>) o;
                                EObjectEList<EObject> l_r = (EObjectEList<EObject>) o_resolved;
                                Map<Object, Object[]> toReplace = new HashMap<Object, Object[]>();

                                for (EObject object : l.basicList()) {
                                    int indexOf = l.indexOf(object);
                                    EObject updateElement = updateElement(esf, object, l_r.get(indexOf),
                                            modelsTarget);
                                    if (updateElement != null) {
                                        //                              System.out.println("ModelMigrationHelper.updateModel() indexof :" + indexOf);
                                        toReplace.put(l_r.get(indexOf), new Object[] { indexOf, updateElement });
                                    }
                                }
                                // replace
                                Set<Entry<Object, Object[]>> entrySet = toReplace.entrySet();
                                for (Entry<Object, Object[]> entry : entrySet) {

                                    Object object = entry.getKey();
                                    EObject updateElement = (EObject) entry.getValue()[1];
                                    //                           System.out.println("ModelMigrationHelper.updateModel() REPLACE " + object + " by " + updateElement);

                                    // System.out.println("ModelMigrationHelper.updateModel() BEFORE size :" + l.size());
                                    int indexOf = (Integer) entry.getValue()[0];
                                    l.add(indexOf, updateElement);
                                    // System.out.println("ModelMigrationHelper.updateModel() ADD size :" + l.size());
                                    l.remove(object);
                                    // System.out.println("ModelMigrationHelper.updateModel() REMOVE " + remove + " size :" + l.size());

                                }
                            } else {
                                //                        System.err.println("ModelMigrationHelper.updateModel() NOT Managed o: " + o + " for :" + esf.getName());
                            }
                        } else {
                            if (o instanceof EObject) {
                                EObject updateElement = updateElement(esf, (EObject) o, (EObject) o_resolved,
                                        modelsTarget);
                                if (updateElement != null) {
                                    //                           System.out.println("ModelMigrationHelper.updateModel() REPLACE " + o + " by " + updateElement);
                                    eObject2.eSet(esf, updateElement);
                                }
                            }
                        }
                    } else {
                        //                  System.out.println("ModelMigrationHelper.updateModel() null value in " + model + " on " + eObject2 + " ref :" + esf.getName());
                    }
                } catch (EqualsException e) {
                    throw new Exception("Please Check your models for missing references in " + model + " on "
                            + eObject2 + " ref :" + esf.getName());
                }
            }
        }

        EResourceUtils.saveModel(model, eObject);

    }

    protected EObject updateElement(EStructuralFeature esf, EObject eo2, EObject resolved, List<File> modelsTarget)
            throws Exception {
        if (eo2.eIsProxy()) {
            //         System.out.println("ModelMigrationHelper.updateModel() search on feature " + esf.getName());
            if (eo2 instanceof InternalEObject) {
                //            System.out.println("ModelMigrationHelper.updateModel() le truc est un proxy interne de machin " + eo2);
                // search in target for the same object
                return searchForSameObjectIn(resolved, modelsTarget);

            } else {
                //            System.out.println("ModelMigrationHelper.updateModel() le truc est un proxy externe de machin " + eo2);
            }
        } else {
            //         System.out.println("ModelMigrationHelper.updateModel() le truc est un machin" + eo2);
        }
        return null;
    }

    protected EObject searchForSameObjectIn(EObject object, List<File> modelsTarget) throws Exception {
        loadIndexes(modelsTarget);
        EObject target = null;
        for (File file : modelsTarget) {
            target = searchForSameObjectIn(object, file);
            if (target != null) {
                break;
            }
        }
        return target;
    }

    protected void loadIndexes(List<File> modelsTarget) throws IOException {
        for (File file : modelsTarget) {
            if (!map.containsKey(file)) {
                List<ComparableEObject> value = new ArrayList<ModelMigrationHelper.ComparableEObject>();
                IFile model = IFileHelper.getIFile(file);
                EList<EObject> openModel = EResourceUtils.openModel(model);
                EObject eObject = openModel.get(0);
                // System.out.println("ModelMigrationHelper.searchForSameObjectIn() model root :" + eObject);
                // System.out.println("ModelMigrationHelper.searchForSameObjectIn() Object to find :" + object);
                TreeIterator<EObject> eAllContents = eObject.eAllContents();
                while (eAllContents.hasNext()) {
                    EObject eObject2 = (EObject) eAllContents.next();
                    value.add(new ComparableEObject(eObject2));
                }
                map.put(file, value);
            }
        }
    }

    protected EObject searchForSameObjectIn(EObject object, File modelsTarget) throws Exception {

        List<ComparableEObject> list = map.get(modelsTarget);
        for (ComparableEObject comparableEObject : list) {
            if (new ComparableEObject(object).equals(comparableEObject)) {
                //            System.out.println("ModelMigrationHelper.searchForSameObjectIn() object matchs :" + eObject2);
                return comparableEObject.eObject;
            }
        }

        return null;
    }

    public static boolean equals(EObject a, EObject b) throws RootElementException {
        EClass aeClass = a.eClass();
        EClass beClass = b.eClass();
        //       System.out.println("ModelMigrationHelper.equals() a :" + a);
        //       System.out.println("ModelMigrationHelper.equals() b :" + b);
        boolean equals = aeClass.equals(beClass);

        if (equals) {
            if (a instanceof NamedModelElement && b instanceof NamedModelElement) {
                NamedModelElement namedModelElementA = (NamedModelElement) a;
                NamedModelElement namedModelElementB = (NamedModelElement) b;

                String fullNameA = namedModelElementA.getFullName();
                String fullNameB = namedModelElementB.getFullName();

                equals &= isInSameNS(namedModelElementA, namedModelElementB);

                if (a instanceof Column) {
                    equals &= avoid40_42_missmatchs(fullNameA).equals(avoid40_42_missmatchs(fullNameB));
                } else {
                    equals &= fullNameA.equals(fullNameB);
                }

            } else {

                //             System.out.println("ModelMigrationHelper.equals() not NamedElement " + a);

                if (a instanceof Portlet && b instanceof Portlet) {
                    equals &= getRootName(a).equals(getRootName(b));
                    // System.out.println("ModelMigrationHelper.equals() is Portlet");
                    equals &= ((Portlet) a).getName().equals(((Portlet) b).getName());

                    String name = StringUtils.trimToEmpty(((Portlet) a).getTitle());
                    String name2 = StringUtils.trimToEmpty(((Portlet) b).getTitle());
                    equals &= name.equals(name2);
                } else if (a instanceof Page && b instanceof Page) {
                    equals &= getRootName(a).equals(getRootName(b));
                    equals &= ((Page) a).getID().equals(((Page) b).getID());
                } else if (a instanceof PortletType && b instanceof PortletType) {
                    equals &= getRootName(a).equals(getRootName(b));
                    equals &= ((PortletType) a).getId().equals(((PortletType) b).getId());
                    String name = StringUtils.trimToEmpty(((PortletType) a).getName());
                    String name2 = StringUtils.trimToEmpty(((PortletType) b).getName());
                    equals &= name.equals(name2);

                } else if (a instanceof PortletAttribute) {
                    PortletAttribute portA = (PortletAttribute) a;
                    PortletAttribute portB = (PortletAttribute) b;

                    equals &= isInSameNS(portA, portB);
                    equals &= portA.getName().equals(portB.getName());
                    equals &= portA.getType().getName().equals(portB.getType().getName());

                } else if (a instanceof HavePortlet) {
                    equals &= getRootName(a).equals(getRootName(b));

                    HavePortlet hpA = (HavePortlet) a;

                    Page associationPage = hpA.getAssociationPage();
                    Portlet associationPortlet = hpA.getAssociationPortlet();

                    HavePortlet hpB = (HavePortlet) b;
                    Page associationPage2 = hpB.getAssociationPage();
                    Portlet associationPortlet2 = hpB.getAssociationPortlet();

                    equals &= equals(associationPage, associationPage2);
                    equals &= equals(associationPortlet, associationPortlet2);
                } else if (a instanceof InstanciatePortletType) {
                    InstanciatePortletType iptA = (InstanciatePortletType) a;
                    InstanciatePortletType iptB = (InstanciatePortletType) b;

                    equals &= equals(iptA.getPortletType(), iptB.getPortletType());
                } else if (a instanceof EnumerationLiteral) {
                    Enumeration eContainerA = (Enumeration) a.eContainer();
                    Enumeration eContainerB = (Enumeration) b.eContainer();
                    equals &= equals(eContainerA, eContainerB);

                    equals &= ((EnumerationLiteral) a).getName().equals(((EnumerationLiteral) b).getName());
                    equals &= ((EnumerationLiteral) a).getValue().equals(((EnumerationLiteral) b).getValue());
                } else {
                    //               System.out.println("ModelMigrationHelper.equals() not managed to be compared NEED TO BE ADDED TO CONTROLER :" + a.getClass());
                    throw new UnsupportedOperationException(
                            "equals on " + a.getClass() + " is not supported this need to be implemented");
                }
            }
        }
        return equals;
    }

    protected static String avoid40_42_missmatchs(String fullNameA) {
        String replaceAll = fullNameA.replaceAll("\\.@markup", "");
        return replaceAll;
    }

    public static boolean isInSameNS(ModelElement a, ModelElement b) throws RootElementException {
        return getCompliteNS(a).equals(getCompliteNS(b));
    }

    public static String getCompliteNS(ModelElement a) throws RootElementException {
        NameSpace logicalNameSpace = a.getLogicalNameSpace();
        if (logicalNameSpace != null) {
            return "{" + logicalNameSpace.getURI() + "}" + logicalNameSpace.getPrefix();
        } else {
            String name = getRootName(a);
            if (name == null) {
                throw new RootElementException("Root element is Null, please to check and Fix your models");
            }
            // System.out.println("ModelMigrationHelper.getCompliteNS() no NS object so use rootElement name as NS :" + name);
            return name;
        }

    }

    protected static String getRootName(EObject a) {
        return ((NamedModelElement) EcoreUtil.getRootContainer(a, true)).getName();
    }

    class ComparableEObject {
        EObject eObject;

        public ComparableEObject(EObject eObject) {
            this.eObject = eObject;
        }

        /*
         * (non-Javadoc)
         * @see java.lang.Object#equals(java.lang.Object)
         */
        @Override
        public boolean equals(Object arg0) {
            if (arg0 instanceof ComparableEObject) {
                try {
                    return ModelMigrationHelper.equals(eObject, ((ComparableEObject) arg0).eObject);
                } catch (RootElementException e) {
                    throw new EqualsException(e.getMessage(), e.getCause());
                }
            } else {
                return false;
            }
        }
    }
}