metabup.annotations.general.Annotation.java Source code

Java tutorial

Introduction

Here is the source code for metabup.annotations.general.Annotation.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.annotations.general;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.WordUtils;
import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;

import fragments.FragmentModel;
import metabup.annotations.Activator;
import metabup.annotations.IAnnotation;
import metabup.issues.general.IOpenIssue;
import metabup.metamodel.AnnotatedElement;
import metabup.metamodel.AnnotationParam;
import metabup.metamodel.Attribute;
import metabup.metamodel.Feature;
import metabup.metamodel.MetaClass;
import metabup.metamodel.MetaModel;
import metabup.metamodel.ParamValue;
import metabup.metamodel.Reference;
import metabup.transformations.models.WMetamodelModel;

/**
 * @author Jesus
 *
 */
public abstract class Annotation implements IAnnotation {
    protected String name = null;
    protected String description = null;
    protected boolean persistent = false;

    protected AnnotatedElement element = null;
    protected metabup.metamodel.Annotation annotation = null;
    protected EList<metabup.metamodel.AnnotationParam> annotationParams = null;
    protected WMetamodelModel sourceMetaModel = null;
    protected MetaModel targetMetaModel = null;

    protected List<String> errors = new ArrayList<String>();
    /* it is indexed by the preference modelName. the object represents its default value */
    public HashMap<String, Object> preferences = new HashMap<String, Object>();
    private boolean activeMode = true;

    public final void run(boolean activeMode) {
        this.activeMode = activeMode;
        if (name != null)
            if (let(element, sourceMetaModel, targetMetaModel))
                if (when())
                    targetMetaModel = perform();
    }

    public final boolean let(AnnotatedElement element, WMetamodelModel sourceMetaModel, MetaModel targetMetaModel) {
        if (element == null || sourceMetaModel == null || targetMetaModel == null || name == null)
            return false;

        this.setElement(element);
        this.setSourceMetaModel(sourceMetaModel);
        this.setTargetMetaModel(targetMetaModel);

        EList<metabup.metamodel.Annotation> ann = element.getAnnotations();

        for (metabup.metamodel.Annotation annotation : ann) {
            if (annotation.getName().toLowerCase().equals(name.toLowerCase())) {
                this.annotation = annotation;
                this.annotationParams = annotation.getParams();
                return true;
            }
        }

        return false;
    }

    public boolean isActiveMode() {
        return activeMode;
    }

    public List<IOpenIssue> detectFragmentIssues(FragmentModel fm, AnnotatedElement ae) {
        return null;
    }

