summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Flicker 2012-11-28 06:03:52 (EST)
committer Malgorzata Janczarska2013-04-03 04:20:50 (EDT)
commitbf225ea8f252cddb2686012f4c44cc8040d627d2 (patch)
tree8e9697e52038851be88397e355ac07a109fa10ed
parent41435564a99c604566f10591e675ce10072b8133 (diff)
downloadeclipse.platform.team-bf225ea8f252cddb2686012f4c44cc8040d627d2.zip
eclipse.platform.team-bf225ea8f252cddb2686012f4c44cc8040d627d2.tar.gz
eclipse.platform.team-bf225ea8f252cddb2686012f4c44cc8040d627d2.tar.bz2
Bug 382427 - Mechanism to inject line compare strategies into merge andchange/9004/1
structure viewers Change-Id: Iec597bd9582933b90f67de94547b4ccdaef9a319
-rw-r--r--bundles/org.eclipse.compare/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/ICompareStrategy.java85
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/contentmergeviewer/TextMergeViewer.java94
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/ChangeCompareStrategyPropertyAction.java122
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareEditorContributor.java61
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareStrategyDescriptor.java102
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareUIPlugin.java140
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/DocLineComparator.java73
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/MergeSourceViewer.java6
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/Utilities.java67
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/merge/DocumentMerger.java23
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/structuremergeviewer/Differencer.java35
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/structuremergeviewer/IStructureCreator3.java46
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/structuremergeviewer/StructureCreator.java91
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/structuremergeviewer/StructureDiffViewer.java23
-rw-r--r--bundles/org.eclipse.compare/plugin.xml1
-rw-r--r--bundles/org.eclipse.compare/schema/compareStrategies.exsd228
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/RangeDifferenceComparator.java8
-rw-r--r--bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/RegexDiffComparator.java6
19 files changed, 1156 insertions, 57 deletions
diff --git a/bundles/org.eclipse.compare/META-INF/MANIFEST.MF b/bundles/org.eclipse.compare/META-INF/MANIFEST.MF
index 016995a..de34052 100644
--- a/bundles/org.eclipse.compare/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.compare/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.compare; singleton:=true
-Bundle-Version: 3.5.400.qualifier
+Bundle-Version: 3.6.0.qualifier
Bundle-Activator: org.eclipse.compare.internal.CompareUIPlugin
Bundle-Vendor: %providerName
Bundle-Localization: plugin
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/ICompareStrategy.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/ICompareStrategy.java
new file mode 100644
index 0000000..82ea5fa
--- /dev/null
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/ICompareStrategy.java
@@ -0,0 +1,85 @@
+package org.eclipse.compare;
+
+import java.util.HashMap;
+
+import org.eclipse.jface.text.IRegion;
+
+/*******************************************************************************
+ * Copyright (c) 2013 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
+ *******************************************************************************/
+
+/**
+ * A strategy that can be used to customize the detection of text differences
+ * via the compareStrategies extension point Strategies are exposed as toggle
+ * actions in the compare viewer.
+ *
+ * @since 3.6
+ */
+public interface ICompareStrategy {
+
+ /**
+ * Key for the <code>String</code> of the line of text being compared.
+ */
+ public static final String THIS_LINE= "THIS_LINE"; //$NON-NLS-1$
+
+ /**
+ * Key for the <code>Character</code> representing contributor of this line.
+ * Value is either 'A' for ancestor, 'L' for left, or 'R' for right.
+ */
+ public static final String THIS_CONTRIBUTOR= "THIS_CONTRIBUTOR"; //$NON-NLS-1$
+
+ /**
+ * Key for the <code>String</code> of the line of text this line is being compared to.
+ */
+ public static final String OTHER_LINE= "OTHER_LINE"; //$NON-NLS-1$
+
+ /**
+ * Key for the <code>Character</code> representing contributor of the other line.
+ * Value is either 'A' for ancestor, 'L' for left, or 'R' for right.
+ */
+ public static final String OTHER_CONTRIBUTOR= "OTHER_CONTRIBUTOR"; //$NON-NLS-1$
+
+ /**
+ * Forwards the current input objects of the compare
+ * @param input the merge viewer input
+ * @param ancestor input into ancestor viewer
+ * @param left input into left viewer
+ * @param right input into right viewer
+ */
+ public void setInput(Object input, Object ancestor, Object left, Object right);
+
+ /**
+ * Identifies the regions of a line of text in a comparison that should
+ * be ignored for comparison purposes.
+ *
+ * @param lineComparison contains values for the keys <CODE>THIS_LINE</CODE>,
+ * <CODE>THIS_CONTRIBUTOR</CODE>, <CODE>OTHER_LINE</CODE>
+ * and <CODE>OTHER_CONTRIBUTOR</CODE>
+ * @return Regions of <code>THIS_LINE</code> to be ignored for comparison purposes.
+ */
+ public IRegion[] ignoreRegions(HashMap lineComparison);
+
+ /**
+ * Returns whether the strategy should be enabled when first initialized
+ *
+ * @return default enablement
+ */
+ public boolean isEnabledInitially();
+
+ /**
+ * Because the comparison routine may compare each line multiple times to other lines,
+ * the ignored regions may need to be calculated multiple times for the same line during
+ * a comparison. If the ignored regions for each line will be the same regardless of what
+ * line it is being compared to, returning <code>true</code> to this method will cause the
+ * ignored region calculations to be re-used and improve the performance of the comparison.
+ * @return ignored region results can be cached
+ */
+ public boolean areIgnoredRegionsReusable();
+}
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/contentmergeviewer/TextMergeViewer.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/contentmergeviewer/TextMergeViewer.java
index 28ee9c1..02395c5 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/contentmergeviewer/TextMergeViewer.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/contentmergeviewer/TextMergeViewer.java
@@ -39,12 +39,15 @@ import org.eclipse.compare.IStreamContentAccessor;
import org.eclipse.compare.ITypedElement;
import org.eclipse.compare.SharedDocumentAdapter;
import org.eclipse.compare.internal.BufferedCanvas;
+import org.eclipse.compare.internal.ChangeCompareStrategyPropertyAction;
import org.eclipse.compare.internal.ChangePropertyAction;
import org.eclipse.compare.internal.CompareEditor;
+import org.eclipse.compare.internal.CompareEditorContributor;
import org.eclipse.compare.internal.CompareEditorSelectionProvider;
import org.eclipse.compare.internal.CompareHandlerService;
import org.eclipse.compare.internal.CompareMessages;
import org.eclipse.compare.internal.ComparePreferencePage;
+import org.eclipse.compare.internal.CompareStrategyDescriptor;
import org.eclipse.compare.internal.CompareUIPlugin;
import org.eclipse.compare.internal.DocumentManager;
import org.eclipse.compare.internal.ICompareContextIds;
@@ -426,6 +429,7 @@ public class TextMergeViewer extends ContentMergeViewer implements IAdaptable {
private TextEditorPropertyAction toggleLineNumbersAction;
private IFindReplaceTarget fFindReplaceTarget;
private ChangePropertyAction fIgnoreWhitespace;
+ private List fCompareStrategyActions = new ArrayList();
private DocumentMerger fMerger;
/** The current diff */
private Diff fCurrentDiff;
@@ -1852,7 +1856,10 @@ public class TextMergeViewer extends ContentMergeViewer implements IAdaptable {
if (fIgnoreWhitespace != null)
fIgnoreWhitespace.dispose();
-
+
+ getCompareConfiguration().setProperty(ChangeCompareStrategyPropertyAction.COMPARE_STRATEGIES_INITIALIZING, Boolean.TRUE);
+ disposeCompareStrategiesActions();
+
if (fSourceViewerDecorationSupport != null) {
for (Iterator iterator = fSourceViewerDecorationSupport.iterator(); iterator.hasNext();) {
((SourceViewerDecorationSupport) iterator.next()).dispose();
@@ -2790,6 +2797,8 @@ public class TextMergeViewer extends ContentMergeViewer implements IAdaptable {
Object input= getInput();
+ configureCompareStrategiesActions(input, ancestor, left, right);
+
Position leftRange= null;
Position rightRange= null;
@@ -3720,6 +3729,85 @@ public class TextMergeViewer extends ContentMergeViewer implements IAdaptable {
fHandlerService.registerAction(toggleLineNumbersAction, ITextEditorActionDefinitionIds.LINENUMBER_TOGGLE);
}
+ private void configureCompareStrategiesActions(Object input, Object ancestor, Object left, Object right) {
+ CompareStrategyDescriptor[] compareStrategyDescriptors = CompareUIPlugin
+ .getDefault().findCompareStrategies(input);
+
+ Object current = getCompareConfiguration().getProperty(ChangeCompareStrategyPropertyAction.COMPARE_STRATEGY_ACTIONS);
+ boolean currentStrategiesMatch = false;
+ if (current!=null && current instanceof List && ((List)current).size()==compareStrategyDescriptors.length) {
+ currentStrategiesMatch = true;
+ List currentStrategyActions = (List)current;
+ for (int i = 0; i<compareStrategyDescriptors.length; i++) {
+ boolean match = false;
+ for (int j=0;j<currentStrategyActions.size();j++) {
+ if (compareStrategyDescriptors[i].getStrategyId().equals(
+ ((ChangeCompareStrategyPropertyAction)currentStrategyActions.get(j)).getStrategyId())) {
+ match = true;
+ break;
+ }
+ }
+ if (!match) {
+ currentStrategiesMatch = false;
+ break;
+ }
+ }
+ }
+
+ if (!currentStrategiesMatch) {
+ getCompareConfiguration().setProperty(ChangeCompareStrategyPropertyAction.COMPARE_STRATEGIES_INITIALIZING, Boolean.TRUE);
+ disposeCompareStrategiesActions();
+ fCompareStrategyActions.clear();
+ for (int i = 0; i<compareStrategyDescriptors.length; i++) {
+ ChangeCompareStrategyPropertyAction compareStrategyAction = new ChangeCompareStrategyPropertyAction(
+ compareStrategyDescriptors[i], getCompareConfiguration());
+ compareStrategyAction.setInput(input, ancestor, left, right);
+ fCompareStrategyActions.add(compareStrategyAction);
+ fLeft.addTextAction(compareStrategyAction);
+ fRight.addTextAction(compareStrategyAction);
+ fAncestor.addTextAction(compareStrategyAction);
+
+ if (getCompareConfiguration().getContainer().getActionBars()!=null) {
+ getCompareConfiguration().getContainer().getActionBars().getToolBarManager().appendToGroup(CompareEditorContributor.STRATEGY_SEPARATOR, compareStrategyAction);
+ }
+ }
+ if (!fCompareStrategyActions.isEmpty() && getCompareConfiguration().getContainer().getActionBars()!=null) {
+ getCompareConfiguration().getContainer().getActionBars().getToolBarManager().markDirty();
+ getCompareConfiguration().getContainer().getActionBars().getToolBarManager().update(true);
+ getCompareConfiguration().getContainer().getActionBars().updateActionBars();
+ }
+ getCompareConfiguration().setProperty(ChangeCompareStrategyPropertyAction.COMPARE_STRATEGY_ACTIONS, fCompareStrategyActions);
+ getCompareConfiguration().setProperty(ChangeCompareStrategyPropertyAction.COMPARE_STRATEGIES_INITIALIZING, null);
+ } else {
+ for (int i = 0; i<fCompareStrategyActions.size(); i++) {
+ ((ChangeCompareStrategyPropertyAction)fCompareStrategyActions.get(i)).setInput(input, ancestor, left, right);
+ }
+ }
+ }
+
+ private void disposeCompareStrategiesActions() {
+ Iterator compareStrategyActionsIterator = fCompareStrategyActions
+ .iterator();
+ while (compareStrategyActionsIterator.hasNext()) {
+ ChangeCompareStrategyPropertyAction compareStrategyAction = (ChangeCompareStrategyPropertyAction) compareStrategyActionsIterator
+ .next();
+ fLeft.removeTextAction(compareStrategyAction);
+ fRight.removeTextAction(compareStrategyAction);
+ fAncestor.removeTextAction(compareStrategyAction);
+ if (getCompareConfiguration().getContainer().getActionBars()!=null) {
+ getCompareConfiguration().getContainer().getActionBars().getToolBarManager().remove(compareStrategyAction.getId());
+ }
+ compareStrategyAction.dispose();
+ }
+ if (!fCompareStrategyActions.isEmpty() && getCompareConfiguration().getContainer().getActionBars()!=null) {
+ getCompareConfiguration().getContainer().getActionBars().getToolBarManager().markDirty();
+ getCompareConfiguration().getContainer().getActionBars().getToolBarManager().update(true);
+ }
+ fCompareStrategyActions.clear();
+ getCompareConfiguration().setProperty(ChangeCompareStrategyPropertyAction.COMPARE_STRATEGIES, null);
+ getCompareConfiguration().setProperty(ChangeCompareStrategyPropertyAction.COMPARE_STRATEGY_ACTIONS, null);
+ }
+
/* (non-Javadoc)
* @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#handlePropertyChangeEvent(org.eclipse.jface.util.PropertyChangeEvent)
*/
@@ -3727,7 +3815,9 @@ public class TextMergeViewer extends ContentMergeViewer implements IAdaptable {
String key= event.getProperty();
if (key.equals(CompareConfiguration.IGNORE_WHITESPACE)
- || key.equals(ComparePreferencePage.SHOW_PSEUDO_CONFLICTS)) {
+ || key.equals(ComparePreferencePage.SHOW_PSEUDO_CONFLICTS)
+ || (key.equals(ChangeCompareStrategyPropertyAction.COMPARE_STRATEGIES) &&
+ getCompareConfiguration().getProperty(ChangeCompareStrategyPropertyAction.COMPARE_STRATEGIES_INITIALIZING)==null)) {
fShowPseudoConflicts= fPreferenceStore.getBoolean(ComparePreferencePage.SHOW_PSEUDO_CONFLICTS);
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/ChangeCompareStrategyPropertyAction.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/ChangeCompareStrategyPropertyAction.java
new file mode 100644
index 0000000..fab2660
--- /dev/null
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/ChangeCompareStrategyPropertyAction.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 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 org.eclipse.compare.internal;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.ResourceBundle;
+
+import org.eclipse.compare.CompareConfiguration;
+import org.eclipse.compare.ICompareStrategy;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+
+/**
+ * Toggles the activation of a compare strategy
+ */
+public class ChangeCompareStrategyPropertyAction extends Action implements IPropertyChangeListener, DisposeListener {
+
+ public static final String COMPARE_STRATEGIES = "COMPARE_STRATEGIES"; //$NON-NLS-1$
+ public static final String COMPARE_STRATEGY_ACTIONS = "COMPARE_STRATEGY_ACTIONS"; //$NON-NLS-1$
+ public static final String COMPARE_STRATEGIES_INITIALIZING = "COMPARE_STRATEGIES_INITIALIZING"; //$NON-NLS-1$
+
+ private CompareConfiguration fCompareConfiguration;
+ private ResourceBundle fBundle;
+ private String fPrefix = "strategy."; //$NON-NLS-1$
+ private CompareStrategyDescriptor fCompareStrategyDescriptor;
+ private ICompareStrategy fCompareStrategy;
+
+ public ChangeCompareStrategyPropertyAction(CompareStrategyDescriptor compareStrategyDescriptor, CompareConfiguration compareConfiguration) {
+ this.fBundle = compareStrategyDescriptor.getResourceBundle();
+ this.fCompareStrategyDescriptor = compareStrategyDescriptor;
+ this.fCompareStrategy = compareStrategyDescriptor.createCompareStrategy();
+ Utilities.initAction(this, fBundle, fPrefix);
+
+ //Utilities only loads images from compare plugin
+ setImageDescriptor(compareStrategyDescriptor.getImageDescriptor());
+ setId(compareStrategyDescriptor.getStrategyId());//TODO this ok?
+ setCompareConfiguration(compareConfiguration);
+
+ if (fCompareStrategy.isEnabledInitially()) {
+ setChecked(true);
+ setProperty(true);
+ }
+ }
+
+ void setProperty(boolean state){
+ if (fCompareConfiguration != null){
+ Map strategies = new HashMap();
+ if(fCompareConfiguration.getProperty(COMPARE_STRATEGIES) != null){
+ strategies.putAll((Map)fCompareConfiguration.getProperty(COMPARE_STRATEGIES));
+ }
+ if(state){
+ strategies.put(fCompareStrategyDescriptor.getStrategyId(), fCompareStrategy);
+ }else{
+ strategies.remove(fCompareStrategyDescriptor.getStrategyId());
+ }
+ fCompareConfiguration.setProperty(COMPARE_STRATEGIES, strategies);
+ }
+ }
+
+ boolean getProperty(){
+ Map strategies = (Map) fCompareConfiguration.getProperty(COMPARE_STRATEGIES);
+ if(strategies == null){
+ strategies = new HashMap();
+ }
+ return strategies.containsKey(fCompareStrategyDescriptor.getStrategyId());
+ }
+
+ public void run() {
+ boolean b= !getProperty();
+ setChecked(b);
+ setProperty(b);
+ }
+
+ public void setChecked(boolean state) {
+ super.setChecked(state);
+ Utilities.initToggleAction(this, fBundle, fPrefix, state);
+ }
+
+ public void setCompareConfiguration(CompareConfiguration cc) {
+ if (fCompareConfiguration != null)
+ fCompareConfiguration.removePropertyChangeListener(this);
+ fCompareConfiguration= cc;
+ if (fCompareConfiguration != null)
+ fCompareConfiguration.addPropertyChangeListener(this);
+ setChecked(getProperty());
+ }
+
+ public void propertyChange(PropertyChangeEvent event) {
+ if (event.getProperty().equals(COMPARE_STRATEGIES) && event.getNewValue() instanceof Map) {
+ setChecked(((Map)event.getNewValue()).containsKey(fCompareStrategyDescriptor.getStrategyId()));
+ }
+ }
+
+ public void dispose(){
+ if (fCompareConfiguration != null)
+ fCompareConfiguration.removePropertyChangeListener(this);
+ }
+
+ public void widgetDisposed(DisposeEvent e) {
+ dispose();
+ }
+
+ public String getStrategyId() {
+ return fCompareStrategyDescriptor.getStrategyId();
+ }
+
+ public void setInput(Object input, Object ancestor, Object left, Object right) {
+ fCompareStrategy.setInput(input, ancestor, left, right);
+ }
+}
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareEditorContributor.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareEditorContributor.java
index fc427fe..3eebc2c 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareEditorContributor.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareEditorContributor.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Copyright (c) 2000, 2013 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
@@ -10,21 +10,33 @@
*******************************************************************************/
package org.eclipse.compare.internal;
+import java.util.Iterator;
+import java.util.List;
import java.util.ResourceBundle;
-import org.eclipse.jface.action.*;
-
-import org.eclipse.ui.*;
+import org.eclipse.compare.CompareConfiguration;
+import org.eclipse.compare.CompareEditorInput;
+import org.eclipse.compare.CompareUI;
+import org.eclipse.compare.NavigationAction;
+import org.eclipse.jface.action.IContributionItem;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.help.IWorkbenchHelpSystem;
import org.eclipse.ui.part.EditorActionBarContributor;
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
-import org.eclipse.compare.*;
-
public class CompareEditorContributor extends EditorActionBarContributor {
+ public final static String STRATEGY_SEPARATOR = "compare.strategies"; //$NON-NLS-1$
+ public final static String BUILTIN_SEPARATOR = "compare.builtin"; //$NON-NLS-1$
+
private IEditorPart fActiveEditorPart= null;
private ChangePropertyAction fIgnoreWhitespace;
@@ -59,10 +71,11 @@ public class CompareEditorContributor extends EditorActionBarContributor {
* @see EditorActionBarContributor#contributeToToolBar(IToolBarManager)
*/
public void contributeToToolBar(IToolBarManager tbm) {
- tbm.add(new Separator());
- tbm.add(fIgnoreWhitespace);
- tbm.add(fToolbarNext);
- tbm.add(fToolbarPrevious);
+ tbm.add(new Separator(STRATEGY_SEPARATOR));
+ tbm.add(new Separator(BUILTIN_SEPARATOR));
+ tbm.appendToGroup(BUILTIN_SEPARATOR, fIgnoreWhitespace);
+ tbm.appendToGroup(BUILTIN_SEPARATOR, fToolbarNext);
+ tbm.appendToGroup(BUILTIN_SEPARATOR, fToolbarPrevious);
}
/*
@@ -106,6 +119,34 @@ public class CompareEditorContributor extends EditorActionBarContributor {
CompareConfiguration cc= editor.getCompareConfiguration();
fIgnoreWhitespace.setCompareConfiguration(cc);
+
+ IContributionItem[] items = actionBars.getToolBarManager().getItems();
+ boolean inStrategies = false;
+ for (int i=0;i<items.length;i++) {
+ if (items[i].getId().equals(STRATEGY_SEPARATOR)) { //$NON-NLS-1$
+ inStrategies = true;
+ } else if (items[i].getId().equals(BUILTIN_SEPARATOR)) { //$NON-NLS-1$
+ break;
+ } else if (inStrategies) {
+ actionBars.getToolBarManager().remove(items[i]);
+ }
+ }
+
+ IEditorInput input = editor.getEditorInput();
+ if (input instanceof CompareEditorInput) {
+ Object strategyActions = ((CompareEditorInput)input).getCompareConfiguration().getProperty(ChangeCompareStrategyPropertyAction.COMPARE_STRATEGY_ACTIONS);
+ if (strategyActions instanceof List && !((List)strategyActions).isEmpty()) {
+ Iterator i = ((List)strategyActions).iterator();
+ while (i.hasNext()) {
+ Object next = i.next();
+ if (next instanceof ChangeCompareStrategyPropertyAction)
+ actionBars.getToolBarManager().appendToGroup(STRATEGY_SEPARATOR, (ChangeCompareStrategyPropertyAction)next);
+ }
+ actionBars.getToolBarManager().markDirty();
+ actionBars.getToolBarManager().update(true);
+ actionBars.updateActionBars();
+ }
+ }
} else {
IActionBars actionBars= getActionBars();
actionBars.setGlobalActionHandler(ActionFactory.NEXT.getId(), null);
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareStrategyDescriptor.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareStrategyDescriptor.java
new file mode 100644
index 0000000..e6bc264
--- /dev/null
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareStrategyDescriptor.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2013 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 org.eclipse.compare.internal;
+
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.ResourceBundle;
+
+import org.eclipse.compare.ICompareStrategy;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.osgi.framework.Bundle;
+
+/**
+ * Describes compare strategy extension.
+ */
+public class CompareStrategyDescriptor {
+
+ private final static String CLASS_ATTRIBUTE = "class"; //$NON-NLS-1$
+ private final static String ID_ATTRIBUTE = "id"; //$NON-NLS-1$
+
+ private IConfigurationElement fConfiguration;
+ private ResourceBundle fResourceBundle;
+ private ImageDescriptor fImageDescriptor;
+
+ private class ConfigurationKeysEnumeration implements Enumeration {
+
+ private String[] keySet;
+ private int cursor = 0;
+
+ public ConfigurationKeysEnumeration(IConfigurationElement configuration) {
+ super();
+ this.keySet = configuration.getAttributeNames();
+ }
+
+ public boolean hasMoreElements() {
+ return cursor >= keySet.length;
+ }
+
+ public Object nextElement() {
+ return keySet[cursor++];
+ }
+
+ }
+
+ public CompareStrategyDescriptor(IConfigurationElement config) {
+ fConfiguration = config;
+ fResourceBundle = new ResourceBundle() {
+ protected Object handleGetObject(String key) {
+ return fConfiguration.getAttribute(key);
+ }
+
+ public Enumeration getKeys() {
+ return new ConfigurationKeysEnumeration(fConfiguration);
+ }
+ };
+
+ URL url = null;
+ String pluginId= fConfiguration.getContributor().getName();
+ Bundle bundle= Platform.getBundle(pluginId);
+ if (bundle != null) {
+ String path = Utilities.getString(fResourceBundle, "strategy.image", "strategy.image");
+ if (path!=null)
+ url= FileLocator.find(bundle, new Path(path), null);
+ }
+ fImageDescriptor = (url==null)?null:ImageDescriptor.createFromURL(url);
+ }
+
+ public ICompareStrategy createCompareStrategy() {
+ try {
+ return (ICompareStrategy) fConfiguration
+ .createExecutableExtension(CLASS_ATTRIBUTE);
+ } catch (CoreException e) {
+ CompareUIPlugin.log(e);
+ }
+ return null;
+ }
+
+ public String getStrategyId() {
+ return fConfiguration.getAttribute(ID_ATTRIBUTE);
+ }
+
+ public ResourceBundle getResourceBundle() {
+ return fResourceBundle;
+ }
+
+ public ImageDescriptor getImageDescriptor() {
+ return fImageDescriptor;
+ }
+}
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareUIPlugin.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareUIPlugin.java
index e1d7e21..194b009 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareUIPlugin.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareUIPlugin.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2013 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
@@ -16,6 +16,9 @@ import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
@@ -195,9 +198,12 @@ public final class CompareUIPlugin extends AbstractUIPlugin {
private static final String STRUCTURE_CREATOR_ID_ATTRIBUTE= "structureCreatorId"; //$NON-NLS-1$
private static final String VIEWER_TAG= "viewer"; //$NON-NLS-1$
+ private static final String STRATEGY_TAG = "strategy"; //$NON-NLS-1$
private static final String STRUCTURE_MERGE_VIEWER_EXTENSION_POINT= "structureMergeViewers"; //$NON-NLS-1$
private static final String STRUCTURE_MERGE_VIEWER_ID_ATTRIBUTE= "structureMergeViewerId"; //$NON-NLS-1$
private static final String CONTENT_MERGE_VIEWER_EXTENSION_POINT= "contentMergeViewers"; //$NON-NLS-1$
+ private static final String COMPARE_STRATEGIES_EXTENTION_POINT = "compareStrategies"; //$NON-NLS-1$
+ private static final String COMPARE_STRATEGY_ID_ATTRIBUTE = "strategyId"; //$NON-NLS-1$
private static final String CONTENT_MERGE_VIEWER_ID_ATTRIBUTE= "contentMergeViewerId"; //$NON-NLS-1$
private static final String CONTENT_VIEWER_EXTENSION_POINT= "contentViewers"; //$NON-NLS-1$
private static final String CONTENT_VIEWER_ID_ATTRIBUTE= "contentViewerId"; //$NON-NLS-1$
@@ -236,6 +242,7 @@ public final class CompareUIPlugin extends AbstractUIPlugin {
private CompareRegistry fStructureMergeViewers= new CompareRegistry();
private CompareRegistry fContentViewers= new CompareRegistry();
private CompareRegistry fContentMergeViewers= new CompareRegistry();
+ private CompareRegistry fCompareStrategies = new CompareRegistry();
private Map fStructureViewerAliases;
private CompareFilter fFilter;
@@ -391,7 +398,29 @@ public final class CompareUIPlugin extends AbstractUIPlugin {
if (CONTENT_TYPE_BINDING.equals(element.getName()))
fContentMergeViewers.createBinding(element, CONTENT_MERGE_VIEWER_ID_ATTRIBUTE);
}
-
+
+ // collect all extensions that define the compare strategy extension point
+ elements = registry.getConfigurationElementsFor(PLUGIN_ID,
+ COMPARE_STRATEGIES_EXTENTION_POINT);
+ for (int i = 0; i < elements.length; i++) {
+ IConfigurationElement element = elements[i];
+ String name = element.getName();
+ if (!CONTENT_TYPE_BINDING.equals(name)) {
+ if (!STRATEGY_TAG.equals(name))
+ logErrorMessage(Utilities
+ .getFormattedString(
+ "CompareUIPlugin.unexpectedTag", name, STRATEGY_TAG)); //$NON-NLS-1$
+ fCompareStrategies.register(element,
+ new CompareStrategyDescriptor(element));
+ }
+ }
+ for (int i = 0; i < elements.length; i++) {
+ IConfigurationElement element = elements[i];
+ if (CONTENT_TYPE_BINDING.equals(element.getName()))
+ fCompareStrategies.createBinding(element,
+ COMPARE_STRATEGY_ID_ATTRIBUTE);
+ }
+
// collect all viewers which define the content viewer extension point
elements= registry.getConfigurationElementsFor(PLUGIN_ID, CONTENT_VIEWER_EXTENSION_POINT);
for (int i= 0; i < elements.length; i++) {
@@ -850,6 +879,113 @@ public final class CompareUIPlugin extends AbstractUIPlugin {
return getViewer(descriptors[0], oldViewer, parent, configuration);
}
+ public CompareStrategyDescriptor[] findCompareStrategies(Object in) {
+ Collection contentTypes = getContentTypes(in);
+ if (contentTypes == null) {
+ return new CompareStrategyDescriptor[0];
+ }
+ Set result = new LinkedHashSet();
+ Iterator ctIterator = contentTypes.iterator();
+ while (ctIterator.hasNext()) {
+ Object ct = ctIterator.next();
+ if (ct instanceof IContentType) {
+ List list = fCompareStrategies.searchAll((IContentType) ct);
+ if (list != null)
+ result.addAll(list);
+ } else if (ct instanceof String) {
+ List list = fCompareStrategies.searchAll((String) ct);
+ if (list != null)
+ result.addAll(list);
+ }
+ }
+
+ ArrayList list = new ArrayList(result);
+ Collections.sort(list, new Comparator(){
+ public int compare(Object left, Object right) {
+ return ((CompareStrategyDescriptor)left).getStrategyId().compareTo(
+ ((CompareStrategyDescriptor)right).getStrategyId());
+ }
+ });
+
+
+ return (CompareStrategyDescriptor[]) result
+ .toArray(new CompareStrategyDescriptor[result.size()]);
+ }
+
+ private Collection getContentTypes(Object in) {
+ Set result = new LinkedHashSet();
+ if (in instanceof IStreamContentAccessor) {
+ String type = ITypedElement.TEXT_TYPE;
+
+ if (in instanceof ITypedElement) {
+ ITypedElement tin = (ITypedElement) in;
+
+ IContentType ct = getContentType(tin);
+ if (ct != null) {
+ result.add(ct);
+ }
+
+ String ty = tin.getType();
+ if (ty != null)
+ type = ty;
+ result.add(type);
+ }
+ return result;
+ }
+
+ if (!(in instanceof ICompareInput))
+ return null;
+
+ ICompareInput input = (ICompareInput) in;
+
+ IContentType ctype = getCommonType(input);
+ if (ctype != null) {
+ result.add(ctype);
+ }
+
+ String[] types = getTypes(input);
+ String type = null;
+ if (isHomogenous(types))
+ type = types[0];
+
+ if (ITypedElement.FOLDER_TYPE.equals(type))
+ return null;
+
+ if (type == null) {
+ int n = 0;
+ for (int i = 0; i < types.length; i++)
+ if (!ITypedElement.UNKNOWN_TYPE.equals(types[i])) {
+ n++;
+ if (type == null)
+ type = types[i]; // remember the first known type
+ }
+ if (n > 1) // don't use the type if there were more than one
+ type = null;
+ }
+
+ if (type != null) {
+ result.add(type);
+ }
+
+ // fallback
+ String leftType = guessType(input.getLeft());
+ String rightType = guessType(input.getRight());
+
+ if (leftType != null || rightType != null) {
+ boolean right_text = rightType != null
+ && ITypedElement.TEXT_TYPE.equals(rightType);
+ boolean left_text = leftType != null
+ && ITypedElement.TEXT_TYPE.equals(leftType);
+ if ((rightType != null && !right_text)
+ || (leftType != null && !left_text)) {
+ result.add(BINARY_TYPE);
+ }
+ result.add(ITypedElement.TEXT_TYPE);
+
+ }
+ return result;
+ }
+
public ViewerDescriptor[] findContentViewerDescriptor(Viewer oldViewer, Object in, CompareConfiguration cc) {
Set result = new LinkedHashSet();
if (in instanceof IStreamContentAccessor) {
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/DocLineComparator.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/DocLineComparator.java
index 8686bbb..767fe3b 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/DocLineComparator.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/DocLineComparator.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2013 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
@@ -10,9 +10,13 @@
*******************************************************************************/
package org.eclipse.compare.internal;
-import org.eclipse.jface.text.*;
+import org.eclipse.compare.ICompareStrategy;
import org.eclipse.compare.contentmergeviewer.ITokenComparator;
import org.eclipse.compare.rangedifferencer.IRangeComparator;
+import org.eclipse.core.internal.expressions.util.LRUCache;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
/**
* Implements the <code>IRangeComparator</code> interface for lines in a document.
@@ -29,6 +33,9 @@ public class DocLineComparator implements ITokenComparator {
private int fLineCount;
private int fLength;
private boolean fIgnoreWhiteSpace;
+ private ICompareStrategy[] fCompareStrategies;
+ private char fContributor;
+ private LRUCache fCompareStrategyCache;
/**
* Creates a <code>DocLineComparator</code> for the given document range.
@@ -40,9 +47,23 @@ public class DocLineComparator implements ITokenComparator {
* @param ignoreWhiteSpace if <code>true</code> white space is ignored when comparing lines
*/
public DocLineComparator(IDocument document, IRegion region,
- boolean ignoreWhiteSpace) {
+ boolean ignoreWhiteSpace, ICompareStrategy[] compareStrategies, char contributor) {
fDocument = document;
fIgnoreWhiteSpace = ignoreWhiteSpace;
+ fCompareStrategies = compareStrategies;
+ fContributor = contributor;
+
+ boolean cacheIgnoredRegions = false;
+ if (compareStrategies!=null && compareStrategies.length>0) {
+ cacheIgnoredRegions = true;
+ for (int i=0;i<compareStrategies.length;i++) {
+ if (!compareStrategies[i].areIgnoredRegionsReusable()) {
+ cacheIgnoredRegions = false;
+ break;
+ }
+ }
+ }
+ fCompareStrategyCache = (cacheIgnoredRegions)?new LRUCache(1024):null;
fLineOffset = 0;
if (region != null) {
@@ -116,18 +137,15 @@ public class DocLineComparator implements ITokenComparator {
DocLineComparator other= (DocLineComparator) otherComparator;
if (fIgnoreWhiteSpace) {
- String s1= extract(thisIndex);
- String s2= other.extract(otherIndex);
- //return s1.trim().equals(s2.trim());
- return compare(s1, s2);
+ String[] linesToCompare = extract(thisIndex, otherIndex, other);
+ return compare(linesToCompare[0], linesToCompare[1]);
}
int tlen= getTokenLength(thisIndex);
int olen= other.getTokenLength(otherIndex);
- if (tlen == olen) {
- String s1= extract(thisIndex);
- String s2= other.extract(otherIndex);
- return s1.equals(s2);
+ if (tlen == olen || fCompareStrategies!=null) {
+ String[] linesToCompare = extract(thisIndex, otherIndex, other);
+ return linesToCompare[0].equals(linesToCompare[1]);
}
}
return false;
@@ -149,6 +167,39 @@ public class DocLineComparator implements ITokenComparator {
//---- private methods
+ private String[] extract(int thisIndex, int otherIndex, DocLineComparator other){
+
+ String[] extracts = new String[2];
+ if (fCompareStrategies!=null || fCompareStrategies.length>0) {
+ if (fCompareStrategyCache!=null) {
+ extracts[0] = (String)fCompareStrategyCache.get(new Integer(thisIndex));
+ if (extracts[0] == null) {
+ extracts[0] = Utilities.applyCompareStrategies(
+ extract(thisIndex), fContributor, other.extract(otherIndex), other.fContributor, fCompareStrategies);
+ fCompareStrategyCache.put(new Integer(thisIndex), extracts[0]);
+ }
+
+ extracts[1] = (String)other.fCompareStrategyCache.get(new Integer(otherIndex));
+ if (extracts[1] == null) {
+ extracts[1] = Utilities.applyCompareStrategies(
+ other.extract(otherIndex), other.fContributor, extract(thisIndex), fContributor, fCompareStrategies);
+ other.fCompareStrategyCache.put(new Integer(otherIndex), extracts[1]);
+ }
+ } else {
+ String thisLine = extract(thisIndex);
+ String otherLine = other.extract(otherIndex);
+ extracts = new String[] {
+ Utilities.applyCompareStrategies(thisLine, fContributor,
+ otherLine, other.fContributor, fCompareStrategies),
+ Utilities.applyCompareStrategies(otherLine, other.fContributor,
+ thisLine, fContributor, fCompareStrategies)};
+ }
+ } else {
+ extracts = new String[]{extract(thisIndex), other.extract(otherIndex)};
+ }
+ return extracts;
+ }
+
/**
* Extract a single line from the underlying document without the line separator.
*
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/MergeSourceViewer.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/MergeSourceViewer.java
index ec99bd7..549abf3 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/MergeSourceViewer.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/MergeSourceViewer.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2013 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
@@ -990,6 +990,10 @@ public class MergeSourceViewer implements ISelectionChangedListener,
public void addTextAction(IAction textEditorPropertyAction) {
textActions.add(textEditorPropertyAction);
}
+
+ public boolean removeTextAction(IAction textEditorPropertyAction) {
+ return textActions.remove(textEditorPropertyAction);
+ }
public void addAction(String id, IAction action) {
fActions.put(id, action);
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/Utilities.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/Utilities.java
index fe48c72..6ba04b3 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/Utilities.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/Utilities.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2013 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
@@ -31,6 +31,7 @@ import java.util.ResourceBundle;
import org.eclipse.compare.CompareConfiguration;
import org.eclipse.compare.CompareUI;
+import org.eclipse.compare.ICompareStrategy;
import org.eclipse.compare.IEncodedStreamContentAccessor;
import org.eclipse.compare.ISharedDocumentAdapter;
import org.eclipse.compare.IStreamContentAccessor;
@@ -71,6 +72,7 @@ import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ISelection;
@@ -140,6 +142,27 @@ public class Utilities {
return dflt;
}
+ /**
+ * Returns the active compare strategies for the compare configuration
+ * @param cc
+ * @return the active compare strategies
+ */
+ public static ICompareStrategy[] getCompareStrategies(
+ CompareConfiguration cc) {
+ if (cc != null) {
+ Object value = cc
+ .getProperty(ChangeCompareStrategyPropertyAction.COMPARE_STRATEGIES);
+ if (value instanceof Map) {
+ Map strategiesMap = (Map) value;
+ return (ICompareStrategy[]) strategiesMap.values()
+ .toArray(
+ new ICompareStrategy[strategiesMap
+ .size()]);
+ }
+ }
+ return new ICompareStrategy[0];
+ }
+
public static void firePropertyChange(ListenerList listenerList, Object source, String property, Object old, Object newValue) {
PropertyChangeEvent event= new PropertyChangeEvent(source, property, old, newValue);
firePropertyChange(listenerList, event);
@@ -912,4 +935,46 @@ public class Utilities {
});
return result[0];
}
+
+ /**
+ * Applies the compare strategies to the lines of text taken from the specified contributors
+ * @param line1
+ * @param line1Contributor
+ * @param line2
+ * @param line2Contributor
+ * @param strategies may be null
+ * @return returns the result of applying the strategies to the line from the contributor
+ */
+ public static String applyCompareStrategies(String line1, char line1Contributor,
+ String line2, char line2Contributor, ICompareStrategy[] strategies) {
+ IRegion[][] ignoredRegions = new IRegion[strategies.length][];
+
+ HashMap input = new HashMap(4);
+ input.put(ICompareStrategy.THIS_LINE, line1);
+ input.put(ICompareStrategy.THIS_CONTRIBUTOR, new Character(line1Contributor));
+ input.put(ICompareStrategy.OTHER_LINE, line2);
+ input.put(ICompareStrategy.OTHER_CONTRIBUTOR, new Character(line2Contributor));
+ for (int i=0;i<strategies.length;i++) {
+ ignoredRegions[i] = strategies[i].ignoreRegions(input);
+ }
+
+ boolean[] ignored = new boolean[line1.length()];
+ for (int j=0;j<ignoredRegions.length;j++) {
+ if (ignoredRegions[j]!=null) {
+ for (int k=0;k<ignoredRegions[j].length;k++) {
+ if (ignoredRegions[j][k]!=null)
+ for (int l=0;l<ignoredRegions[j][k].getLength();l++) {
+ ignored[ignoredRegions[j][k].getOffset()+l]=true;
+ }
+ }
+ }
+ }
+ StringBuffer buffer = new StringBuffer(line1.length());
+ for (int i=0;i<ignored.length;i++) {
+ if (!ignored[i]) {
+ buffer.append(line1.charAt(i));
+ }
+ }
+ return buffer.toString();
+ }
}
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/merge/DocumentMerger.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/merge/DocumentMerger.java
index 81a28fe..9e013e6 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/merge/DocumentMerger.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/merge/DocumentMerger.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2012 IBM Corporation and others.
+ * Copyright (c) 2007, 2013 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
@@ -37,6 +37,7 @@ import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.progress.IProgressService;
import org.eclipse.compare.CompareConfiguration;
+import org.eclipse.compare.ICompareStrategy;
import org.eclipse.compare.contentmergeviewer.ITokenComparator;
import org.eclipse.compare.internal.CompareContentViewerSwitchingPane;
import org.eclipse.compare.internal.CompareMessages;
@@ -422,12 +423,13 @@ public class DocumentMerger {
resetPositions(aDoc);
boolean ignoreWhiteSpace= isIgnoreWhitespace();
+ ICompareStrategy[] compareStrategies = getCompareStrategies();
- DocLineComparator sright= new DocLineComparator(rDoc, toRegion(rRegion), ignoreWhiteSpace);
- DocLineComparator sleft= new DocLineComparator(lDoc, toRegion(lRegion), ignoreWhiteSpace);
+ DocLineComparator sright= new DocLineComparator(rDoc, toRegion(rRegion), ignoreWhiteSpace, compareStrategies, MergeViewerContentProvider.RIGHT_CONTRIBUTOR);
+ DocLineComparator sleft= new DocLineComparator(lDoc, toRegion(lRegion), ignoreWhiteSpace, compareStrategies,MergeViewerContentProvider.LEFT_CONTRIBUTOR);
DocLineComparator sancestor= null;
if (aDoc != null) {
- sancestor= new DocLineComparator(aDoc, toRegion(aRegion), ignoreWhiteSpace);
+ sancestor= new DocLineComparator(aDoc, toRegion(aRegion), ignoreWhiteSpace, compareStrategies, MergeViewerContentProvider.ANCESTOR_CONTRIBUTOR);
/*if (isPatchHunk()) {
if (isHunkOnLeft()) {
sright= new DocLineComparator(aDoc, toRegion(aRegion), ignoreWhiteSpace);
@@ -594,12 +596,13 @@ public class DocumentMerger {
aDoc= getDocument(MergeViewerContentProvider.ANCESTOR_CONTRIBUTOR);
boolean ignoreWhiteSpace= isIgnoreWhitespace();
-
- DocLineComparator sright= new DocLineComparator(rDoc, toRegion(rRegion), ignoreWhiteSpace);
- DocLineComparator sleft= new DocLineComparator(lDoc, toRegion(lRegion), ignoreWhiteSpace);
+ ICompareStrategy[] compareStrategies = getCompareStrategies();
+
+ DocLineComparator sright= new DocLineComparator(rDoc, toRegion(rRegion), ignoreWhiteSpace, compareStrategies, MergeViewerContentProvider.RIGHT_CONTRIBUTOR);
+ DocLineComparator sleft= new DocLineComparator(lDoc, toRegion(lRegion), ignoreWhiteSpace, compareStrategies, MergeViewerContentProvider.LEFT_CONTRIBUTOR);
DocLineComparator sancestor= null;
if (aDoc != null)
- sancestor= new DocLineComparator(aDoc, toRegion(aRegion), ignoreWhiteSpace);
+ sancestor= new DocLineComparator(aDoc, toRegion(aRegion), ignoreWhiteSpace, compareStrategies, MergeViewerContentProvider.ANCESTOR_CONTRIBUTOR);
final Object[] result= new Object[1];
final DocLineComparator sa= sancestor, sl= sleft, sr= sright;
@@ -682,6 +685,10 @@ public class DocumentMerger {
return Utilities.getBoolean(getCompareConfiguration(), CompareConfiguration.IGNORE_WHITESPACE, false);
}
+ private ICompareStrategy[] getCompareStrategies() {
+ return Utilities.getCompareStrategies(getCompareConfiguration());
+ }
+
private boolean isCappingDisabled() {
return CompareUIPlugin.getDefault().getPreferenceStore().getBoolean(ComparePreferencePage.CAPPING_DISABLED);
}
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/structuremergeviewer/Differencer.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/structuremergeviewer/Differencer.java
index 60fa61b..7f3e83a 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/structuremergeviewer/Differencer.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/structuremergeviewer/Differencer.java
@@ -22,6 +22,7 @@ import java.util.Set;
import org.eclipse.compare.IStreamContentAccessor;
import org.eclipse.compare.ITypedElement;
+import org.eclipse.compare.internal.MergeViewerContentProvider;
import org.eclipse.compare.internal.Utilities;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
@@ -360,7 +361,7 @@ public class Differencer {
description= LEFT | ADDITION;
} else {
description= CONFLICTING | ADDITION;
- if (contentsEqual(left, right))
+ if (contentsEqual(left, MergeViewerContentProvider.LEFT_CONTRIBUTOR, right, MergeViewerContentProvider.RIGHT_CONTRIBUTOR))
description|= PSEUDO_CONFLICT;
}
}
@@ -369,20 +370,20 @@ public class Differencer {
if (right == null) {
description= CONFLICTING | DELETION | PSEUDO_CONFLICT;
} else {
- if (contentsEqual(ancestor, right))
+ if (contentsEqual(ancestor, MergeViewerContentProvider.ANCESTOR_CONTRIBUTOR, right, MergeViewerContentProvider.RIGHT_CONTRIBUTOR))
description= LEFT | DELETION;
else
description= CONFLICTING | CHANGE;
}
} else {
if (right == null) {
- if (contentsEqual(ancestor, left))
+ if (contentsEqual(ancestor, MergeViewerContentProvider.ANCESTOR_CONTRIBUTOR, left, MergeViewerContentProvider.LEFT_CONTRIBUTOR))
description= RIGHT | DELETION;
else
description= CONFLICTING | CHANGE;
} else {
- boolean ay= contentsEqual(ancestor, left);
- boolean am= contentsEqual(ancestor, right);
+ boolean ay= contentsEqual(ancestor, MergeViewerContentProvider.ANCESTOR_CONTRIBUTOR, left, MergeViewerContentProvider.LEFT_CONTRIBUTOR);
+ boolean am= contentsEqual(ancestor, MergeViewerContentProvider.ANCESTOR_CONTRIBUTOR, right, MergeViewerContentProvider.RIGHT_CONTRIBUTOR);
if (ay && am) {
// empty
@@ -392,7 +393,7 @@ public class Differencer {
description= LEFT | CHANGE;
} else {
description= CONFLICTING | CHANGE;
- if (contentsEqual(left, right))
+ if (contentsEqual(left, MergeViewerContentProvider.LEFT_CONTRIBUTOR, right, MergeViewerContentProvider.RIGHT_CONTRIBUTOR))
description|= PSEUDO_CONFLICT;
}
}
@@ -410,7 +411,7 @@ public class Differencer {
if (right == null) {
description= DELETION;
} else {
- if (! contentsEqual(left, right))
+ if (! contentsEqual(left, MergeViewerContentProvider.LEFT_CONTRIBUTOR, right, MergeViewerContentProvider.RIGHT_CONTRIBUTOR))
description= CHANGE;
}
}
@@ -418,6 +419,26 @@ public class Differencer {
return description;
}
+
+ /**
+ * Performs a content compare on the two given inputs.
+ * <p>
+ * The <code>Differencer</code> implementation returns
+ * <code>contentsEqual(Object input1, Object input2)</code>.
+ * Subclasses may override to implement a different content compare
+ * on the given inputs.
+ * </p>
+ *
+ * @param input1 first input to contents compare
+ * @param contributor1 the contributor of input1
+ * @param input2 second input to contents compare
+ * @param contributor2 the contributor of input2
+ * @return <code>true</code> if content is equal
+ * @since 3.6
+ */
+ protected boolean contentsEqual(Object input1, char contributor1, Object input2, char contributor2) {
+ return contentsEqual(input1, input2);
+ }
/**
* Performs a content compare on the two given inputs.
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/structuremergeviewer/IStructureCreator3.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/structuremergeviewer/IStructureCreator3.java
new file mode 100644
index 0000000..db450bf
--- /dev/null
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/structuremergeviewer/IStructureCreator3.java
@@ -0,0 +1,46 @@
+package org.eclipse.compare.structuremergeviewer;
+
+import org.eclipse.compare.ICompareStrategy;
+
+/*******************************************************************************
+ * Copyright (c) 2013 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
+ *******************************************************************************/
+
+ /**
+ * An extension to the {@link IStructureCreator2} interface that supports the
+ * use of activated compare strategies when generating the string contents
+ * of a node.
+ * <p>
+ * Clients may implement this interface; there is no standard implementation.
+ * </p>
+ * @since 3.6
+ */
+ public interface IStructureCreator3 extends IStructureCreator2 {
+
+ /**
+ * Returns true if the two nodes are equal for comparison purposes.
+ * If <code>compareStrategies</code> is not empty, the strategies should be applied
+ * to each line of each node's text representation. The strategies should be applied to each
+ * line individually, without delimiters, but with all other whitespace characters intact.
+ * A default implementation <code>StructureCreator.contentsEquals()</code> is available for reuse.
+ * @param node1
+ * @param contributor1 either 'A', 'L', or 'R' for ancestor, left or right contributor
+ * @param node2
+ * @param contributor2 either 'A', 'L', or 'R' for ancestor, left or right contributor
+ * @param ignoreWhitespace if <code>true</code> whitespace characters should be ignored
+ * when determining equality.
+ * @param compareStrategies the strategies used to customize the comparison of lines of text.
+ * @return whether the two nodes are equal for comparison purposes
+ */
+ boolean contentsEquals(Object node1, char contributor1,
+ Object node2, char contributor2, boolean ignoreWhitespace,
+ ICompareStrategy[] compareStrategies);
+
+ } \ No newline at end of file
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/structuremergeviewer/StructureCreator.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/structuremergeviewer/StructureCreator.java
index 799afba..db6233b 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/structuremergeviewer/StructureCreator.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/structuremergeviewer/StructureCreator.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2009 IBM Corporation and others.
+ * Copyright (c) 2006, 2013 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
@@ -10,9 +10,13 @@
*******************************************************************************/
package org.eclipse.compare.structuremergeviewer;
+import java.io.BufferedReader;
+import java.io.StringReader;
import java.io.UnsupportedEncodingException;
+import java.util.List;
import org.eclipse.compare.CompareUI;
+import org.eclipse.compare.ICompareStrategy;
import org.eclipse.compare.IEditableContent;
import org.eclipse.compare.IEncodedStreamContentAccessor;
import org.eclipse.compare.ISharedDocumentAdapter;
@@ -22,6 +26,7 @@ import org.eclipse.compare.SharedDocumentAdapter;
import org.eclipse.compare.contentmergeviewer.IDocumentRange;
import org.eclipse.compare.internal.CompareUIPlugin;
import org.eclipse.compare.internal.Utilities;
+import org.eclipse.compare.internal.patch.LineReader;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
@@ -430,4 +435,88 @@ public abstract class StructureCreator implements IStructureCreator2 {
}
return null;
}
+
+ /**
+ * Applies the compare strategies to the line of text taken from the specified contributor
+ * @param line1
+ * @param contributor1
+ * @param line2
+ * @param contributor2
+ * @param strategies may be null
+ * @return returns the result of applying the strategies to the line from the contributor
+ * @since 3.6
+ */
+ public String applyCompareStrategies(String line1, char contributor1,
+ String line2, char contributor2, ICompareStrategy[] strategies) {
+ return Utilities.applyCompareStrategies(line1, contributor1, line2, contributor2, strategies);
+ }
+
+ /**
+ * Reusable implementation of <code>IStructureCreator3.contentsEquals()</code>
+ * @param node1
+ * @param contributor1
+ * @param node2
+ * @param contributor2
+ * @param ignoreWhitespace
+ * @param compareStrategies
+ * @return returns whether the nodes are equal for comparison purposes
+ * @since 3.6
+ */
+ public boolean contentsEquals(Object node1, char contributor1,
+ Object node2, char contributor2, boolean ignoreWhitespace,
+ ICompareStrategy[] compareStrategies) {
+
+ List lines1 = LineReader.readLines(new BufferedReader(new StringReader(getContents(node1, false))));
+ List lines2 = LineReader.readLines(new BufferedReader(new StringReader(getContents(node2, false))));
+
+ if (lines1.size()!=lines2.size())
+ return false;
+
+ for (int i=0;i<lines1.size();i++) {
+ String s1 = (String)lines1.get(i);
+ String s2 = (String)lines2.get(i);
+
+ if (compareStrategies != null && compareStrategies.length>0) {
+ s1 = applyCompareStrategies(s1, contributor1,
+ s2, contributor2, compareStrategies);
+ s2 = applyCompareStrategies(s2, contributor2,
+ s1, contributor1, compareStrategies);
+ }
+
+ if (ignoreWhitespace) {
+ int l1= s1.length();
+ int l2= s2.length();
+ int c1= 0, c2= 0;
+ int i1= 0, i2= 0;
+
+ while (c1 != -1) {
+
+ c1= -1;
+ while (i1 < l1) {
+ char c= s1.charAt(i1++);
+ if (! Character.isWhitespace(c)) {
+ c1= c;
+ break;
+ }
+ }
+
+ c2= -1;
+ while (i2 < l2) {
+ char c= s2.charAt(i2++);
+ if (! Character.isWhitespace(c)) {
+ c2= c;
+ break;
+ }
+ }
+
+ if (c1 != c2)
+ return false;
+ }
+ } else if (!s1.equals(s2)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
}
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/structuremergeviewer/StructureDiffViewer.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/structuremergeviewer/StructureDiffViewer.java
index 4b87006..dc6e9eb 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/structuremergeviewer/StructureDiffViewer.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/structuremergeviewer/StructureDiffViewer.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2013 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
@@ -475,8 +475,8 @@ public class StructureDiffViewer extends DiffTreeViewer {
if (fDifferencer == null)
fDifferencer= new Differencer() {
- protected boolean contentsEqual(Object o1, Object o2) {
- return StructureDiffViewer.this.contentsEqual(o1, o2);
+ protected boolean contentsEqual(Object o1, char contributor1, Object o2, char contributor2) {
+ return StructureDiffViewer.this.contentsEqual(o1, contributor1, o2, contributor2);
}
protected Object visit(Object data, int result, Object ancestor, Object left, Object right) {
Object o= super.visit(data, result, ancestor, left, right);
@@ -608,11 +608,17 @@ public class StructureDiffViewer extends DiffTreeViewer {
* Called from the difference engine.
* Returns <code>null</code> if no structure creator has been set.
*/
- private boolean contentsEqual(Object o1, Object o2) {
+ private boolean contentsEqual(Object o1, char contributor1, Object o2, char contributor2) {
if (fStructureCreator != null) {
- boolean ignoreWhiteSpace= Utilities.getBoolean(getCompareConfiguration(), CompareConfiguration.IGNORE_WHITESPACE, false);
- String s1= fStructureCreator.getContents(o1, ignoreWhiteSpace);
- String s2= fStructureCreator.getContents(o2, ignoreWhiteSpace);
+ boolean ignoreWhiteSpace= Utilities.getBoolean(getCompareConfiguration(), CompareConfiguration.IGNORE_WHITESPACE, false);
+ ICompareStrategy[] compareStrategies = Utilities.getCompareStrategies(getCompareConfiguration());
+ String s1, s2;
+ if (fStructureCreator instanceof IStructureCreator3) {
+ return ((IStructureCreator3)fStructureCreator).contentsEquals(o1, contributor1, o2, contributor2, ignoreWhiteSpace, compareStrategies);
+ } else {
+ s1= fStructureCreator.getContents(o1, ignoreWhiteSpace);
+ s2= fStructureCreator.getContents(o2, ignoreWhiteSpace);
+ }
if (s1 == null || s2 == null)
return false;
return s1.equals(s2);
@@ -630,6 +636,9 @@ public class StructureDiffViewer extends DiffTreeViewer {
String key= event.getProperty();
if (key.equals(CompareConfiguration.IGNORE_WHITESPACE)) {
diff();
+ } else if (key.equals(ChangeCompareStrategyPropertyAction.COMPARE_STRATEGIES) &&
+ getCompareConfiguration().getProperty(ChangeCompareStrategyPropertyAction.COMPARE_STRATEGIES_INITIALIZING)==null) {
+ diff();
} else if (key.equals("ANCESTOR_STRUCTURE_REFRESH")) { //$NON-NLS-1$
fAncestorStructure.refresh(new NullProgressMonitor());
diff();
diff --git a/bundles/org.eclipse.compare/plugin.xml b/bundles/org.eclipse.compare/plugin.xml
index 751f46a..266072d 100644
--- a/bundles/org.eclipse.compare/plugin.xml
+++ b/bundles/org.eclipse.compare/plugin.xml
@@ -19,6 +19,7 @@
<extension-point id="structureMergeViewers" name="%structureMergeViewers" schema="schema/structureMergeViewers.exsd"/>
<extension-point id="contentMergeViewers" name="%contentMergeViewers" schema="schema/contentMergeViewers.exsd"/>
<extension-point id="contentViewers" name="%contentViewers" schema="schema/contentViewers.exsd"/>
+ <extension-point id="compareStrategies" name="%compareStrategies" schema="schema/compareStrategies.exsd"/>
<!-- Extensions -->
<extension
diff --git a/bundles/org.eclipse.compare/schema/compareStrategies.exsd b/bundles/org.eclipse.compare/schema/compareStrategies.exsd
new file mode 100644
index 0000000..56c4658
--- /dev/null
+++ b/bundles/org.eclipse.compare/schema/compareStrategies.exsd
@@ -0,0 +1,228 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.compare" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.compare" id="compareStrategies" name="Compare Strategies"/>
+ </appInfo>
+ <documentation>
+ This extension point allows a plug-in to register a compare strategy
+for specific content types. The compare strategy will be exposed as a
+toggle action in the compare viewer and can be used to customize how
+differences are calculated when comparing text. The extension point must
+implement the interface &lt;samp&gt;org.eclipse.compare.ICompareStrategy&lt;/samp&gt;.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appInfo>
+ <meta.element />
+ </appInfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="strategy" minOccurs="0" maxOccurs="unbounded"/>
+ <element ref="contentTypeBinding" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+ a fully qualified identifier of the target extension point
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+ an optional identifier of the extension instance
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ an optional name of the extension instance
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="strategy">
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ a unique identifier that can be used to reference the strategy
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="extensions" type="string">
+ <annotation>
+ <documentation>
+ a comma separated list of file extensions e.g. &quot;java, txt&quot;
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.compare.ICompareStrategy"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="strategy.label" type="string" use="required">
+ <annotation>
+ <documentation>
+ A translatable label that will be used in the UI for this strategy.
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="strategy.tooltip" type="string" use="required">
+ <annotation>
+ <documentation>
+ A translatable label that will be used in the UI for this strategy.
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="strategy.tooltip.checked" type="string">
+ <annotation>
+ <documentation>
+ A translatable label that will be used in the UI for this strategy.
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="strategy.tooltip.unchecked" type="string">
+ <annotation>
+ <documentation>
+ A translatable label that will be used in the UI for this strategy.
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="strategy.description" type="string" use="required">
+ <annotation>
+ <documentation>
+ A translatable label that will be used in the UI for this strategy.
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="strategy.description.checked" type="string">
+ <annotation>
+ <documentation>
+ A translatable label that will be used in the UI for this strategy.
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="strategy.description.unchecked" type="string">
+ <annotation>
+ <documentation>
+ A translatable label that will be used in the UI for this strategy.
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="strategy.image" type="string">
+ <annotation>
+ <documentation>
+ An image that will be used in the UI for this strategy.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="contentTypeBinding">
+ <annotation>
+ <documentation>
+ A &lt;code&gt;contentTypeBinding&lt;/code&gt; binds a compare strategy to a content type.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="contentTypeId" type="string" use="required">
+ <annotation>
+ <documentation>
+ The id of a content type defined using the &lt;code&gt;org.eclipse.core.contenttype.contentTypes&lt;/code&gt; extension point.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.core.contenttype.contentTypes/content-type/@id"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="strategyId" type="string" use="required">
+ <annotation>
+ <documentation>
+ The id of a strategy defined using the &lt;code&gt;strategy&lt;/code&gt; element of this extension point (i.e. &lt;code&gt;org.eclipse.compare.compareStrategies&lt;/code&gt;)
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.compare.compareStrategies/strategy/@id"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiinfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/RangeDifferenceComparator.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/RangeDifferenceComparator.java
index 6383917..09046fc 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/RangeDifferenceComparator.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/RangeDifferenceComparator.java
@@ -13,8 +13,8 @@ package org.eclipse.team.internal.ui.synchronize;
import java.io.IOException;
import java.io.InputStream;
-import org.eclipse.compare.internal.DocLineComparator;
-import org.eclipse.compare.internal.Utilities;
+import org.eclipse.compare.ICompareStrategy;
+import org.eclipse.compare.internal.*;
import org.eclipse.compare.rangedifferencer.RangeDifference;
import org.eclipse.compare.rangedifferencer.RangeDifferencer;
import org.eclipse.core.resources.ResourcesPlugin;
@@ -62,9 +62,9 @@ public abstract class RangeDifferenceComparator extends
IDocument lDoc = new Document(left);
IDocument rDoc = new Document(right);
DocLineComparator sleft = new DocLineComparator(lDoc, new Region(0,
- lDoc.getLength()), shouldIgnoreWhitespace());
+ lDoc.getLength()), shouldIgnoreWhitespace(), new ICompareStrategy[0], MergeViewerContentProvider.LEFT_CONTRIBUTOR);
DocLineComparator sright = new DocLineComparator(rDoc, new Region(0,
- rDoc.getLength()), shouldIgnoreWhitespace());
+ rDoc.getLength()), shouldIgnoreWhitespace(), new ICompareStrategy[0], MergeViewerContentProvider.RIGHT_CONTRIBUTOR);
final DocLineComparator sl = sleft, sr = sright;
RangeDifference[] ranges = RangeDifferencer.findRanges(monitor, sl, sr);
return compareRangeDifferences(ranges, lDoc, rDoc);
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/RegexDiffComparator.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/RegexDiffComparator.java
index 333b9af..d354d4f 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/RegexDiffComparator.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/RegexDiffComparator.java
@@ -12,7 +12,9 @@ package org.eclipse.team.internal.ui.synchronize;
import java.util.regex.Pattern;
+import org.eclipse.compare.ICompareStrategy;
import org.eclipse.compare.internal.DocLineComparator;
+import org.eclipse.compare.internal.MergeViewerContentProvider;
import org.eclipse.compare.rangedifferencer.RangeDifference;
import org.eclipse.jface.text.*;
@@ -41,9 +43,9 @@ public class RegexDiffComparator extends RangeDifferenceComparator {
continue;
DocLineComparator sleft = new DocLineComparator(lDoc, null,
- shouldIgnoreWhitespace());
+ shouldIgnoreWhitespace(), new ICompareStrategy[0], MergeViewerContentProvider.LEFT_CONTRIBUTOR);
DocLineComparator sright = new DocLineComparator(rDoc, null,
- shouldIgnoreWhitespace());
+ shouldIgnoreWhitespace(), new ICompareStrategy[0], MergeViewerContentProvider.RIGHT_CONTRIBUTOR);
IRegion lRegion = lDoc.getLineInformation(diff.leftStart());
int leftEnd = sleft.getTokenStart(diff.leftStart()