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.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(); } }