    public class PreferenceInitializer extends AbstractPreferenceInitializer {
        @Override
        public void initializeDefaultPreferences() {
            // TODO Auto-generated method stub
            IPreferenceStore store = Activator.getDefault().getPreferenceStore();

            Iterator it = preferences.entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry e = (Map.Entry) it.next();
                if (e.getValue() instanceof String)
                    store.setDefault((String) e.getKey(), (String) e.getValue());
                else if (e.getValue() instanceof Boolean)
                    store.setDefault((String) e.getKey(), (Boolean) e.getValue());
                else if (e.getValue() instanceof Integer)
                    store.setDefault((String) e.getKey(), (Integer) e.getValue());
            }
        }
    }

    public Object getPreferenceValue(String name) {
        IPreferenceStore store = Activator.getDefault().getPreferenceStore();
        Object value = preferences.get(name);
        if (value == null)
            return null;
        if (value instanceof String)
            return store.getString(name);
        if (value instanceof Boolean)
            return store.getBoolean(name);
        if (value instanceof Integer)
            return store.getInt(name);
        return null;
    }

    protected void initializePreferences() {
        PreferenceInitializer pi = this.new PreferenceInitializer();
        pi.initializeDefaultPreferences();
    }

    protected void addPreference(String name, Object defaultValue) {
        if (defaultValue instanceof String || defaultValue instanceof Boolean || defaultValue instanceof Integer)
            preferences.put(name, defaultValue);
    }

    public HashMap<String, Object> getPreferences() {
        return preferences;
    }

    public boolean isPersistent() {
        return persistent;
    }

    protected void setPersistent(boolean persistent) {
        this.persistent = persistent;
    }

    public boolean when() {
        return true;
    }

    public final String getName() {
        return name;
    }

    public final String getDescription() {
        return description;
    }

    public final MetaModel getTargetMetaModel() {
        return targetMetaModel;
    }

    public void setElement(AnnotatedElement element) {
        this.element = element;
    }

    public final void setSourceMetaModel(WMetamodelModel sourceMetaModel) {
        this.sourceMetaModel = sourceMetaModel;
    }

    public void setTargetMetaModel(MetaModel targetMetaModel) {
        this.targetMetaModel = targetMetaModel;
    }

    public metabup.metamodel.Annotation getAnnotation() {
        return annotation;
    }

    public List<metabup.metamodel.AnnotationParam> getAnnotationParams() {
        return this.annotationParams;
    }

    public void setAnnotation(metabup.metamodel.Annotation annotation) {
        this.annotation = annotation;
    }

    public AnnotatedElement getElement() {
        return element;
    }

    public WMetamodelModel getSourceMetaModel() {
        return sourceMetaModel;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    protected void putError(String error) {
        errors.add(error);
        MessageDialog.openError(null, "Error when applying annotation refactoring", error);
    }

    /*
     * method library set
     */

    /* 
     * METACLASSES 
     * 
     * */

    protected List<MetaClass> allMetaClasses() {
        ArrayList<MetaClass> all = new ArrayList<MetaClass>();

        for (MetaClass c : sourceMetaModel.allMetaClasses()) {
            all.add(c);
        }

        return all;
    }

    protected List<MetaClass> allMetaClassesWithFeatureName(String fName) {
        ArrayList<MetaClass> all = new ArrayList<MetaClass>();

        for (MetaClass c : sourceMetaModel.allMetaClasses()) {
            for (metabup.metamodel.Feature ff : c.getFeatures()) {
                if (ff.getName().equals(fName)) { // TODO: Check also the type...
                    all.add(c);
                    break;
                }
            }
        }

        return all;
    }

    protected List<MetaClass> allMetaClassesWithAnnotation(metabup.metamodel.Annotation a) {
        ArrayList<MetaClass> allMC = new ArrayList<MetaClass>();
        EList<AnnotationParam> annParams = a.getParams();

        for (MetaClass mc : sourceMetaModel.allMetaClasses()) {
            for (metabup.metamodel.Annotation ann : mc.getAnnotations()) {
                if (ann.getName().equals(a.getName())) {
                    boolean ok = true;

                    if (!a.getParams().isEmpty()) {
                        for (metabup.metamodel.AnnotationParam annParam : ann.getParams()) {
                            if (ok) {
                                for (AnnotationParam originalAnnParam : annParams) {
                                    if (ok) {
                                        if (!originalAnnParam.getName().equals(annParam.getName())
                                                || !originalAnnParam.getValue().equals(annParam.getValue())) {
                                            ok = false;
                                        }
                                    }
                                }
                            }
                        }

                        if (ok)
                            allMC.add(mc);
                    } else
                        allMC.add(mc);
                }
            }
        }

        return allMC;
    }

    protected boolean existsMetaClassByName(String name) {
        ArrayList<MetaClass> all = new ArrayList<MetaClass>();

        for (MetaClass mc : sourceMetaModel.allMetaClasses()) {
            if (mc.getName().equals(name))
                return true;
        }

        return false;
    }

    protected MetaClass getMetaClassByName(String name) {
        ArrayList<MetaClass> all = new ArrayList<MetaClass>();

        for (MetaClass mc : sourceMetaModel.allMetaClasses()) {
            if (mc.getName().equals(name))
                return mc;
        }

        return null;
    }

    protected boolean removeMetaClass(MetaClass mc) {
        for (MetaClass othermc : this.targetMetaModel.getClasses()) {
            if (othermc.getSupers().contains(mc)) {
                othermc.getSupers().addAll(mc.getSupers());
                othermc.getSupers().remove(mc);
            }
            if (othermc.getSubclasses().contains(mc)) {
                othermc.getSubclasses().addAll(mc.getSubclasses());
                othermc.getSubclasses().remove(mc);
            }

            for (Feature f : othermc.getFeatures()) {
                if (f instanceof Reference) {
                    Reference r = (Reference) f;
                    if (r.getReference().equals(mc))
                        othermc.getFeatures().remove(r);
                }
            }

            for (Reference r : othermc.getIncomingRefs()) {
                // REMOVE INCOMING REFS!!
            }
        }

        return this.targetMetaModel.getClasses().remove(mc);
    }

    public static List<MetaClass> getCommonSupers(List<MetaClass> mcs) {
        if (mcs == null || mcs.isEmpty())
            return null;
        List<MetaClass> supers = new ArrayList<MetaClass>();
        supers.addAll(mcs.get(0).getSupers());

        for (MetaClass mc : mcs)
            for (MetaClass superMc : mc.getSupers())
                if (!supers.contains(superMc))
                    supers.remove(superMc);

        if (supers.isEmpty())
            return null;
        else
            return supers;
    }

    protected List<Feature> getCommonFeatures(List<MetaClass> mcs) {
        if (mcs == null || mcs.size() == 0)
            return null;
        if (mcs.size() == 1)
            return null;

        List<Feature> commonff = mcs.get(0).getFeatures();
        List<Feature> noncommonff = new ArrayList<Feature>();

        for (MetaClass mc : mcs) {
            for (Feature f1 : commonff) {
                boolean found = false;

                for (int i = 0; !found && i < mc.getFeatures().size(); i++) {
                    Feature f2 = mc.getFeatures().get(i);
                    if (areEqual(f1, f2, false))
                        found = true;
                }

                if (!found && !noncommonff.contains(f1)) {
                    noncommonff.add(f1);
                }
            }
        }

        /* generate copies of the common features */

        List<Feature> retcommonff = new ArrayList<Feature>();

        for (Feature f : commonff) {
            if (!noncommonff.contains(f)) {
                if (f instanceof Reference) {
                    Reference ref = (Reference) EcoreUtil.copy(f);
                    ref.setId(EcoreUtil.generateUUID());
                    retcommonff.add(ref);
                } else {
                    if (f instanceof Attribute) {
                        Attribute att = (Attribute) EcoreUtil.copy(f);
                        att.setId(EcoreUtil.generateUUID());
                        retcommonff.add(att);
                    }
                }
            }
        }

        return retcommonff;
    }

    /*
     * FEATURES
     * 
     */
    protected boolean areEqual(Feature f1, Feature f2, boolean withCardinality) {
        if (f1 instanceof Attribute && f2 instanceof Reference)
            return false;
        if (f1 instanceof Reference && f2 instanceof Attribute)
            return false;
        if (!f1.getName().equals(f2.getName()))
            return false;

        if (withCardinality) {
            if (f1.getMin() != f2.getMin())
                return false;
            if (f1.getMax() != f2.getMax())
                return false;
        }

        if (f1 instanceof Attribute && f2 instanceof Attribute)
            if (!((Attribute) f1).getPrimitiveType().equals(((Attribute) f2).getPrimitiveType()))
                return false;
        if (f1 instanceof Reference && f2 instanceof Reference)
            if (!((Reference) f1).getReference().getId().equals(((Reference) f2).getReference().getId()))
                return false;
        return true;
    }

    protected boolean existsFeatureInMetaClass(Feature f, MetaClass mc) {
        List<Feature> mcff = mc.getFeatures();
        if (mcff.contains(f))
            return true;
        else
            return false;
    }

    protected List<metabup.metamodel.Annotation> removeFeatureWithName(MetaClass cont, String name) {
        for (metabup.metamodel.Feature ff : cont.getFeatures()) {
            if (ff.getName().equals(name)) {
                cont.getFeatures().remove(ff);
                return ff.getAnnotations();
            }
        }
        return new ArrayList<metabup.metamodel.Annotation>();
    }

    protected void removeAnnotationWithName(MetaClass cont, String name) {
        for (metabup.metamodel.Annotation a : cont.getAnnotations()) {
            if (a.getName().equals(name)) {
                cont.getAnnotations().remove(a);
            }
        }
    }

    protected void removeSelfReferences(MetaClass mc) {
        List<Reference> refs = new ArrayList<Reference>();

        for (Feature f : mc.getFeatures()) {
            if (f instanceof Reference) {
                Reference r = (Reference) f;
                if (mc.getId().equals(r.getReference().getId()))
                    refs.add(r);
            }
        }

        mc.getFeatures().removeAll(refs);
    }

    protected void removeReplicatedFeatures(MetaClass mc) {
        List<Feature> ff = mc.getFeatures();
        List<String> ffnames = new ArrayList<String>();
        List<Feature> removeff = new ArrayList<Feature>();
        for (Feature f : ff)
            ffnames.add(f.getName());

        for (Feature f : ff) {
            int occ = Collections.frequency(ffnames, f.getName());
            if (occ > 1) {
                String name = f.getName();
                int i = 1;

                for (Feature f2 : ff) {
                    if (f2.getName().equals(name) && i < occ) {
                        removeff.add(f2);
                        i++;
                    }
                }
            }
        }

        if (!removeff.isEmpty()) {
            mc.getFeatures().removeAll(removeff);
        }
    }

    protected boolean isCompatibleType(metabup.metamodel.Feature f, metabup.metamodel.Feature ff) {
        if (f instanceof metabup.metamodel.Reference && ff instanceof metabup.metamodel.Reference) {
            if (((metabup.metamodel.Reference) f).getReference() != null) // Puede ser null si no se ha resuelto el target... no s si habra que postponer los refactorings al final...
                return ((metabup.metamodel.Reference) f).getReference()
                        .equals(((metabup.metamodel.Reference) ff).getReference());
            return false;
        }
        if (f instanceof metabup.metamodel.Attribute && ff instanceof metabup.metamodel.Attribute) {
            return ((metabup.metamodel.Attribute) f).getPrimitiveType()
                    .equals(((metabup.metamodel.Attribute) ff).getPrimitiveType());
        }
        return false;
    }

    /*
     * REFERENCES
     * 
     */

    protected List<Reference> allReferencesFromMetaClassWithAnnotation(metabup.metamodel.Annotation a,
            metabup.metamodel.MetaClass mc) {
        EList<AnnotationParam> annParams = a.getParams();
        ArrayList<Reference> refs = new ArrayList<Reference>();

        for (Feature f : mc.getFeatures()) {
            if (f instanceof metabup.metamodel.Reference) {
                for (metabup.metamodel.Annotation ann : f.getAnnotations()) {
                    if (ann.getName().equals(a.getName())) {
                        boolean ok = true;

                        if (!a.getParams().isEmpty()) {
                            for (metabup.metamodel.AnnotationParam annParam : ann.getParams()) {
                                if (ok) {
                                    for (AnnotationParam originalAnnParam : annParams) {
                                        if (ok) {
                                            if (!originalAnnParam.getName().equals(annParam.getName())
                                                    || !originalAnnParam.getValue().equals(annParam.getValue())) {
                                                ok = false;
                                            }
                                        }
                                    }
                                }
                            }

                            if (ok)
                                refs.add((Reference) f);
                        } else
                            refs.add((Reference) f);
                    }
                }
            }
        }

        return refs;
    }

    protected List<Reference> allReferencesFromMetaClassWithName(String name, metabup.metamodel.MetaClass mc) {
        ArrayList<Reference> refs = new ArrayList<Reference>();

        for (Feature f : mc.getFeatures()) {
            if (f instanceof metabup.metamodel.Reference) {
                if (f.getName().equals(name))
                    refs.add((Reference) f);
            }
        }

        return refs;
    }

    /*
     * ANNOTATIONS
     * 
     */
    protected ParamValue getAnnotationParamValueByParamName(String name) {
        for (AnnotationParam ap : annotationParams) {
            if (ap.getName().equals(name))
                return ap.getValue();
        }

        return null;
    }

    public static String promptClassName(List<MetaClass> mcs, String suggested) {
        List<String> names = new ArrayList<String>();
        for (MetaClass mc : mcs)
            names.add(mc.getName());
        if (names.isEmpty())
            return suggested;
        InputDialog id = new InputDialog(null, "Generalization to MetaClass", names
                + " are to be generalized to the MetaClass. Type another class name, either new or existing, if you like:",
                suggested, null);
        if (id.open() == InputDialog.OK)
            return id.getValue();
        else
            return suggested;
    }

    /*
     * String and naming conventions
     */

    public static String induceCommonName(List<MetaClass> mcs) {
        List<MetaClass> supers = getCommonSupers(mcs);

        String name = null;

        if (supers == null || (supers.get(0).getSubclasses().size() != mcs.size())) {
            name = calculateCommonName(mcs);
            if (name.equals("") || name.length() < 3)
                name = calculateConcatName(mcs);
        } else
            name = supers.get(0).getName();

        return name;
    }

    public static String calculateCommonName(List<MetaClass> mcs) {
        if (mcs == null || mcs.isEmpty() || mcs.size() < 0)
            return "";
        if (mcs.size() == 1)
            return WordUtils.capitalize(mcs.get(0).getName());
        ArrayList<String> allNames = new ArrayList<String>();
        for (MetaClass mc : mcs)
            allNames.add(mc.getName());
        String name = WordUtils.capitalize(longestSubstring(allNames.get(0), allNames, 1));
        for (MetaClass mc : mcs)
            if (mc.getName().equals(name))
                name = "General" + name;
        return name;
    }

    public static String calculateConcatName(List<MetaClass> mcs) {
        if (mcs.isEmpty() || mcs.size() < 0)
            return "";
        String name = "General";
        for (MetaClass mc : mcs)
            name += mc.getName();
        return name;
    }

    public static String longestSubstring(String pivot, List<String> remain, int index) {
        StringBuilder sb = new StringBuilder();
        String str1 = pivot;
        String str2 = remain.get(index);

        if (str1 == null || str1.isEmpty() || str2 == null || str2.isEmpty())
            return "";

        // ignore case
        str1 = str1.toLowerCase();
        str2 = str2.toLowerCase();

        // java initializes them already with 0
        int[][] num = new int[str1.length()][str2.length()];
        int maxlen = 0;
        int lastSubsBegin = 0;

        for (int i = 0; i < str1.length(); i++) {
            for (int j = 0; j < str2.length(); j++) {
                if (str1.charAt(i) == str2.charAt(j)) {
                    if ((i == 0) || (j == 0))
                        num[i][j] = 1;
                    else
                        num[i][j] = 1 + num[i - 1][j - 1];

                    if (num[i][j] > maxlen) {
                        maxlen = num[i][j];
                        // generate substring from str1 => i
                        int thisSubsBegin = i - num[i][j] + 1;
                        if (lastSubsBegin == thisSubsBegin) {
                            //if the current LCS is the same as the last time this block ran
                            sb.append(str1.charAt(i));
                        } else {
                            //this block resets the string builder if a different LCS is found
                            lastSubsBegin = thisSubsBegin;
                            sb = new StringBuilder();
                            sb.append(str1.substring(lastSubsBegin, i + 1));
                        }
                    }
                }
            }
        }

        if (sb.equals(""))
            return "";
        index++;
        if (index < remain.size())
            return longestSubstring(sb.toString(), remain, index);
        else
            return sb.toString();
    }
}