### Eclipse Workspace Patch 1.0
#P org.eclipse.gmf.codegen.reconciler
Index: src/org/eclipse/gmf/codegen/reconciler/ReconcilerConfig.java
===================================================================
RCS file: src/org/eclipse/gmf/codegen/reconciler/ReconcilerConfig.java
diff -N src/org/eclipse/gmf/codegen/reconciler/ReconcilerConfig.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/gmf/codegen/reconciler/ReconcilerConfig.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2006 Borland Software Corporation
+ *
+ * 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:
+ * Michael Golubev (Borland) - initial API and implementation
+ */
+
+package org.eclipse.gmf.codegen.reconciler;
+
+import org.eclipse.emf.ecore.EClass;
+
+public interface ReconcilerConfig {
+ Matcher getMatcher(EClass eClass);
+ DecisionMaker[] getDecisionMakers(EClass eClass);
+}
Index: build.properties
===================================================================
RCS file: build.properties
diff -N build.properties
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ build.properties 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
Index: src/org/eclipse/gmf/codegen/reconciler/StringPatternDecisionMaker.java
===================================================================
RCS file: src/org/eclipse/gmf/codegen/reconciler/StringPatternDecisionMaker.java
diff -N src/org/eclipse/gmf/codegen/reconciler/StringPatternDecisionMaker.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/gmf/codegen/reconciler/StringPatternDecisionMaker.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2006 Borland Software Corporation
+ *
+ * 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:
+ * Michael Golubev (Borland) - initial API and implementation
+ */
+
+package org.eclipse.gmf.codegen.reconciler;
+
+import java.util.regex.Pattern;
+
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EcorePackage;
+
+public class StringPatternDecisionMaker extends DecisionMaker {
+ private Pattern myPattern;
+
+ public StringPatternDecisionMaker(String valuePattern, EAttribute attribute){
+ this(Pattern.compile(valuePattern), attribute);
+ }
+
+ public StringPatternDecisionMaker(Pattern valuePattern, EAttribute attribute){
+ super(attribute);
+ if (attribute.getEAttributeType() != EcorePackage.eINSTANCE.getEString()){
+ throw new IllegalArgumentException("Expected string attribute");
+ }
+ if (attribute.getUpperBound() != 1){
+ throw new IllegalArgumentException("Expected multiplicity [0..1] or [1]");
+ }
+ myPattern = valuePattern;
+ }
+
+ public Decision makeDecision(EObject current, EObject old) {
+ String oldValue = (String)old.eGet(getFeature());
+ if (oldValue != null && !myPattern.matcher(oldValue).matches()){
+ return Decision.PRESERVE_OLD;
+ } else {
+ return Decision.ACCEPT_NEW;
+ }
+ }
+
+}
Index: src/org/eclipse/gmf/codegen/reconciler/AttributeMatcher.java
===================================================================
RCS file: src/org/eclipse/gmf/codegen/reconciler/AttributeMatcher.java
diff -N src/org/eclipse/gmf/codegen/reconciler/AttributeMatcher.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/gmf/codegen/reconciler/AttributeMatcher.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2006 Borland Software Corporation
+ *
+ * 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:
+ * Michael Golubev (Borland) - initial API and implementation
+ */
+
+package org.eclipse.gmf.codegen.reconciler;
+
+import java.text.MessageFormat;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+public class AttributeMatcher implements Matcher {
+ private final String myFeatureName;
+ private EClass myCachedFeatureOwner;
+ private EStructuralFeature myCachedFeature;
+
+ public AttributeMatcher(String featureName){
+ myFeatureName = featureName;
+ }
+
+ public AttributeMatcher(EStructuralFeature feature){
+ this(feature.getName());
+ }
+
+ public boolean match(EObject current, EObject old) {
+ assertCompatible(current, old);
+ EStructuralFeature feature = findFeature(current.eClass());
+ return safeEquals(current.eGet(feature), old.eGet(feature));
+ }
+
+ private void assertCompatible(EObject current, EObject old){
+ if (!current.eClass().equals(old.eClass())){
+ throw new IllegalStateException(MessageFormat.format("Objects not compatible: {0}, {1}", new Object[] {current, old}));
+ }
+ }
+
+ private EStructuralFeature findFeature(EClass eClass){
+ if (!eClass.equals(myCachedFeatureOwner)){
+ EStructuralFeature result = eClass.getEStructuralFeature(myFeatureName);
+ if (result == null){
+ throw new IllegalStateException(MessageFormat.format("Unknown feature {0} in EClass {1}", new Object[] {myFeatureName, eClass}));
+ }
+ myCachedFeatureOwner = eClass;
+ myCachedFeature = result;
+ }
+ return myCachedFeature;
+ }
+
+ private boolean safeEquals(Object first, Object second){
+ return first == null ? second == null : first.equals(second);
+ }
+
+}
Index: src/org/eclipse/gmf/codegen/reconciler/ReconcilerConfigBase.java
===================================================================
RCS file: src/org/eclipse/gmf/codegen/reconciler/ReconcilerConfigBase.java
diff -N src/org/eclipse/gmf/codegen/reconciler/ReconcilerConfigBase.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/gmf/codegen/reconciler/ReconcilerConfigBase.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2006 Borland Software Corporation
+ *
+ * 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:
+ * Michael Golubev (Borland) - initial API and implementation
+ */
+
+package org.eclipse.gmf.codegen.reconciler;
+
+import java.text.MessageFormat;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EReference;
+
+public class ReconcilerConfigBase implements ReconcilerConfig {
+ private static final EClassRecord EMPTY_RECORD = new EClassRecord();
+ private final HashMap myEClass2Record;
+
+ public ReconcilerConfigBase(){
+ myEClass2Record = new HashMap();
+ }
+
+ public final Matcher getMatcher(EClass eClass) {
+ return getRecord(eClass, false).getMatcher();
+ }
+
+ public final DecisionMaker[] getDecisionMakers(EClass eClass) {
+ return getRecord(eClass, false).getDecisionMakers();
+ }
+
+ protected final void setMatcher(EClass eClass, Matcher matcher){
+ getRecord(eClass, true).setMatcher(matcher);
+ }
+
+ protected final void addDecisionMaker(EClass eClass, DecisionMaker decisionMaker){
+ getRecord(eClass, true).addDecisionMaker(decisionMaker);
+ }
+
+ protected final void setMatcher(EClass eClass, EAttribute attribute){
+ checkStructuralFeature(eClass, attribute);
+ Matcher matcher = new AttributeMatcher(attribute);
+ setMatcher(eClass, matcher);
+ }
+
+ protected final void setMatcher(EClass eClass, EReference reference){
+ if (eClass.getEPackage().equals(reference.eClass().getEPackage())){
+ //XXX: use lazyly resolved matcher???
+ setMatcher(eClass, new AttributeMatcher(reference));
+ } else {
+ setMatcher(eClass, new AttributeMatcher(reference));
+ }
+ }
+
+ private EClassRecord getRecord(EClass eClass, boolean force){
+ EClassRecord result = (EClassRecord) myEClass2Record.get(eClass);
+ if (result == null){
+ if (force){
+ result = new EClassRecord();
+ myEClass2Record.put(eClass, result);
+ } else {
+ result = EMPTY_RECORD;
+ }
+ }
+ return result;
+ }
+
+ private void checkStructuralFeature(EClass expectedClass, EAttribute feature) {
+ if (expectedClass.getEStructuralFeature(feature.getFeatureID()) != feature){
+ throw new IllegalArgumentException(MessageFormat.format("Alien feature {0} for EClass {1}", new Object[] {feature, expectedClass}));
+ }
+ }
+
+ private static class EClassRecord {
+ private Matcher myMatcher = Matcher.FALSE;
+ private final List myDecisionMakers = new LinkedList();
+ private DecisionMaker[] myMakersArray;
+
+ public void addDecisionMaker(DecisionMaker maker){
+ myDecisionMakers.add(maker);
+ makersSetChanged();
+ }
+
+ public DecisionMaker[] getDecisionMakers(){
+ if (myMakersArray == null){
+ myMakersArray = (DecisionMaker[]) myDecisionMakers.toArray(new DecisionMaker[myDecisionMakers.size()]);
+ }
+ return myMakersArray;
+ }
+
+ public void setMatcher(Matcher matcher) {
+ myMatcher = matcher;
+ }
+
+ public Matcher getMatcher() {
+ return myMatcher;
+ }
+
+ private void makersSetChanged(){
+ myMakersArray = null;
+ }
+ }
+
+}
Index: .project
===================================================================
RCS file: .project
diff -N .project
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ .project 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,28 @@
+
+
+ org.eclipse.gmf.codegen.reconciler
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+
+
Index: META-INF/MANIFEST.MF
===================================================================
RCS file: META-INF/MANIFEST.MF
diff -N META-INF/MANIFEST.MF
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ META-INF/MANIFEST.MF 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,11 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.gmf.codegen.reconciler
+Bundle-Version: 1.0.0.version
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Require-Bundle: org.eclipse.emf.ecore,
+ org.eclipse.gmf.codegen
+Export-Package: org.eclipse.gmf.codegen.reconciler,
+ org.eclipse.gmf.internal.codegen.reconciler
Index: src/org/eclipse/gmf/codegen/reconciler/DefaultDecisionMaker.java
===================================================================
RCS file: src/org/eclipse/gmf/codegen/reconciler/DefaultDecisionMaker.java
diff -N src/org/eclipse/gmf/codegen/reconciler/DefaultDecisionMaker.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/gmf/codegen/reconciler/DefaultDecisionMaker.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2006 Borland Software Corporation
+ *
+ * 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:
+ * Michael Golubev (Borland) - initial API and implementation
+ */
+
+package org.eclipse.gmf.codegen.reconciler;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+public class DefaultDecisionMaker extends DecisionMaker {
+ public DefaultDecisionMaker(EStructuralFeature feature){
+ super(feature);
+ }
+
+ public Decision makeDecision(EObject current, EObject old) {
+ assert current.eClass().equals(old.eClass());
+ return (!current.eIsSet(getFeature()) && old.eIsSet(getFeature())) ? Decision.PRESERVE_OLD : Decision.ACCEPT_NEW;
+ }
+
+}
Index: src/org/eclipse/gmf/codegen/reconciler/Matcher.java
===================================================================
RCS file: src/org/eclipse/gmf/codegen/reconciler/Matcher.java
diff -N src/org/eclipse/gmf/codegen/reconciler/Matcher.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/gmf/codegen/reconciler/Matcher.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2006 Borland Software Corporation
+ *
+ * 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:
+ * Michael Golubev (Borland) - initial API and implementation
+ */
+
+package org.eclipse.gmf.codegen.reconciler;
+
+import java.util.Collection;
+
+import org.eclipse.emf.ecore.EObject;
+
+public interface Matcher {
+ public boolean match(EObject current, EObject old);
+
+ public static final Matcher FALSE = new Matcher() {
+ public boolean match(EObject current, EObject old) {
+ return false;
+ }
+ };
+
+ public static class OR implements Matcher {
+ private final Matcher[] myMatchers;
+
+ public OR(Matcher[] matchers){
+ myMatchers = matchers;
+ }
+
+ public OR(Collection matchers){
+ this((Matcher[])matchers.toArray(new Matcher[matchers.size()]));
+ }
+
+ public boolean match(EObject current, EObject old) {
+ boolean result = false;
+ for (int i = 0; !result && i < myMatchers.length; i++){
+ result = myMatchers[i].match(current, old);
+ }
+ return result;
+ }
+ }
+
+ public static class AND implements Matcher {
+ private final Matcher[] myMatchers;
+
+ public AND(Matcher[] matchers){
+ myMatchers = matchers;
+ }
+
+ public AND(Collection matchers){
+ this((Matcher[])matchers.toArray(new Matcher[matchers.size()]));
+ }
+
+ public boolean match(EObject current, EObject old) {
+ boolean result = true;
+ for (int i = 0; result && i < myMatchers.length; i++){
+ result = myMatchers[i].match(current, old);
+ }
+ return result;
+ }
+ }
+
+}
Index: src/org/eclipse/gmf/codegen/reconciler/Reconciler.java
===================================================================
RCS file: src/org/eclipse/gmf/codegen/reconciler/Reconciler.java
diff -N src/org/eclipse/gmf/codegen/reconciler/Reconciler.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/gmf/codegen/reconciler/Reconciler.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2006 Borland Software Corporation
+ *
+ * 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:
+ * Michael Golubev (Borland) - initial API and implementation
+ */
+
+package org.eclipse.gmf.codegen.reconciler;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+
+public class Reconciler {
+ private final ReconcilerConfig myConfig;
+
+ public Reconciler(ReconcilerConfig config){
+ myConfig = config;
+ }
+
+ protected void handleNotMatchedCurrent(EObject current){
+ //FIXME ??? Is it user escape -- check history ???
+ //FIXME How to handle not macthed old ???
+ }
+
+ public void reconcileResource(Resource current, Resource old){
+ reconcileContents(current.getContents(), old.getContents());
+ }
+
+ public void reconcileTree(EObject currentRoot, EObject oldRoot){
+ reconcileVertex(currentRoot, oldRoot);
+ reconcileContents(currentRoot.eContents(), oldRoot.eContents());
+ }
+
+ private void reconcileVertex(EObject current, EObject old){
+ assert current.eClass().equals(old.eClass());
+ DecisionMaker[] decisionMakers = myConfig.getDecisionMakers(current.eClass());
+ for (int i = 0; i < decisionMakers.length; i++){
+ DecisionMaker next = decisionMakers[i];
+ Decision decision = next.makeDecision(current, old);
+ decision.apply(current, old, next.getFeature());
+ }
+ }
+
+ private void reconcileContents(Collection allCurrents, Collection allOlds){
+ for (Iterator currentContents = allCurrents.iterator(); currentContents.hasNext();){
+ EObject nextCurrent = (EObject) currentContents.next();
+ EObject nextOld = findMatched(nextCurrent, allOlds);
+ if (nextOld == null){
+ handleNotMatchedCurrent(nextCurrent);
+ } else {
+ reconcileTree(nextCurrent, nextOld);
+ }
+ }
+ }
+
+ private EObject findMatched(EObject current, Collection allOld){
+ EClass eClass = current.eClass();
+ Matcher matcher = myConfig.getMatcher(eClass);
+ EObject result = null;
+ if (matcher != Matcher.FALSE){
+ for (Iterator all = allOld.iterator(); result == null && all.hasNext();){
+ EObject next = (EObject)all.next();
+ if (eClass.equals(eClass) && matcher.match(current, next)){
+ result = next;
+ }
+ }
+ }
+ return result;
+ }
+
+}
Index: plugin.properties
===================================================================
RCS file: plugin.properties
diff -N plugin.properties
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ plugin.properties 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,20 @@
+#
+#
+#
+# $Id$
+
+# ====================================================================
+# To code developer:
+# Do NOT change the properties between this line and the
+# "%%% END OF TRANSLATED PROPERTIES %%%" line.
+# Make a new property name, append to the end of the file and change
+# the code to use the new property.
+# ====================================================================
+
+# ====================================================================
+# %%% END OF TRANSLATED PROPERTIES %%%
+# ====================================================================
+
+pluginName = GMFGen Reconciler Plugin
+providerName = Eclipse.org
+
Index: src/org/eclipse/gmf/codegen/reconciler/DecisionMaker.java
===================================================================
RCS file: src/org/eclipse/gmf/codegen/reconciler/DecisionMaker.java
diff -N src/org/eclipse/gmf/codegen/reconciler/DecisionMaker.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/gmf/codegen/reconciler/DecisionMaker.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2006 Borland Software Corporation
+ *
+ * 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:
+ * Michael Golubev (Borland) - initial API and implementation
+ */
+
+package org.eclipse.gmf.codegen.reconciler;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+public abstract class DecisionMaker {
+ private final EStructuralFeature myFeature;
+
+ public abstract Decision makeDecision(EObject current, EObject old);
+
+ public DecisionMaker(EStructuralFeature feature){
+ myFeature = feature;
+ }
+
+ public final EStructuralFeature getFeature(){
+ return myFeature;
+ }
+
+ public static class ALWAYS_OLD extends DecisionMaker {
+ public ALWAYS_OLD(EStructuralFeature feature){
+ super(feature);
+ }
+
+ public Decision makeDecision(EObject current, EObject old) {
+ return Decision.PRESERVE_OLD;
+ }
+ }
+
+ public static class ALWAYS_NEW extends DecisionMaker {
+ public ALWAYS_NEW(EStructuralFeature feature){
+ super(feature);
+ }
+
+ public Decision makeDecision(EObject current, EObject old) {
+ return Decision.ACCEPT_NEW;
+ }
+ }
+
+}
Index: src/org/eclipse/gmf/codegen/reconciler/Decision.java
===================================================================
RCS file: src/org/eclipse/gmf/codegen/reconciler/Decision.java
diff -N src/org/eclipse/gmf/codegen/reconciler/Decision.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/gmf/codegen/reconciler/Decision.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2006 Borland Software Corporation
+ *
+ * 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:
+ * Michael Golubev (Borland) - initial API and implementation
+ */
+
+package org.eclipse.gmf.codegen.reconciler;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+public interface Decision {
+ public void apply(EObject current, EObject old, EStructuralFeature feature);
+
+ public static final Decision PRESERVE_OLD = new Decision(){
+ public void apply(EObject current, EObject old, EStructuralFeature feature) {
+ Object oldValue = old.eGet(feature, true);
+ current.eSet(feature, oldValue);
+ }
+ };
+
+ public static final Decision ACCEPT_NEW = new Decision(){
+ public void apply(EObject current, EObject old, EStructuralFeature feature) {
+ //do nothing
+ }
+ };
+}
Index: src/org/eclipse/gmf/internal/codegen/reconciler/GMFGenConfig.java
===================================================================
RCS file: src/org/eclipse/gmf/internal/codegen/reconciler/GMFGenConfig.java
diff -N src/org/eclipse/gmf/internal/codegen/reconciler/GMFGenConfig.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/gmf/internal/codegen/reconciler/GMFGenConfig.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2006 Borland Software Corporation
+ *
+ * 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:
+ * Michael Golubev (Borland) - initial API and implementation
+ */
+
+package org.eclipse.gmf.internal.codegen.reconciler;
+
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.gmf.codegen.gmfgen.GMFGenPackage;
+import org.eclipse.gmf.codegen.reconciler.DefaultDecisionMaker;
+import org.eclipse.gmf.codegen.reconciler.Matcher;
+import org.eclipse.gmf.codegen.reconciler.ReconcilerConfigBase;
+
+public class GMFGenConfig extends ReconcilerConfigBase {
+ private static final GMFGenPackage GMFGEN = GMFGenPackage.eINSTANCE;
+
+ public GMFGenConfig(){
+ setMatcher(GMFGEN.getGenEditorGenerator(), ALWAYS_MATCH);
+ preserveIfSet(GMFGEN.getGenEditorGenerator(), GMFGEN.getGenEditorGenerator_CopyrightText());
+ preserveIfSet(GMFGEN.getGenEditorGenerator(), GMFGEN.getGenEditorGenerator_PackageNamePrefix());
+ preserveIfSet(GMFGEN.getGenEditorGenerator(), GMFGEN.getGenEditorGenerator_DiagramFileExtension());
+ preserveIfSet(GMFGEN.getGenEditorGenerator(), GMFGEN.getGenEditorGenerator_SameFileForDiagramAndModel());
+
+ setMatcher(GMFGEN.getGenPlugin(), ALWAYS_MATCH); //exactly one feature for ALWAYS_MATCH GenEditorGenerator
+ preserveIfSet(GMFGEN.getGenPlugin(), GMFGEN.getGenPlugin_Provider());
+ preserveIfSet(GMFGEN.getGenPlugin(), GMFGEN.getGenPlugin_Version());
+ }
+
+ private void preserveIfSet(EClass eClass, EAttribute feature){
+ //FIXME: only attributes for now, allow references
+ addDecisionMaker(eClass, new DefaultDecisionMaker(feature));
+ }
+
+ private static final Matcher ALWAYS_MATCH = new Matcher(){
+ public boolean match(EObject current, EObject old) {
+ return current.eClass().equals(old.eClass());
+ }
+ };
+
+}
Index: .classpath
===================================================================
RCS file: .classpath
diff -N .classpath
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ .classpath 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
#P org.eclipse.gmf.codegen.ui
Index: src/org/eclipse/gmf/internal/codegen/popup/actions/TransformToGenModel.java
===================================================================
RCS file: /cvsroot/technology/org.eclipse.gmf/plugins/org.eclipse.gmf.codegen.ui/src/org/eclipse/gmf/internal/codegen/popup/actions/TransformToGenModel.java,v
retrieving revision 1.15
diff -u -r1.15 TransformToGenModel.java
--- src/org/eclipse/gmf/internal/codegen/popup/actions/TransformToGenModel.java 15 Feb 2006 14:04:08 -0000 1.15
+++ src/org/eclipse/gmf/internal/codegen/popup/actions/TransformToGenModel.java 10 Mar 2006 18:59:52 -0000
@@ -15,6 +15,7 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import org.eclipse.core.resources.IFile;
@@ -45,8 +46,10 @@
import org.eclipse.gmf.bridge.genmodel.GenModelAccess;
import org.eclipse.gmf.bridge.genmodel.SpecificDiagramRunTimeModelHelper;
import org.eclipse.gmf.codegen.gmfgen.GenEditorGenerator;
+import org.eclipse.gmf.codegen.reconciler.Reconciler;
import org.eclipse.gmf.internal.bridge.naming.gen.GenModelNamingMediatorImpl;
import org.eclipse.gmf.internal.codegen.CodeGenUIPlugin;
+import org.eclipse.gmf.internal.codegen.reconciler.GMFGenConfig;
import org.eclipse.gmf.mappings.Mapping;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.ErrorDialog;
@@ -131,13 +134,19 @@
}
protected IStatus run(IProgressMonitor monitor) {
- monitor.beginTask(getName(), 3);
+ monitor.beginTask(getName(), 4);
try {
GenEditorGenerator genEditor = transform(mapping);
monitor.worked(1);
if (monitor.isCanceled()) {
return Status.CANCEL_STATUS;
}
+
+ reconcile(genEditor);
+ monitor.worked(1);
+ if (monitor.isCanceled()) {
+ return Status.CANCEL_STATUS;
+ }
save(genEditor);
monitor.worked(1);
@@ -172,6 +181,28 @@
dgmmRes.getContents().add(genBurdern);
dgmmRes.save(getSaveOptions());
}
+
+ private void reconcile(GenEditorGenerator genBurdern) {
+ GenEditorGenerator old = null;
+ Resource resource = null;
+ try {
+ resource = resSet.getResource(getGenModelURI(), true);
+ List contents = resource.getContents();
+ if (!contents.isEmpty() && contents.get(0) instanceof GenEditorGenerator){
+ old = (GenEditorGenerator)contents.get(0);
+ }
+ } catch (RuntimeException e){
+ old = null;
+ } finally {
+ if (resource != null){
+ resource.unload();
+ }
+ }
+
+ if (old != null){
+ new Reconciler(new GMFGenConfig()).reconcileTree(genBurdern, old);
+ }
+ }
}.schedule();
}
Index: META-INF/MANIFEST.MF
===================================================================
RCS file: /cvsroot/technology/org.eclipse.gmf/plugins/org.eclipse.gmf.codegen.ui/META-INF/MANIFEST.MF,v
retrieving revision 1.14
diff -u -r1.14 MANIFEST.MF
--- META-INF/MANIFEST.MF 1 Mar 2006 14:20:27 -0000 1.14
+++ META-INF/MANIFEST.MF 10 Mar 2006 18:59:52 -0000
@@ -9,7 +9,8 @@
org.eclipse.core.runtime,
org.eclipse.core.resources,
org.eclipse.gmf.bridge,
- org.eclipse.gmf.codegen.edit
+ org.eclipse.gmf.codegen.edit,
+ org.eclipse.gmf.codegen.reconciler
Eclipse-LazyStart: true
Bundle-Vendor: %providerName
Export-Package: org.eclipse.gmf.internal.codegen.popup.actions;x-friends:="org.eclipse.gmf.bridge.ui.dashboard"
#P org.eclipse.gmf.codegen.reconciler.test.taipan
Index: build.properties
===================================================================
RCS file: build.properties
diff -N build.properties
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ build.properties 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
Index: .classpath
===================================================================
RCS file: .classpath
diff -N .classpath
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ .classpath 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
Index: META-INF/MANIFEST.MF
===================================================================
RCS file: META-INF/MANIFEST.MF
diff -N META-INF/MANIFEST.MF
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ META-INF/MANIFEST.MF 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,14 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Reconciler Tests Plugin
+Bundle-SymbolicName: org.eclipse.gmf.codegen.reconciler.test.taipan
+Bundle-Version: 1.0.0.version
+Bundle-Vendor: Eclipse.org
+Bundle-Localization: plugin
+Require-Bundle: org.eclipse.gmf.codegen,
+ org.eclipse.gmf.codegen.reconciler,
+ org.eclipse.gmf.examples.taipan,
+ org.junit,
+ org.eclipse.osgi,
+ org.eclipse.core.runtime,
+ org.eclipse.gmf.bridge
Index: src/org/eclipse/gmf/codegen/reconciler/test/ReconcileTaipanTest.java
===================================================================
RCS file: src/org/eclipse/gmf/codegen/reconciler/test/ReconcileTaipanTest.java
diff -N src/org/eclipse/gmf/codegen/reconciler/test/ReconcileTaipanTest.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/gmf/codegen/reconciler/test/ReconcileTaipanTest.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2006 Borland Software Corporation
+ *
+ * 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:
+ * Michael Golubev (Borland) - initial API and implementation
+ */
+
+package org.eclipse.gmf.codegen.reconciler.test;
+
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+import org.eclipse.gmf.codegen.gmfgen.GenEditorGenerator;
+import org.eclipse.gmf.codegen.gmfgen.GenPlugin;
+import org.eclipse.gmf.codegen.reconciler.Reconciler;
+import org.eclipse.gmf.internal.codegen.reconciler.GMFGenConfig;
+
+public class ReconcileTaipanTest extends TestCase {
+ public void testLoadGMFGen() throws Exception {
+ GenEditorGenerator original = loadTaipanGMFGen();
+ assertNotNull(original);
+ GenEditorGenerator copy = loadTaipanGMFGen();
+ assertNotNull(copy);
+
+ assertFalse(original == copy);
+ assertFalse(original.equals(copy));
+
+ assertEquals(original.getCopyrightText(), copy.getCopyrightText());
+ assertEquals(original.isSameFileForDiagramAndModel(), copy.isSameFileForDiagramAndModel());
+ assertEquals(original.getPackageNamePrefix(), copy.getPackageNamePrefix());
+
+ final String NEW_VALUE = "New Value";
+ copy.setCopyrightText(NEW_VALUE);
+ assertEquals(copy.getCopyrightText(), NEW_VALUE);
+ assertFalse(copy.getCopyrightText().equals(original.getCopyrightText()));
+ }
+
+ public void testReconcileDeepElementWithAlwaysMatcher() throws Exception {
+ GenPlugin old = loadTaipanGMFGen().getPlugin();
+ GenPlugin current = loadTaipanGMFGen().getPlugin();
+
+ assertNotNull(old.getProvider());
+ assertNotNull(old.getVersion());
+
+ final String NEW_PROVIDER = "NewProviderValue";
+ final String NEW_VERSION = "NewVersionValue";
+
+ old.setProvider(NEW_PROVIDER);
+ old.setVersion(NEW_VERSION);
+
+ getReconciler().reconcileTree(current, old);
+
+ assertEquals(NEW_PROVIDER, current.getProvider());
+ assertEquals(NEW_VERSION, current.getVersion());
+ }
+
+ public void testReconcileGenEditorGenerator() throws Exception {
+ GenEditorGenerator old = loadTaipanGMFGen();
+ GenEditorGenerator current = loadTaipanGMFGen();
+
+ old.setCopyrightText("AAA");
+ old.setPackageNamePrefix("BBB");
+ old.setDiagramFileExtension("CCC");
+
+ boolean sameFile = !old.isSameFileForDiagramAndModel();
+ old.setSameFileForDiagramAndModel(sameFile);
+
+ //we do not reconcile this now
+ old.setTemplateDirectory("DDD");
+ assertEquals("DDD", old.getTemplateDirectory());
+
+ getReconciler().reconcileTree(current, old);
+
+ assertEquals("AAA", current.getCopyrightText());
+ assertEquals("BBB", current.getPackageNamePrefix());
+ assertEquals("CCC", current.getDiagramFileExtension());
+ assertEquals(sameFile, current.isSameFileForDiagramAndModel());
+
+ assertEquals("DDD", old.getTemplateDirectory());
+ assertFalse("DDD".equals(current.getTemplateDirectory()));
+ }
+
+ private Reconciler getReconciler(){
+ return new Reconciler(new GMFGenConfig());
+ }
+
+ private GenEditorGenerator loadTaipanGMFGen() throws IOException{
+ return new TaipanSuite().createTaipanEditorGenerator();
+ }
+}
Index: .project
===================================================================
RCS file: .project
diff -N .project
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ .project 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,28 @@
+
+
+ org.eclipse.gmf.codegen.reconciler.test.taipan
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+
+
Index: src/org/eclipse/gmf/codegen/reconciler/test/TaipanSuite.java
===================================================================
RCS file: src/org/eclipse/gmf/codegen/reconciler/test/TaipanSuite.java
diff -N src/org/eclipse/gmf/codegen/reconciler/test/TaipanSuite.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/gmf/codegen/reconciler/test/TaipanSuite.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2006 Borland Software Corporation
+ *
+ * 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:
+ * Michael Golubev (Borland) - initial API and implementation
+ */
+
+package org.eclipse.gmf.codegen.reconciler.test;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.HashSet;
+import java.util.Iterator;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.emf.codegen.ecore.genmodel.GenModel;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.gmf.bridge.genmodel.BasicDiagramRunTimeModelHelper;
+import org.eclipse.gmf.bridge.genmodel.BasicGenModelAccess;
+import org.eclipse.gmf.bridge.genmodel.DiagramGenModelTransformer;
+import org.eclipse.gmf.bridge.genmodel.DiagramRunTimeModelHelper;
+import org.eclipse.gmf.codegen.gmfgen.GenEditorGenerator;
+import org.eclipse.gmf.internal.bridge.naming.gen.GenModelNamingMediatorImpl;
+import org.eclipse.gmf.mappings.Mapping;
+import org.osgi.framework.Bundle;
+
+public class TaipanSuite {
+ private static final String TAIPAN = "org.eclipse.gmf.examples.taipan";
+
+ private final Bundle myBundle;
+ private final ResourceSet myResourceSet;
+
+ public TaipanSuite(){
+ myResourceSet = new ResourceSetImpl();
+ myBundle = Platform.getBundle(TAIPAN);
+ if (myBundle == null){
+ throw new IllegalStateException();
+ }
+ }
+
+ public GenEditorGenerator createTaipanEditorGenerator() throws IOException{
+ Mapping mapping = (Mapping) loadResource("/models/taipan.gmfmap").getContents().get(0);
+ BasicGenModelAccess gma = getGenModelAccess(mapping);
+ gma.initDefault();
+ gma.load(myResourceSet);
+ GenModel domainGenModel = gma.model();
+ DiagramRunTimeModelHelper drtHelper = new BasicDiagramRunTimeModelHelper();
+ DiagramGenModelTransformer transformer = new DiagramGenModelTransformer(drtHelper, new GenModelNamingMediatorImpl());
+ if (domainGenModel != null) {
+ transformer.setEMFGenModel(domainGenModel);
+ }
+ transformer.transform(mapping);
+ GenEditorGenerator result = transformer.getResult();
+ return result;
+ }
+
+ public Resource loadResource(String relativePath) throws IOException{
+ URL resolvedUrl = FileLocator.resolve(myBundle.getEntry(relativePath));
+ URI uri = URI.createURI(resolvedUrl.toString());
+ return myResourceSet.getResource(uri, true);
+ }
+
+ public BasicGenModelAccess getGenModelAccess(Mapping mapping) {
+ HashSet packages = new HashSet();
+ for (Iterator it = EcoreUtil.ExternalCrossReferencer.find(mapping).keySet().iterator(); it.hasNext();) {
+ Object next = it.next();
+ if (next instanceof EClass) {
+ packages.add(((EClass) next).getEPackage());
+ }
+ }
+ for (Iterator it = packages.iterator(); it.hasNext();) {
+ EPackage next = (EPackage) it.next();
+ if (next.getESuperPackage() != null && EcoreUtil.isAncestor(packages, next.getESuperPackage())) {
+ it.remove();
+ }
+ }
+ if (packages.isEmpty()) {
+ throw new IllegalStateException("Mapping without domain model");
+ }
+ if (packages.size() != 1) {
+ throw new IllegalStateException("Too many packages");
+ }
+ EPackage theOnly = (EPackage) packages.iterator().next();
+ return new BasicGenModelAccess(theOnly);
+ }
+
+}