aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Flicker 2012-11-28 06:03:52 (EST)
committerMalgorzata Janczarska2013-04-15 08:06:24 (EDT)
commit5755d15895e8d471924809f783feb9a95718d240 (patch)
tree19f7a73d05c76c071c5f8bde2ecbeb81491617dd
parent1ddeb74cb0186cd27c3d909f02e726f979c4254e (diff)
downloadeclipse.platform.team-5755d15895e8d471924809f783feb9a95718d240.zip
eclipse.platform.team-5755d15895e8d471924809f783feb9a95718d240.tar.gz
eclipse.platform.team-5755d15895e8d471924809f783feb9a95718d240.tar.bz2
Bug 382427 - Mechanism to inject line compare strategies into merge andrefs/changes/04/9004/17
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/ICompareFilter.java99
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/contentmergeviewer/TextMergeViewer.java156
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/ChangeCompareFilterPropertyAction.java131
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareEditorContributor.java87
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareFilterDescriptor.java110
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/ComparePreferencePage.java4
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareResourceFilter.java (renamed from bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareFilter.java)12
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareUIPlugin.java144
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/DocLineComparator.java126
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/IMergeViewerTestAdapter.java9
-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.java72
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/merge/DocumentMerger.java35
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/structuremergeviewer/Differencer.java44
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/structuremergeviewer/StructureCreator.java93
-rw-r--r--bundles/org.eclipse.compare/compare/org/eclipse/compare/structuremergeviewer/StructureDiffViewer.java35
-rw-r--r--bundles/org.eclipse.compare/plugin.properties1
-rw-r--r--bundles/org.eclipse.compare/plugin.xml1
-rw-r--r--bundles/org.eclipse.compare/schema/compareFilters.exsd283
-rw-r--r--tests/org.eclipse.compare.tests/META-INF/MANIFEST.MF2
-rw-r--r--tests/org.eclipse.compare.tests/src/org/eclipse/compare/tests/AllTests.java3
-rw-r--r--tests/org.eclipse.compare.tests/src/org/eclipse/compare/tests/DocLineComparatorTest.java212
-rw-r--r--tests/org.eclipse.compare.tests/src/org/eclipse/compare/tests/FilterTest.java14
-rw-r--r--tests/org.eclipse.compare.tests/src/org/eclipse/compare/tests/StructureCreatorTest.java181
-rw-r--r--tests/org.eclipse.compare.tests/src/org/eclipse/compare/tests/TextMergeViewerTest.java118
26 files changed, 1894 insertions, 86 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/ICompareFilter.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/ICompareFilter.java
new file mode 100644
index 0000000..1d740d3
--- /dev/null
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/ICompareFilter.java
@@ -0,0 +1,99 @@
+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 filter that can be applied during the comparison of documents that can be
+ * used to customize the detection of text differences via the compareFilter
+ * extension point. Filters are exposed as toggle actions in the compare viewer.
+ *
+ * @noimplement This interface is not intended to be implemented by clients.
+ * This is an interface for org.eclipse.compare.compareFilters
+ * extension point which is internal.
+ * @since 3.6
+ */
+public interface ICompareFilter {
+
+ /**
+ * 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[] getFilteredRegions(HashMap lineComparison);
+
+ /**
+ * Returns whether the filter 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 canCacheFilteredRegions();
+}
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 727a079..fcdc3ed 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.ChangeCompareFilterPropertyAction;
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.CompareFilterDescriptor;
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 fCompareFilterActions = new ArrayList();
private DocumentMerger fMerger;
/** The current diff */
private Diff fCurrentDiff;
@@ -1852,7 +1856,12 @@ public class TextMergeViewer extends ContentMergeViewer implements IAdaptable {
if (fIgnoreWhitespace != null)
fIgnoreWhitespace.dispose();
-
+
+ getCompareConfiguration().setProperty(
+ ChangeCompareFilterPropertyAction.COMPARE_FILTERS_INITIALIZING,
+ Boolean.TRUE);
+ disposeCompareFilterActions(false);
+
if (fSourceViewerDecorationSupport != null) {
for (Iterator iterator = fSourceViewerDecorationSupport.iterator(); iterator.hasNext();) {
((SourceViewerDecorationSupport) iterator.next()).dispose();
@@ -2790,6 +2799,8 @@ public class TextMergeViewer extends ContentMergeViewer implements IAdaptable {
Object input= getInput();
+ configureCompareFilterActions(input, ancestor, left, right);
+
Position leftRange= null;
Position rightRange= null;
@@ -3711,6 +3722,140 @@ public class TextMergeViewer extends ContentMergeViewer implements IAdaptable {
fHandlerService.registerAction(toggleLineNumbersAction, ITextEditorActionDefinitionIds.LINENUMBER_TOGGLE);
}
+ private void configureCompareFilterActions(Object input, Object ancestor,
+ Object left, Object right) {
+ if (getCompareConfiguration() != null) {
+ CompareFilterDescriptor[] compareFilterDescriptors = CompareUIPlugin
+ .getDefault().findCompareFilters(input);
+
+ Object current = getCompareConfiguration().getProperty(
+ ChangeCompareFilterPropertyAction.COMPARE_FILTER_ACTIONS);
+ boolean currentFiltersMatch = false;
+ if (current != null
+ && current instanceof List
+ && ((List) current).size() == compareFilterDescriptors.length) {
+ currentFiltersMatch = true;
+ List currentFilterActions = (List) current;
+ for (int i = 0; i < compareFilterDescriptors.length; i++) {
+ boolean match = false;
+ for (int j = 0; j < currentFilterActions.size(); j++) {
+ if (compareFilterDescriptors[i]
+ .getFilterId()
+ .equals(((ChangeCompareFilterPropertyAction) currentFilterActions
+ .get(j)).getFilterId())) {
+ match = true;
+ break;
+ }
+ }
+ if (!match) {
+ currentFiltersMatch = false;
+ break;
+ }
+ }
+ }
+
+ if (!currentFiltersMatch) {
+ getCompareConfiguration()
+ .setProperty(
+ ChangeCompareFilterPropertyAction.COMPARE_FILTERS_INITIALIZING,
+ Boolean.TRUE);
+ disposeCompareFilterActions(true);
+ fCompareFilterActions.clear();
+ for (int i = 0; i < compareFilterDescriptors.length; i++) {
+ ChangeCompareFilterPropertyAction compareFilterAction = new ChangeCompareFilterPropertyAction(
+ compareFilterDescriptors[i],
+ getCompareConfiguration());
+ compareFilterAction.setInput(input, ancestor, left, right);
+ fCompareFilterActions.add(compareFilterAction);
+ fLeft.addTextAction(compareFilterAction);
+ fRight.addTextAction(compareFilterAction);
+ fAncestor.addTextAction(compareFilterAction);
+
+ if (getCompareConfiguration().getContainer()
+ .getActionBars() != null) {
+ getCompareConfiguration()
+ .getContainer()
+ .getActionBars()
+ .getToolBarManager()
+ .appendToGroup(
+ CompareEditorContributor.FILTER_SEPARATOR,
+ compareFilterAction);
+ if (compareFilterAction.getActionDefinitionId() != null)
+ getCompareConfiguration()
+ .getContainer()
+ .getActionBars()
+ .setGlobalActionHandler(
+ compareFilterAction
+ .getActionDefinitionId(),
+ compareFilterAction);
+ }
+ }
+ if (!fCompareFilterActions.isEmpty()
+ && getCompareConfiguration().getContainer()
+ .getActionBars() != null) {
+ getCompareConfiguration().getContainer().getActionBars()
+ .getToolBarManager().markDirty();
+ getCompareConfiguration().getContainer().getActionBars()
+ .getToolBarManager().update(true);
+ getCompareConfiguration().getContainer().getActionBars()
+ .updateActionBars();
+ }
+ getCompareConfiguration()
+ .setProperty(
+ ChangeCompareFilterPropertyAction.COMPARE_FILTER_ACTIONS,
+ fCompareFilterActions);
+ getCompareConfiguration()
+ .setProperty(
+ ChangeCompareFilterPropertyAction.COMPARE_FILTERS_INITIALIZING,
+ null);
+ } else {
+ for (int i = 0; i < fCompareFilterActions.size(); i++) {
+ ((ChangeCompareFilterPropertyAction) fCompareFilterActions
+ .get(i)).setInput(input, ancestor, left, right);
+ }
+ }
+ }
+ }
+
+ private void disposeCompareFilterActions(boolean updateActionBars) {
+ Iterator compareFilterActionsIterator = fCompareFilterActions
+ .iterator();
+ while (compareFilterActionsIterator.hasNext()) {
+ ChangeCompareFilterPropertyAction compareFilterAction = (ChangeCompareFilterPropertyAction) compareFilterActionsIterator
+ .next();
+ fLeft.removeTextAction(compareFilterAction);
+ fRight.removeTextAction(compareFilterAction);
+ fAncestor.removeTextAction(compareFilterAction);
+ if (updateActionBars
+ && getCompareConfiguration().getContainer().getActionBars() != null) {
+ getCompareConfiguration().getContainer().getActionBars()
+ .getToolBarManager()
+ .remove(compareFilterAction.getId());
+ if (compareFilterAction.getActionDefinitionId() != null)
+ getCompareConfiguration()
+ .getContainer()
+ .getActionBars()
+ .setGlobalActionHandler(
+ compareFilterAction.getActionDefinitionId(),
+ null);
+ }
+ compareFilterAction.dispose();
+ }
+ if (updateActionBars
+ && !fCompareFilterActions.isEmpty()
+ && getCompareConfiguration().getContainer().getActionBars() != null) {
+ getCompareConfiguration().getContainer().getActionBars()
+ .getToolBarManager().markDirty();
+ getCompareConfiguration().getContainer().getActionBars()
+ .getToolBarManager().update(true);
+ }
+ fCompareFilterActions.clear();
+ getCompareConfiguration().setProperty(
+ ChangeCompareFilterPropertyAction.COMPARE_FILTERS, null);
+ getCompareConfiguration().setProperty(
+ ChangeCompareFilterPropertyAction.COMPARE_FILTER_ACTIONS, null);
+ }
+
/* (non-Javadoc)
* @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#handlePropertyChangeEvent(org.eclipse.jface.util.PropertyChangeEvent)
*/
@@ -3718,7 +3863,10 @@ 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(ChangeCompareFilterPropertyAction.COMPARE_FILTERS) && getCompareConfiguration()
+ .getProperty(
+ ChangeCompareFilterPropertyAction.COMPARE_FILTERS_INITIALIZING) == null)) {
fShowPseudoConflicts= fPreferenceStore.getBoolean(ComparePreferencePage.SHOW_PSEUDO_CONFLICTS);
@@ -4969,6 +5117,10 @@ public class TextMergeViewer extends ContentMergeViewer implements IAdaptable {
}
return null;
}
+
+ public int getChangesCount() {
+ return fMerger.changesCount();
+ }
};
}
if (adapter == OutlineViewerCreator.class) {
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/ChangeCompareFilterPropertyAction.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/ChangeCompareFilterPropertyAction.java
new file mode 100644
index 0000000..6093535
--- /dev/null
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/ChangeCompareFilterPropertyAction.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * 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.ICompareFilter;
+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 filter
+ */
+public class ChangeCompareFilterPropertyAction extends Action implements
+ IPropertyChangeListener, DisposeListener {
+
+ public static final String COMPARE_FILTERS = "COMPARE_FILTERS"; //$NON-NLS-1$
+ public static final String COMPARE_FILTER_ACTIONS = "COMPARE_FILTER_ACTIONS"; //$NON-NLS-1$
+ public static final String COMPARE_FILTERS_INITIALIZING = "COMPARE_FILTERS_INITIALIZING"; //$NON-NLS-1$
+
+ private CompareConfiguration fCompareConfiguration;
+ private ResourceBundle fBundle;
+ private String fPrefix = "filter."; //$NON-NLS-1$
+ private CompareFilterDescriptor fCompareFilterDescriptor;
+ private ICompareFilter fCompareFilter;
+
+ public ChangeCompareFilterPropertyAction(
+ CompareFilterDescriptor compareFilterDescriptor,
+ CompareConfiguration compareConfiguration) {
+ this.fBundle = compareFilterDescriptor.getResourceBundle();
+ this.fCompareFilterDescriptor = compareFilterDescriptor;
+ this.fCompareFilter = compareFilterDescriptor.createCompareFilter();
+ Utilities.initAction(this, fBundle, fPrefix);
+
+ // Utilities only loads images from compare plugin
+ setImageDescriptor(compareFilterDescriptor.getImageDescriptor());
+ setId(compareFilterDescriptor.getFilterId());
+ setActionDefinitionId(compareFilterDescriptor.getDefinitionId());
+ setCompareConfiguration(compareConfiguration);
+
+ if (fCompareFilter.isEnabledInitially()) {
+ setChecked(true);
+ setProperty(true);
+ }
+ }
+
+ void setProperty(boolean state) {
+ if (fCompareConfiguration != null) {
+ Map filters = new HashMap();
+ if (fCompareConfiguration.getProperty(COMPARE_FILTERS) != null) {
+ filters.putAll((Map) fCompareConfiguration
+ .getProperty(COMPARE_FILTERS));
+ }
+ if (state) {
+ filters.put(fCompareFilterDescriptor.getFilterId(),
+ fCompareFilter);
+ } else {
+ filters.remove(fCompareFilterDescriptor.getFilterId());
+ }
+ fCompareConfiguration.setProperty(COMPARE_FILTERS, filters);
+ }
+ }
+
+ boolean getProperty() {
+ Map filters = (Map) fCompareConfiguration.getProperty(COMPARE_FILTERS);
+ if (filters == null) {
+ filters = new HashMap();
+ }
+ return filters.containsKey(fCompareFilterDescriptor.getFilterId());
+ }
+
+ 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_FILTERS)
+ && event.getNewValue() instanceof Map) {
+ setChecked(((Map) event.getNewValue())
+ .containsKey(fCompareFilterDescriptor.getFilterId()));
+ }
+ }
+
+ public void dispose() {
+ if (fCompareConfiguration != null)
+ fCompareConfiguration.removePropertyChangeListener(this);
+ }
+
+ public void widgetDisposed(DisposeEvent e) {
+ dispose();
+ }
+
+ public String getFilterId() {
+ return fCompareFilterDescriptor.getFilterId();
+ }
+
+ public void setInput(Object input, Object ancestor, Object left,
+ Object right) {
+ fCompareFilter.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..10de7ce 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,34 @@
*******************************************************************************/
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.ActionContributionItem;
+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 FILTER_SEPARATOR = "compare.filters"; //$NON-NLS-1$
+ public final static String BUILTIN_SEPARATOR = "compare.builtin"; //$NON-NLS-1$
+
private IEditorPart fActiveEditorPart= null;
private ChangePropertyAction fIgnoreWhitespace;
@@ -59,10 +72,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(FILTER_SEPARATOR));
+ tbm.add(new Separator(BUILTIN_SEPARATOR));
+ tbm.appendToGroup(BUILTIN_SEPARATOR, fIgnoreWhitespace);
+ tbm.appendToGroup(BUILTIN_SEPARATOR, fToolbarNext);
+ tbm.appendToGroup(BUILTIN_SEPARATOR, fToolbarPrevious);
}
/*
@@ -106,6 +120,59 @@ public class CompareEditorContributor extends EditorActionBarContributor {
CompareConfiguration cc= editor.getCompareConfiguration();
fIgnoreWhitespace.setCompareConfiguration(cc);
+
+ IContributionItem[] items = actionBars.getToolBarManager()
+ .getItems();
+ boolean inFilters = false;
+ for (int i = 0; i < items.length; i++) {
+ if (items[i].getId().equals(FILTER_SEPARATOR)) {
+ inFilters = true;
+ } else if (items[i].getId().equals(BUILTIN_SEPARATOR)) {
+ break;
+ } else if (inFilters) {
+ if (items[i] instanceof ActionContributionItem) {
+ String definitionId = ((ActionContributionItem) items[i])
+ .getAction().getActionDefinitionId();
+ if (definitionId != null) {
+ actionBars.setGlobalActionHandler(definitionId,
+ null);
+ }
+ }
+ actionBars.getToolBarManager().remove(items[i]);
+ }
+ }
+
+ IEditorInput input = editor.getEditorInput();
+ if (input instanceof CompareEditorInput
+ && ((CompareEditorInput) input).getCompareConfiguration() != null) {
+ Object filterActions = ((CompareEditorInput) input)
+ .getCompareConfiguration()
+ .getProperty(
+ ChangeCompareFilterPropertyAction.COMPARE_FILTER_ACTIONS);
+ if (filterActions instanceof List
+ && !((List) filterActions).isEmpty()) {
+ Iterator i = ((List) filterActions).iterator();
+ while (i.hasNext()) {
+ Object next = i.next();
+ if (next instanceof ChangeCompareFilterPropertyAction) {
+ actionBars.getToolBarManager().appendToGroup(
+ FILTER_SEPARATOR,
+ (ChangeCompareFilterPropertyAction) next);
+ String definitionId = ((ChangeCompareFilterPropertyAction) next)
+ .getActionDefinitionId();
+ if (definitionId != null) {
+ actionBars
+ .setGlobalActionHandler(
+ definitionId,
+ (ChangeCompareFilterPropertyAction) 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/CompareFilterDescriptor.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareFilterDescriptor.java
new file mode 100644
index 0000000..bfddb2e
--- /dev/null
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareFilterDescriptor.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * 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.ICompareFilter;
+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 filter extension.
+ */
+public class CompareFilterDescriptor {
+
+ private final static String CLASS_ATTRIBUTE = "class"; //$NON-NLS-1$
+ private final static String ID_ATTRIBUTE = "id"; //$NON-NLS-1$
+ private final static String DEFINITION_ID_ATTRIBUTE = "definitionId"; //$NON-NLS-1$
+ private final static String FILTER_IMAGE_ATTRIBUTE = "filter.image"; //$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 CompareFilterDescriptor(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,
+ FILTER_IMAGE_ATTRIBUTE, FILTER_IMAGE_ATTRIBUTE);
+ if (path != null)
+ url = FileLocator.find(bundle, new Path(path), null);
+ }
+ fImageDescriptor = (url == null) ? null : ImageDescriptor
+ .createFromURL(url);
+ }
+
+ public ICompareFilter createCompareFilter() {
+ try {
+ return (ICompareFilter) fConfiguration
+ .createExecutableExtension(CLASS_ATTRIBUTE);
+ } catch (CoreException e) {
+ CompareUIPlugin.log(e);
+ }
+ return null;
+ }
+
+ public String getFilterId() {
+ return fConfiguration.getAttribute(ID_ATTRIBUTE);
+ }
+
+ public String getDefinitionId() {
+ return fConfiguration.getAttribute(DEFINITION_ID_ATTRIBUTE);
+ }
+
+ public ResourceBundle getResourceBundle() {
+ return fResourceBundle;
+ }
+
+ public ImageDescriptor getImageDescriptor() {
+ return fImageDescriptor;
+ }
+}
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/ComparePreferencePage.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/ComparePreferencePage.java
index f4fe72b..2a58149 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/ComparePreferencePage.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/ComparePreferencePage.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 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
@@ -327,7 +327,7 @@ public class ComparePreferencePage extends PreferencePage implements IWorkbenchP
new ModifyListener() {
public void modifyText(ModifyEvent e) {
String filters= fFilters.getText();
- String message= CompareFilter.validateResourceFilters(filters);
+ String message= CompareResourceFilter.validateResourceFilters(filters);
setValid(message == null);
setMessage(null);
setErrorMessage(message);
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareFilter.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareResourceFilter.java
index 3a17994..0e70902 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareFilter.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareResourceFilter.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2006 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,22 +10,24 @@
*******************************************************************************/
package org.eclipse.compare.internal;
-import com.ibm.icu.text.MessageFormat;
import java.util.StringTokenizer;
-import org.eclipse.core.resources.*;
+import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IStatus;
+import com.ibm.icu.text.MessageFormat;
+
-public class CompareFilter {
+public class CompareResourceFilter {
private static final char[][] NO_CHAR_CHAR= new char[0][];
private char[][] fExtraResourceFileFilters;
private String[] fExtraResourceFolderFilters;
- public CompareFilter() {
+ public CompareResourceFilter() {
// nothing to do
}
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..7dc68f7 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 FILTER_TAG = "filter"; //$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_FILTER_EXTENTION_POINT = "compareFilters"; //$NON-NLS-1$
+ private static final String COMPARE_FILTER_ID_ATTRIBUTE = "filterId"; //$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,9 +242,10 @@ public final class CompareUIPlugin extends AbstractUIPlugin {
private CompareRegistry fStructureMergeViewers= new CompareRegistry();
private CompareRegistry fContentViewers= new CompareRegistry();
private CompareRegistry fContentMergeViewers= new CompareRegistry();
+ private CompareRegistry fCompareFilters = new CompareRegistry();
private Map fStructureViewerAliases;
- private CompareFilter fFilter;
+ private CompareResourceFilter fFilter;
private IPropertyChangeListener fPropertyChangeListener;
/**
@@ -391,7 +398,28 @@ 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 filter extension point
+ elements = registry.getConfigurationElementsFor(PLUGIN_ID,
+ COMPARE_FILTER_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 (!FILTER_TAG.equals(name))
+ logErrorMessage(Utilities.getFormattedString(
+ "CompareUIPlugin.unexpectedTag", name, FILTER_TAG)); //$NON-NLS-1$
+ fCompareFilters.register(element, new CompareFilterDescriptor(
+ element));
+ }
+ }
+ for (int i = 0; i < elements.length; i++) {
+ IConfigurationElement element = elements[i];
+ if (CONTENT_TYPE_BINDING.equals(element.getName()))
+ fCompareFilters.createBinding(element,
+ COMPARE_FILTER_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 +878,114 @@ public final class CompareUIPlugin extends AbstractUIPlugin {
return getViewer(descriptors[0], oldViewer, parent, configuration);
}
+ public CompareFilterDescriptor[] findCompareFilters(Object in) {
+ Collection contentTypes = getContentTypes(in);
+ if (contentTypes == null) {
+ return new CompareFilterDescriptor[0];
+ }
+ Set result = new LinkedHashSet();
+ Iterator ctIterator = contentTypes.iterator();
+ while (ctIterator.hasNext()) {
+ Object ct = ctIterator.next();
+ if (ct instanceof IContentType) {
+ List list = fCompareFilters.searchAll((IContentType) ct);
+ if (list != null)
+ result.addAll(list);
+ } else if (ct instanceof String) {
+ List list = fCompareFilters.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 ((CompareFilterDescriptor) left)
+ .getFilterId()
+ .compareTo(
+ ((CompareFilterDescriptor) right).getFilterId());
+ }
+ });
+
+ return (CompareFilterDescriptor[]) result
+ .toArray(new CompareFilterDescriptor[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) {
@@ -1232,7 +1368,7 @@ public final class CompareUIPlugin extends AbstractUIPlugin {
public boolean filter(String name, boolean isFolder, boolean isArchive) {
if (fFilter == null) {
- fFilter= new CompareFilter();
+ fFilter= new CompareResourceFilter();
final IPreferenceStore ps= getPreferenceStore();
fFilter.setFilters(ps.getString(ComparePreferencePage.PATH_FILTER));
fPropertyChangeListener= new IPropertyChangeListener() {
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..c0a4e1a 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.ICompareFilter;
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 ICompareFilter[] fCompareFilters;
+ private char fContributor;
+ private LRUCache fCompareFilterCache;
/**
* Creates a <code>DocLineComparator</code> for the given document range.
@@ -41,8 +48,47 @@ public class DocLineComparator implements ITokenComparator {
*/
public DocLineComparator(IDocument document, IRegion region,
boolean ignoreWhiteSpace) {
+ this(document, region, ignoreWhiteSpace, null, '?');
+ }
+
+ /**
+ * Creates a <code>DocLineComparator</code> for the given document range.
+ * ignoreWhiteSpace controls whether comparing lines (in method
+ * <code>rangesEqual<code>) should ignore whitespace. Compare filters may be used
+ * to affect the detection of line differences.
+ *
+ * @param document
+ * the document from which the lines are taken
+ * @param region
+ * if non-<code>null</code> only lines within this range are
+ * taken
+ * @param ignoreWhiteSpace
+ * if <code>true</code> white space is ignored when comparing
+ * lines
+ * @param compareFilters
+ * the active compare filters for the compare
+ * @param contributor
+ * contributor of document
+ */
+ public DocLineComparator(IDocument document, IRegion region,
+ boolean ignoreWhiteSpace, ICompareFilter[] compareFilters,
+ char contributor) {
fDocument = document;
fIgnoreWhiteSpace = ignoreWhiteSpace;
+ fCompareFilters = compareFilters;
+ fContributor = contributor;
+
+ boolean cacheFilteredLines = false;
+ if (compareFilters != null && compareFilters.length > 0) {
+ cacheFilteredLines = true;
+ for (int i = 0; i < compareFilters.length; i++) {
+ if (!compareFilters[i].canCacheFilteredRegions()) {
+ cacheFilteredLines = false;
+ break;
+ }
+ }
+ }
+ fCompareFilterCache = (cacheFilteredLines) ? new LRUCache(1024) : null;
fLineOffset = 0;
if (region != null) {
@@ -116,18 +162,18 @@ 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, false);
+ 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 (fCompareFilters != null && fCompareFilters.length > 0) {
+ String[] linesToCompare = extract(thisIndex, otherIndex, other, true);
+ return linesToCompare[0].equals(linesToCompare[1]);
+ } else if (tlen == olen) {
+ String[] linesToCompare = extract(thisIndex, otherIndex, other, false);
+ return linesToCompare[0].equals(linesToCompare[1]);
}
}
return false;
@@ -149,24 +195,74 @@ public class DocLineComparator implements ITokenComparator {
//---- private methods
+ private String[] extract(int thisIndex, int otherIndex,
+ DocLineComparator other, boolean includeSeparator) {
+
+ String[] extracts = new String[2];
+ if (fCompareFilters != null && fCompareFilters.length > 0) {
+ if (fCompareFilterCache != null
+ && other.fCompareFilterCache != null) {
+ extracts[0] = (String) fCompareFilterCache.get(new Integer(
+ thisIndex));
+ if (extracts[0] == null) {
+ extracts[0] = Utilities.applyCompareFilters(
+ extract(thisIndex, includeSeparator), fContributor,
+ other.extract(otherIndex, includeSeparator), other.fContributor,
+ fCompareFilters);
+ fCompareFilterCache
+ .put(new Integer(thisIndex), extracts[0]);
+ }
+
+ extracts[1] = (String) other.fCompareFilterCache
+ .get(new Integer(otherIndex));
+ if (extracts[1] == null) {
+ extracts[1] = Utilities.applyCompareFilters(
+ other.extract(otherIndex, includeSeparator), other.fContributor,
+ extract(thisIndex, includeSeparator), fContributor, fCompareFilters);
+ other.fCompareFilterCache.put(new Integer(otherIndex),
+ extracts[1]);
+ }
+ } else {
+ String thisLine = extract(thisIndex, includeSeparator);
+ String otherLine = other.extract(otherIndex, includeSeparator);
+ extracts = new String[] {
+ Utilities.applyCompareFilters(thisLine, fContributor,
+ otherLine, other.fContributor, fCompareFilters),
+ Utilities.applyCompareFilters(otherLine,
+ other.fContributor, thisLine, fContributor,
+ fCompareFilters) };
+ }
+ } else {
+ extracts = new String[] { extract(thisIndex, includeSeparator),
+ other.extract(otherIndex, includeSeparator) };
+ }
+ return extracts;
+ }
+
/**
- * Extract a single line from the underlying document without the line separator.
+ * Extract a single line from the underlying document.
*
* @param line the number of the line to extract
+ * @param whether to include the line separator
* @return the contents of the line as a String
*/
- private String extract(int line) {
+ private String extract(int line, boolean includeSeparator) {
if (line < fLineCount) {
try {
- IRegion r= fDocument.getLineInformation(fLineOffset + line);
+ if (includeSeparator)
+ return fDocument.get(fDocument.getLineOffset(line),
+ fDocument.getLineLength(line));
+
+ IRegion r = fDocument.getLineInformation(fLineOffset + line);
return fDocument.get(r.getOffset(), r.getLength());
- } catch(BadLocationException e) {
+
+ } catch (BadLocationException e) {
// silently ignored
}
}
return ""; //$NON-NLS-1$
}
-
+
private boolean compare(String s1, String s2) {
int l1= s1.length();
int l2= s2.length();
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/IMergeViewerTestAdapter.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/IMergeViewerTestAdapter.java
index a790eaa..bccb14d 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/IMergeViewerTestAdapter.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/IMergeViewerTestAdapter.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006 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
@@ -24,4 +24,11 @@ public interface IMergeViewerTestAdapter {
* @return the document for that leg of the comparison
*/
public IDocument getDocument(char leg);
+
+ /**
+ * Returns the number of changes in merge viewer
+ *
+ * @return the number of changes
+ */
+ public int getChangesCount();
}
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..a06dc47 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
@@ -991,6 +991,10 @@ public class MergeSourceViewer implements ISelectionChangedListener,
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..6283b31 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.ICompareFilter;
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,25 @@ public class Utilities {
return dflt;
}
+ /**
+ * Returns the active compare filters for the compare configuration
+ *
+ * @param cc
+ * @return the active compare filters
+ */
+ public static ICompareFilter[] getCompareFilters(CompareConfiguration cc) {
+ if (cc != null) {
+ Object value = cc
+ .getProperty(ChangeCompareFilterPropertyAction.COMPARE_FILTERS);
+ if (value instanceof Map) {
+ Map filtersMap = (Map) value;
+ return (ICompareFilter[]) filtersMap.values().toArray(
+ new ICompareFilter[filtersMap.size()]);
+ }
+ }
+ return new ICompareFilter[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 +933,53 @@ public class Utilities {
});
return result[0];
}
+
+ /**
+ * Applies the compare filters to the lines of text taken from the specified
+ * contributors
+ *
+ * @param thisLine
+ * @param thisContributor
+ * @param otherLine
+ * @param otherContributor
+ * @param filters
+ * may be null
+ * @return returns the result of applying the filters to the line from the
+ * contributor
+ */
+ public static String applyCompareFilters(String thisLine,
+ char thisContributor, String otherLine, char otherContributor,
+ ICompareFilter[] filters) {
+ IRegion[][] ignoredRegions = new IRegion[filters.length][];
+
+ HashMap input = new HashMap(4);
+ input.put(ICompareFilter.THIS_LINE, thisLine);
+ input.put(ICompareFilter.THIS_CONTRIBUTOR, new Character(
+ thisContributor));
+ input.put(ICompareFilter.OTHER_LINE, otherLine);
+ input.put(ICompareFilter.OTHER_CONTRIBUTOR, new Character(
+ otherContributor));
+ for (int i = 0; i < filters.length; i++) {
+ ignoredRegions[i] = filters[i].getFilteredRegions(input);
+ }
+
+ boolean[] ignored = new boolean[thisLine.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(thisLine.length());
+ for (int i = 0; i < ignored.length; i++) {
+ if (!ignored[i]) {
+ buffer.append(thisLine.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..c961c80 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.ICompareFilter;
import org.eclipse.compare.contentmergeviewer.ITokenComparator;
import org.eclipse.compare.internal.CompareContentViewerSwitchingPane;
import org.eclipse.compare.internal.CompareMessages;
@@ -422,12 +423,19 @@ public class DocumentMerger {
resetPositions(aDoc);
boolean ignoreWhiteSpace= isIgnoreWhitespace();
-
- DocLineComparator sright= new DocLineComparator(rDoc, toRegion(rRegion), ignoreWhiteSpace);
- DocLineComparator sleft= new DocLineComparator(lDoc, toRegion(lRegion), ignoreWhiteSpace);
- DocLineComparator sancestor= null;
+ ICompareFilter[] compareFilters = getCompareFilters();
+
+ DocLineComparator sright = new DocLineComparator(rDoc,
+ toRegion(rRegion), ignoreWhiteSpace, compareFilters,
+ MergeViewerContentProvider.RIGHT_CONTRIBUTOR);
+ DocLineComparator sleft = new DocLineComparator(lDoc,
+ toRegion(lRegion), ignoreWhiteSpace, compareFilters,
+ MergeViewerContentProvider.LEFT_CONTRIBUTOR);
+ DocLineComparator sancestor = null;
if (aDoc != null) {
- sancestor= new DocLineComparator(aDoc, toRegion(aRegion), ignoreWhiteSpace);
+ sancestor = new DocLineComparator(aDoc, toRegion(aRegion),
+ ignoreWhiteSpace, compareFilters,
+ MergeViewerContentProvider.ANCESTOR_CONTRIBUTOR);
/*if (isPatchHunk()) {
if (isHunkOnLeft()) {
sright= new DocLineComparator(aDoc, toRegion(aRegion), ignoreWhiteSpace);
@@ -594,12 +602,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);
+ ICompareFilter[] compareFilters = getCompareFilters();
+
+ DocLineComparator sright= new DocLineComparator(rDoc, toRegion(rRegion), ignoreWhiteSpace, compareFilters, MergeViewerContentProvider.RIGHT_CONTRIBUTOR);
+ DocLineComparator sleft= new DocLineComparator(lDoc, toRegion(lRegion), ignoreWhiteSpace, compareFilters, MergeViewerContentProvider.LEFT_CONTRIBUTOR);
DocLineComparator sancestor= null;
if (aDoc != null)
- sancestor= new DocLineComparator(aDoc, toRegion(aRegion), ignoreWhiteSpace);
+ sancestor= new DocLineComparator(aDoc, toRegion(aRegion), ignoreWhiteSpace, compareFilters, MergeViewerContentProvider.ANCESTOR_CONTRIBUTOR);
final Object[] result= new Object[1];
final DocLineComparator sa= sancestor, sl= sleft, sr= sright;
@@ -681,7 +690,11 @@ public class DocumentMerger {
private boolean isIgnoreWhitespace() {
return Utilities.getBoolean(getCompareConfiguration(), CompareConfiguration.IGNORE_WHITESPACE, false);
}
-
+
+ private ICompareFilter[] getCompareFilters() {
+ return Utilities.getCompareFilters(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..3339b34 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2008 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
@@ -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,7 +419,32 @@ 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
+ * @noreference This method is not intended to be referenced by clients.
+ * @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.
* <p>
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..f978ef0 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.ICompareFilter;
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,90 @@ public abstract class StructureCreator implements IStructureCreator2 {
}
return null;
}
+
+ /**
+ * Returns true if the two nodes are equal for comparison purposes. If
+ * <code>compareFilters</code> is not empty, the filters are applied to each
+ * line of each node's text representation.
+ *
+ * @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 will be ignored
+ * when determining equality. Note: Will bypass any custom ignore
+ * whitespace behaviors contributed through implementations of
+ * <code>org.eclipse.compare.structuremergeviewer.IStructureCreator.getContents()</code>
+ * @param compareFilters
+ * the filters used to customize the comparison of lines of text.
+ * @return whether the two nodes are equal for comparison purposes
+ * @noreference This method is not intended to be referenced by clients.
+ * @since 3.6
+ */
+ public boolean contentsEquals(Object node1, char contributor1,
+ Object node2, char contributor2, boolean ignoreWhitespace,
+ ICompareFilter[] compareFilters) {
+
+ List lines1 = LineReader.readLines(new BufferedReader(new StringReader(
+ getContents(node1, false))));
+ List lines2 = LineReader.readLines(new BufferedReader(new StringReader(
+ getContents(node2, false))));
+
+ StringBuffer buffer1 = new StringBuffer();
+ StringBuffer buffer2 = new StringBuffer();
+
+ int maxLines = Math.max(lines1.size(), lines2.size());
+ for (int i = 0; i < maxLines; i++) {
+ String s1 = lines1.size() > i ? (String) lines1.get(i) : ""; //$NON-NLS-1$
+ String s2 = lines2.size() > i ? (String) lines2.get(i) : ""; //$NON-NLS-1$
+
+ if (compareFilters != null && compareFilters.length > 0) {
+ s1 = Utilities.applyCompareFilters(s1, contributor1, s2,
+ contributor2, compareFilters);
+ s2 = Utilities.applyCompareFilters(s2, contributor2, s1,
+ contributor1, compareFilters);
+ }
+ buffer1.append(s1);
+ buffer2.append(s2);
+ }
+ if (ignoreWhitespace) {
+ int l1 = buffer1.length();
+ int l2 = buffer2.length();
+ int c1 = 0, c2 = 0;
+ int i1 = 0, i2 = 0;
+
+ while (c1 != -1) {
+
+ c1 = -1;
+ while (i1 < l1) {
+ char c = buffer1.charAt(i1++);
+ if (!Character.isWhitespace(c)) {
+ c1 = c;
+ break;
+ }
+ }
+
+ c2 = -1;
+ while (i2 < l2) {
+ char c = buffer2.charAt(i2++);
+ if (!Character.isWhitespace(c)) {
+ c2 = c;
+ break;
+ }
+ }
+
+ if (c1 != c2)
+ return false;
+ }
+ } else if (!buffer1.toString().equals(buffer2.toString())) {
+ 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..b51e562 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,10 @@ 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 +610,24 @@ 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);
+ ICompareFilter[] compareFilters = Utilities
+ .getCompareFilters(getCompareConfiguration());
+ String s1, s2;
+ if (compareFilters != null && compareFilters.length > 0
+ && fStructureCreator instanceof StructureCreator) {
+ return ((StructureCreator) fStructureCreator).contentsEquals(
+ o1, contributor1, o2, contributor2, ignoreWhiteSpace,
+ compareFilters);
+ } else {
+ s1 = fStructureCreator.getContents(o1, ignoreWhiteSpace);
+ s2 = fStructureCreator.getContents(o2, ignoreWhiteSpace);
+ }
if (s1 == null || s2 == null)
return false;
return s1.equals(s2);
@@ -630,6 +645,12 @@ public class StructureDiffViewer extends DiffTreeViewer {
String key= event.getProperty();
if (key.equals(CompareConfiguration.IGNORE_WHITESPACE)) {
diff();
+ } else if (key
+ .equals(ChangeCompareFilterPropertyAction.COMPARE_FILTERS)
+ && getCompareConfiguration()
+ .getProperty(
+ ChangeCompareFilterPropertyAction.COMPARE_FILTERS_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.properties b/bundles/org.eclipse.compare/plugin.properties
index 11d1bdd..2cd5f8c 100644
--- a/bundles/org.eclipse.compare/plugin.properties
+++ b/bundles/org.eclipse.compare/plugin.properties
@@ -22,6 +22,7 @@ structureCreators= Structure Creator
structureMergeViewers= Structure Merge Viewer
contentMergeViewers= Content Merge Viewer
contentViewers= Content Viewer
+compareFilters= Compare Filters
#
# CompareUIPlugin
diff --git a/bundles/org.eclipse.compare/plugin.xml b/bundles/org.eclipse.compare/plugin.xml
index 751f46a..f3acf46 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="compareFilters" name="%compareFilters" schema="schema/compareFilters.exsd"/>
<!-- Extensions -->
<extension
diff --git a/bundles/org.eclipse.compare/schema/compareFilters.exsd b/bundles/org.eclipse.compare/schema/compareFilters.exsd
new file mode 100644
index 0000000..55b04a3
--- /dev/null
+++ b/bundles/org.eclipse.compare/schema/compareFilters.exsd
@@ -0,0 +1,283 @@
+<?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="compareFilters" name="Compare Filters"/>
+ </appInfo>
+ <documentation>
+ This extension point is for internal use only.&lt;br/&gt;
+This extension point allows a plug-in to register a compare filter
+for specific content types. The filter will be exposed as a
+toggle action in the compare viewer and can be used to customize how
+differences are calculated when comparing documents as well as affect the
+calculation of structural differences. The extension point must
+implement the interface &lt;samp&gt;org.eclipse.compare.ICompareFilter&lt;/samp&gt;.
+For the filter to affect the calculation of structural differences, the structure creator must extend
+&lt;samp&gt;org.eclipse.compare.structuremergeviewer.StructureCreator&lt;/samp&gt;.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appInfo>
+ <meta.element internal="true" />
+ </appInfo>
+ <documentation>
+ Internal use only
+ </documentation>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="filter" 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="filter">
+ <annotation>
+ <documentation>
+ Internal use only
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ A unique identifier that can be used to reference the filter. It will also be used as the action id for the toggle action added to the compare viewer
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="definitionId" type="string">
+ <annotation>
+ <documentation>
+ The command id of the toggle action added to the compare viewer
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.ui.commands/command/@id"/>
+ </appInfo>
+ </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>
+ Implementation of ICompareFilter.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.compare.ICompareFilter"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="filter.label" type="string" use="required">
+ <annotation>
+ <documentation>
+ A translatable label that will be used in the UI for this filter.
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="filter.tooltip" type="string" use="required">
+ <annotation>
+ <documentation>
+ A translatable label that will be used in the UI for this filter.
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="filter.tooltip.checked" type="string">
+ <annotation>
+ <documentation>
+ A translatable label that will be used in the UI for this filter.
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="filter.tooltip.unchecked" type="string">
+ <annotation>
+ <documentation>
+ A translatable label that will be used in the UI for this filter.
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="filter.description" type="string" use="required">
+ <annotation>
+ <documentation>
+ A translatable label that will be used in the UI for this filter.
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="filter.description.checked" type="string">
+ <annotation>
+ <documentation>
+ A translatable label that will be used in the UI for this filter.
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="filter.description.unchecked" type="string">
+ <annotation>
+ <documentation>
+ A translatable label that will be used in the UI for this filter.
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="filter.image" type="string">
+ <annotation>
+ <documentation>
+ An image that will be used in the UI for this filter.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="contentTypeBinding">
+ <annotation>
+ <documentation>
+ Internal use only.&lt;br/&gt;
+A &lt;code&gt;contentTypeBinding&lt;/code&gt; binds a compare filter 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="filterId" type="string" use="required">
+ <annotation>
+ <documentation>
+ The id of a filter defined using the &lt;code&gt;filter&lt;/code&gt; element of this extension point (i.e. &lt;code&gt;org.eclipse.compare.compareFilters&lt;/code&gt;)
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.compare.compareFilters/filter/@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>
+ The following is an example of a compare filter
+for example files (extensions &quot;.example&quot; and &quot;.example2&quot;) and
+the text content type:
+&lt;p&gt;
+&lt;pre&gt;
+&lt;extension
+ point=&quot;org.eclipse.compare.compareFilters&quot;&gt;
+ &lt;filter
+ id=&quot;com.example.IgnorePrefixId&quot;
+ class=&quot;com.example.IgnorePrefix&quot;
+ extensions=&quot;example,example2&quot;
+ definitionId=&quot;com.example.IgnorePrefixCommand&quot;
+ filter.description=&quot;Ignore Columns 1-6&quot;
+ filter.label=&quot;Ignore Prefix&quot;
+ filter.image=&quot;/icons/ignorePrefix.gif&quot;
+ filter.tooltip=&quot;Ignore Prefix&quot;&gt;
+ &lt;/filter&gt;
+ &lt;contentTypeBinding
+ contentTypeId=&quot;org.eclipse.core.runtime.text&quot;
+ filterId=&quot;com.example.IgnorePrefixId&quot;&gt;
+ &lt;/contentTypeBinding&gt;
+ &lt;/extension&gt;
+&lt;/pre&gt;
+&lt;/p&gt;
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiinfo"/>
+ </appInfo>
+ <documentation>
+ The contributed class must implement &lt;samp&gt;org.eclipse.compare.ICompareFilter&lt;/samp&gt;. For the filter to affect the calculation of structural differences, the structure creator must extend &lt;samp&gt;org.eclipse.compare.structuremergeviewer.StructureCreator&lt;/samp&gt;.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ Copyright (c) 2013 IBM Corporation and others.&lt;br&gt;
+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 &lt;a href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/tests/org.eclipse.compare.tests/META-INF/MANIFEST.MF b/tests/org.eclipse.compare.tests/META-INF/MANIFEST.MF
index 15b8c03..e7a39c5 100644
--- a/tests/org.eclipse.compare.tests/META-INF/MANIFEST.MF
+++ b/tests/org.eclipse.compare.tests/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.compare.tests;singleton:=true
-Bundle-Version: 3.5.400.qualifier
+Bundle-Version: 3.6.0.qualifier
Bundle-ClassPath: comparetests.jar
Require-Bundle: org.junit,
org.eclipse.compare,
diff --git a/tests/org.eclipse.compare.tests/src/org/eclipse/compare/tests/AllTests.java b/tests/org.eclipse.compare.tests/src/org/eclipse/compare/tests/AllTests.java
index a47c61f..061de77 100644
--- a/tests/org.eclipse.compare.tests/src/org/eclipse/compare/tests/AllTests.java
+++ b/tests/org.eclipse.compare.tests/src/org/eclipse/compare/tests/AllTests.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
@@ -36,6 +36,7 @@ public class AllTests {
suite.addTestSuite(PatchUITest.class);
suite.addTestSuite(RangeDifferencerThreeWayDiffTest.class);
suite.addTestSuite(CompareUIPluginTest.class);
+ suite.addTestSuite(StructureCreatorTest.class);
// $JUnit-END$
return suite;
}
diff --git a/tests/org.eclipse.compare.tests/src/org/eclipse/compare/tests/DocLineComparatorTest.java b/tests/org.eclipse.compare.tests/src/org/eclipse/compare/tests/DocLineComparatorTest.java
index cf963c7..5c8b7c6 100644
--- a/tests/org.eclipse.compare.tests/src/org/eclipse/compare/tests/DocLineComparatorTest.java
+++ b/tests/org.eclipse.compare.tests/src/org/eclipse/compare/tests/DocLineComparatorTest.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,13 +10,17 @@
*******************************************************************************/
package org.eclipse.compare.tests;
+import java.util.HashMap;
+
import junit.framework.Assert;
import junit.framework.TestCase;
+import org.eclipse.compare.ICompareFilter;
import org.eclipse.compare.internal.DocLineComparator;
import org.eclipse.compare.rangedifferencer.IRangeComparator;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Region;
public class DocLineComparatorTest extends TestCase {
@@ -59,6 +63,212 @@ public class DocLineComparatorTest extends TestCase {
Assert.assertTrue(comp1.rangesEqual(0, comp2, 0));
}
+ public void testOneCompareFilter() {
+ IDocument doc1 = new Document();
+ doc1.set("if (s.strip))"); //$NON-NLS-1$
+
+ IDocument doc2 = new Document();
+ doc2.set("IF (S.stRIp))"); //$NON-NLS-1$
+
+ IDocument doc3 = new Document();
+ doc3.set("IF (S.stRIp)) "); //$NON-NLS-1$
+
+ ICompareFilter filter = new ICompareFilter() {
+
+ public void setInput(Object input, Object ancestor, Object left,
+ Object right) {
+ // EMPTY
+ }
+
+ public IRegion[] getFilteredRegions(HashMap lineComparison) {
+ return new IRegion[] { new Region(0, 2), new Region(4, 1),
+ new Region(8, 2) };
+ }
+
+ public boolean isEnabledInitially() {
+ return false;
+ }
+
+ public boolean canCacheFilteredRegions() {
+ return false;
+ }
+ };
+
+ IRangeComparator comp1 = new DocLineComparator(doc1, null, false,
+ new ICompareFilter[] { filter }, 'L');
+ IRangeComparator comp2 = new DocLineComparator(doc2, null, false,
+ new ICompareFilter[] { filter }, 'R');
+ Assert.assertTrue(comp1.rangesEqual(0, comp2, 0));
+
+ IRangeComparator comp3 = new DocLineComparator(doc1, null, true,
+ new ICompareFilter[] { filter }, 'L');
+ IRangeComparator comp4 = new DocLineComparator(doc3, null, true,
+ new ICompareFilter[] { filter }, 'R');
+ Assert.assertTrue(comp3.rangesEqual(0, comp4, 0));
+
+ IRangeComparator comp5 = new DocLineComparator(doc1, null, false,
+ new ICompareFilter[] { filter }, 'L');
+ IRangeComparator comp6 = new DocLineComparator(doc3, null, false,
+ new ICompareFilter[] { filter }, 'R');
+ Assert.assertFalse(comp5.rangesEqual(0, comp6, 0));
+ }
+
+ public void testMultipleCompareFilters() {
+ IDocument doc1 = new Document();
+ doc1.set("if (s.strip))"); //$NON-NLS-1$
+
+ IDocument doc2 = new Document();
+ doc2.set("IF (S.stRIp))"); //$NON-NLS-1$
+
+ ICompareFilter filter1 = new ICompareFilter() {
+
+ public void setInput(Object input, Object ancestor, Object left,
+ Object right) {
+ // EMPTY
+ }
+
+ public IRegion[] getFilteredRegions(HashMap lineComparison) {
+ return new IRegion[] { new Region(0, 2) };
+ }
+
+ public boolean isEnabledInitially() {
+ return false;
+ }
+
+ public boolean canCacheFilteredRegions() {
+ return false;
+ }
+ };
+
+ ICompareFilter filter2 = new ICompareFilter() {
+
+ public void setInput(Object input, Object ancestor, Object left,
+ Object right) {
+ // EMPTY
+ }
+
+ public IRegion[] getFilteredRegions(HashMap lineComparison) {
+ return new IRegion[] { new Region(4, 1) };
+ }
+
+ public boolean isEnabledInitially() {
+ return false;
+ }
+
+ public boolean canCacheFilteredRegions() {
+ return false;
+ }
+ };
+
+ ICompareFilter filter3 = new ICompareFilter() {
+
+ public void setInput(Object input, Object ancestor, Object left,
+ Object right) {
+ // EMPTY
+ }
+
+ public IRegion[] getFilteredRegions(HashMap lineComparison) {
+ return new IRegion[] { new Region(8, 2) };
+ }
+
+ public boolean isEnabledInitially() {
+ return false;
+ }
+
+ public boolean canCacheFilteredRegions() {
+ return false;
+ }
+ };
+
+ IRangeComparator comp1 = new DocLineComparator(doc1, null, false,
+ new ICompareFilter[] { filter1, filter2, filter3 }, 'L');
+ IRangeComparator comp2 = new DocLineComparator(doc2, null, false,
+ new ICompareFilter[] { filter1, filter2, filter3 }, 'R');
+ Assert.assertTrue(comp1.rangesEqual(0, comp2, 0));
+
+ IRangeComparator comp3 = new DocLineComparator(doc1, null, false,
+ new ICompareFilter[] { filter2, filter3 }, 'L');
+ IRangeComparator comp4 = new DocLineComparator(doc2, null, false,
+ new ICompareFilter[] { filter2, filter3 }, 'R');
+ Assert.assertFalse(comp3.rangesEqual(0, comp4, 0));
+ }
+
+ public void testWhitespace() {
+ IDocument[] docs = new IDocument[6];
+ docs[0] = new Document();
+ docs[1] = new Document();
+ docs[2] = new Document();
+ docs[3] = new Document();
+ docs[4] = new Document();
+ docs[5] = new Document();
+
+ docs[0].set("if (s.strip))\r\n");//$NON-NLS-1$
+ docs[1].set("if (s.strip))\n"); //$NON-NLS-1$
+ docs[2].set("if (s .strip))\n"); //$NON-NLS-1$
+ docs[3].set("if (s.str ip))\r"); //$NON-NLS-1$
+ docs[4].set("if (s.strip))"); //$NON-NLS-1$
+ docs[5].set("if (s.stri p))"); //$NON-NLS-1$
+
+ ICompareFilter[][] filters = new ICompareFilter[3][];
+ filters[0] = null;
+ filters[1] = new ICompareFilter[]{
+ new ICompareFilter() {
+
+ public void setInput(Object input, Object ancestor, Object left,
+ Object right) {
+ // EMPTY
+ }
+
+ public IRegion[] getFilteredRegions(HashMap lineComparison) {
+ return new IRegion[] { new Region(0, 2) };
+ }
+
+ public boolean isEnabledInitially() {
+ return false;
+ }
+
+ public boolean canCacheFilteredRegions() {
+ return true; // cache-able
+ }
+ }
+ };
+
+ filters[2] = new ICompareFilter[]{
+ new ICompareFilter() {
+
+ public void setInput(Object input, Object ancestor, Object left,
+ Object right) {
+ // EMPTY
+ }
+
+ public IRegion[] getFilteredRegions(HashMap lineComparison) {
+ return new IRegion[] { new Region(0, 2) };
+ }
+
+ public boolean isEnabledInitially() {
+ return false;
+ }
+
+ public boolean canCacheFilteredRegions() {
+ return false; // not cache-able
+ }
+ }
+ };
+
+ IRangeComparator l, r;
+ for (int i=0;i<docs.length;i++)
+ for (int j=i+1;j<docs.length;j++)
+ for (int k=0;k<filters.length;k++) {
+ l = new DocLineComparator(docs[i], null, false, filters[k], 'L');
+ r = new DocLineComparator(docs[j], null, false, filters[k], 'R');
+ Assert.assertFalse(l.rangesEqual(0, r, 0));
+
+ l = new DocLineComparator(docs[i], null, true, filters[k], 'L');
+ r = new DocLineComparator(docs[j], null, true, filters[k], 'R');
+ Assert.assertTrue(l.rangesEqual(0, r, 0));
+ }
+ }
+
public void testEmpty() {
IDocument doc1= new Document();
doc1.set(""); //$NON-NLS-1$
diff --git a/tests/org.eclipse.compare.tests/src/org/eclipse/compare/tests/FilterTest.java b/tests/org.eclipse.compare.tests/src/org/eclipse/compare/tests/FilterTest.java
index 2e1e48b..29016b1 100644
--- a/tests/org.eclipse.compare.tests/src/org/eclipse/compare/tests/FilterTest.java
+++ b/tests/org.eclipse.compare.tests/src/org/eclipse/compare/tests/FilterTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2006 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,42 +10,42 @@
*******************************************************************************/
package org.eclipse.compare.tests;
-import org.eclipse.compare.internal.CompareFilter;
+import org.eclipse.compare.internal.CompareResourceFilter;
import junit.framework.*;
import junit.framework.TestCase;
public class FilterTest extends TestCase {
- CompareFilter fFilter;
+ CompareResourceFilter fFilter;
public FilterTest(String name) {
super(name);
}
public void testFilterFile() {
- CompareFilter f= new CompareFilter();
+ CompareResourceFilter f= new CompareResourceFilter();
f.setFilters("*.class"); //$NON-NLS-1$
Assert.assertTrue("file foo.class should be filtered", f.filter("foo.class", false, false)); //$NON-NLS-1$ //$NON-NLS-2$
Assert.assertFalse("file foo.java shouldn't be filtered", f.filter("foo.java", false, false)); //$NON-NLS-1$ //$NON-NLS-2$
}
public void testFilterDotFile() {
- CompareFilter f= new CompareFilter();
+ CompareResourceFilter f= new CompareResourceFilter();
f.setFilters(".cvsignore"); //$NON-NLS-1$
Assert.assertTrue("file .cvsignore should be filtered", f.filter(".cvsignore", false, false)); //$NON-NLS-1$ //$NON-NLS-2$
Assert.assertFalse("file foo.cvsignore shouldn't be filtered", f.filter("foo.cvsignore", false, false)); //$NON-NLS-1$ //$NON-NLS-2$
}
public void testFilterFolder() {
- CompareFilter f= new CompareFilter();
+ CompareResourceFilter f= new CompareResourceFilter();
f.setFilters("bin/"); //$NON-NLS-1$
Assert.assertTrue("folder bin should be filtered", f.filter("bin", true, false)); //$NON-NLS-1$ //$NON-NLS-2$
Assert.assertFalse("file bin shouldn't be filtered", f.filter("bin", false, false)); //$NON-NLS-1$ //$NON-NLS-2$
}
public void testMultiFilter() {
- CompareFilter f= new CompareFilter();
+ CompareResourceFilter f= new CompareResourceFilter();
f.setFilters("*.class, .cvsignore, bin/, src/"); //$NON-NLS-1$
Assert.assertTrue("file foo.class should be filtered", f.filter("foo.class", false, false)); //$NON-NLS-1$ //$NON-NLS-2$
Assert.assertFalse("file foo.java shouldn't be filtered", f.filter("foo.java", false, false)); //$NON-NLS-1$ //$NON-NLS-2$
diff --git a/tests/org.eclipse.compare.tests/src/org/eclipse/compare/tests/StructureCreatorTest.java b/tests/org.eclipse.compare.tests/src/org/eclipse/compare/tests/StructureCreatorTest.java
new file mode 100644
index 0000000..27076c6
--- /dev/null
+++ b/tests/org.eclipse.compare.tests/src/org/eclipse/compare/tests/StructureCreatorTest.java
@@ -0,0 +1,181 @@
+/*******************************************************************************
+ * 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.tests;
+
+import java.util.HashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.eclipse.compare.ICompareFilter;
+import org.eclipse.compare.ISharedDocumentAdapter;
+import org.eclipse.compare.structuremergeviewer.DocumentRangeNode;
+import org.eclipse.compare.structuremergeviewer.IStructureComparator;
+import org.eclipse.compare.structuremergeviewer.StructureCreator;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Region;
+
+public class StructureCreatorTest extends TestCase {
+
+ public StructureCreatorTest() {
+ super();
+ }
+
+ public StructureCreatorTest(String name) {
+ super(name);
+ }
+
+ public void testIgnoreWhitespace() {
+ IDocument[] docs = new IDocument[15];
+ docs[0] = new Document();
+ docs[1] = new Document();
+ docs[2] = new Document();
+ docs[3] = new Document();
+ docs[4] = new Document();
+ docs[5] = new Document();
+ docs[6] = new Document();
+ docs[7] = new Document();
+ docs[8] = new Document();
+ docs[9] = new Document();
+ docs[10] = new Document();
+ docs[11] = new Document();
+ docs[12] = new Document();
+ docs[13] = new Document();
+ docs[14] = new Document();
+
+ docs[0].set("ABCDEF"); //$NON-NLS-1$
+ docs[1].set("ABC DEF"); //$NON-NLS-1$
+ docs[2].set("ABC\r\nDEF"); //$NON-NLS-1$
+ docs[3].set("ABC\r\nDEF "); //$NON-NLS-1$
+ docs[4].set("\r\nABC\r\nDEF"); //$NON-NLS-1$
+ docs[5].set(" \r\nABC\r\nDEF"); //$NON-NLS-1$
+ docs[6].set("\r\nABC\r\nDEF\r\n"); //$NON-NLS-1$
+ docs[7].set("\r\nA BC\r\nDE F\r\n"); //$NON-NLS-1$
+ docs[8].set("ABC\r\n\r\nDEF"); //$NON-NLS-1$
+ docs[9].set("ABC\nDEF"); //$NON-NLS-1$
+ docs[10].set("ABC\nDEF "); //$NON-NLS-1$
+ docs[11].set("ABC\nDEF\n"); //$NON-NLS-1$
+ docs[12].set("\nABCDEF"); //$NON-NLS-1$
+ docs[13].set(" \nAB CD EF"); //$NON-NLS-1$
+ docs[14].set("\nABC\nDEF\n"); //$NON-NLS-1$
+
+ ICompareFilter[][] filters = new ICompareFilter[3][];
+ filters[0] = null;
+ filters[1] = new ICompareFilter[] { new ICompareFilter() {
+
+ public void setInput(Object input, Object ancestor, Object left,
+ Object right) {
+ // EMPTY
+ }
+
+ public IRegion[] getFilteredRegions(HashMap lineComparison) {
+ String line = lineComparison.get(ICompareFilter.THIS_LINE)
+ .toString();
+ int index = line.indexOf("A");
+ if (index > -1)
+ return new IRegion[] { new Region(index, 1) };
+ return null;
+ }
+
+ public boolean isEnabledInitially() {
+ return false;
+ }
+
+ public boolean canCacheFilteredRegions() {
+ return true; // cache-able
+ }
+ } };
+
+ filters[2] = new ICompareFilter[] { new ICompareFilter() {
+
+ public void setInput(Object input, Object ancestor, Object left,
+ Object right) {
+ // EMPTY
+ }
+
+ public IRegion[] getFilteredRegions(HashMap lineComparison) {
+ String line = lineComparison.get(ICompareFilter.THIS_LINE)
+ .toString();
+ int index = line.indexOf("E");
+ if (index > -1)
+ return new IRegion[] { new Region(index, 1) };
+ return null;
+ }
+
+ public boolean isEnabledInitially() {
+ return false;
+ }
+
+ public boolean canCacheFilteredRegions() {
+ return false; // not cache-able
+ }
+ } };
+
+ StructureCreator creator = new StructureCreator() {
+ private Pattern whitespace = Pattern.compile("\\s+");
+ private Matcher matcher = null;
+
+ public String getName() {
+ return "NAME";
+ }
+
+ public String getContents(Object node, boolean ignoreWhitespace) {
+ DocumentRangeNode drn = (DocumentRangeNode) node;
+ String retval = null;
+ try {
+ retval = drn.getDocument().get(drn.getRange().getOffset(),
+ drn.getRange().getLength());
+ if (ignoreWhitespace) {
+ if (matcher == null)
+ matcher = whitespace.matcher(retval);
+ else
+ matcher.reset(retval);
+ retval = matcher.replaceAll("");
+ }
+ } catch (BadLocationException ble) {
+ assertNull(ble);
+ }
+ return retval;
+ }
+
+ protected IStructureComparator createStructureComparator(
+ Object element, IDocument document,
+ ISharedDocumentAdapter sharedDocumentAdapter,
+ IProgressMonitor monitor) throws CoreException {
+ return new DocumentRangeNode(1, "ID", document, 0,
+ document.getLength());
+ }
+
+ };
+ DocumentRangeNode l, r;
+ for (int i = 0; i < docs.length; i++)
+ for (int j = i + 1; j < docs.length; j++)
+ for (int k = 0; k < filters.length; k++) {
+
+ l = new DocumentRangeNode(1, "ID", docs[i], 0,
+ docs[i].getLength());
+ r = new DocumentRangeNode(1, "ID", docs[j], 0,
+ docs[j].getLength());
+ creator.contentsEquals(l, 'L', r, 'R', true, filters[k]);
+ Assert.assertFalse(creator.contentsEquals(l, 'L', r, 'R',
+ false, filters[k]));
+ Assert.assertTrue(creator.contentsEquals(l, 'L', r, 'R',
+ true, filters[k]));
+ }
+ }
+} \ No newline at end of file
diff --git a/tests/org.eclipse.compare.tests/src/org/eclipse/compare/tests/TextMergeViewerTest.java b/tests/org.eclipse.compare.tests/src/org/eclipse/compare/tests/TextMergeViewerTest.java
index 608e447..171d4ac 100644
--- a/tests/org.eclipse.compare.tests/src/org/eclipse/compare/tests/TextMergeViewerTest.java
+++ b/tests/org.eclipse.compare.tests/src/org/eclipse/compare/tests/TextMergeViewerTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006 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,21 +10,36 @@
*******************************************************************************/
package org.eclipse.compare.tests;
-import java.io.*;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
import junit.framework.TestCase;
-import org.eclipse.compare.*;
+import org.eclipse.compare.CompareConfiguration;
+import org.eclipse.compare.ICompareFilter;
+import org.eclipse.compare.IEditableContent;
+import org.eclipse.compare.IStreamContentAccessor;
+import org.eclipse.compare.ITypedElement;
import org.eclipse.compare.contentmergeviewer.TextMergeViewer;
-import org.eclipse.compare.internal.*;
+import org.eclipse.compare.internal.ChangeCompareFilterPropertyAction;
+import org.eclipse.compare.internal.IMergeViewerTestAdapter;
+import org.eclipse.compare.internal.MergeViewerContentProvider;
+import org.eclipse.compare.internal.Utilities;
import org.eclipse.compare.structuremergeviewer.DiffNode;
import org.eclipse.compare.structuremergeviewer.Differencer;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Region;
import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.*;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
public class TextMergeViewerTest extends TestCase {
@@ -157,6 +172,11 @@ public class TextMergeViewerTest extends TestCase {
public TestMergeViewer(Composite parent) {
super(parent, new CompareConfiguration());
}
+
+ public TestMergeViewer(Composite parent, CompareConfiguration cc) {
+ super(parent, cc);
+ }
+
public void copy(boolean leftToRight) {
super.copy(leftToRight);
}
@@ -185,11 +205,16 @@ public class TextMergeViewerTest extends TestCase {
}
private void runInDialog(Object input, Runnable runnable) throws Exception {
+ runInDialog(input, runnable, new CompareConfiguration());
+ }
+
+ private void runInDialog(Object input, Runnable runnable,
+ final CompareConfiguration cc) throws Exception {
Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
Dialog dialog = new Dialog(shell) {
protected Control createDialogArea(Composite parent) {
Composite composite = (Composite) super.createDialogArea(parent);
- viewer = new TestMergeViewer(composite);
+ viewer = new TestMergeViewer(composite, cc);
return composite;
}
};
@@ -354,5 +379,86 @@ public class TextMergeViewerTest extends TestCase {
assertEquals(newText, ((EditableTestElement)testNode.getRight()).getContentsAsString());
}
+ public void testCompareFilter() throws Exception {
+ DiffNode parentNode = new DiffNode(new ParentTestElement(),
+ new ParentTestElement());
+
+ final String leftString = "HI there";
+ final String rightString = "hi there";
+ final EditableTestElement leftElement = new EditableTestElement(
+ leftString.getBytes());
+ final EditableTestElement rightElement = new EditableTestElement(
+ rightString.getBytes());
+ DiffNode testNode = new DiffNode(parentNode, Differencer.CHANGE, null,
+ leftElement, rightElement);
+ final CompareConfiguration cc = new CompareConfiguration();
+ runInDialog(testNode, new Runnable() {
+ public void run() {
+ Object adapter = viewer
+ .getAdapter(IMergeViewerTestAdapter.class);
+ if (adapter instanceof IMergeViewerTestAdapter) {
+ IMergeViewerTestAdapter ta = (IMergeViewerTestAdapter) adapter;
+ assertEquals(ta.getChangesCount(), 1);
+
+ Map filters = new HashMap();
+ filters.put("filter.id", new ICompareFilter() {
+ public void setInput(Object input, Object ancestor,
+ Object left, Object right) {
+ assertTrue(leftElement == left);
+ assertTrue(rightElement == right);
+ }
+
+ public IRegion[] getFilteredRegions(
+ HashMap lineComparison) {
+ Object thisLine = lineComparison.get(THIS_LINE);
+ Object thisContributor = lineComparison
+ .get(THIS_CONTRIBUTOR);
+ Object otherLine = lineComparison.get(OTHER_LINE);
+ Object otherContributor = lineComparison
+ .get(OTHER_CONTRIBUTOR);
+ if (thisContributor.equals(new Character('L'))) {
+ assertEquals(thisLine, leftString);
+ assertEquals(otherContributor, new Character(
+ 'R'));
+ assertEquals(otherLine, rightString);
+ } else {
+ assertEquals(thisContributor,
+ new Character('R'));
+ assertEquals(thisLine, rightString);
+ assertEquals(otherContributor, new Character(
+ 'L'));
+ assertEquals(otherLine, leftString);
+ }
+
+ if (thisContributor.equals(new Character('L')))
+ return new IRegion[] { new Region(0, 1),
+ new Region(1, 1) };
+
+ return new IRegion[] { new Region(0, 2) };
+ }
+
+ public boolean isEnabledInitially() {
+ return false;
+ }
+
+ public boolean canCacheFilteredRegions() {
+ return true;
+ }
+
+ });
+
+ cc.setProperty(
+ ChangeCompareFilterPropertyAction.COMPARE_FILTERS,
+ filters);
+ assertEquals(ta.getChangesCount(), 0);
+
+ cc.setProperty(
+ ChangeCompareFilterPropertyAction.COMPARE_FILTERS,
+ null);
+ assertEquals(ta.getChangesCount(), 1);
+ }
+ }
+ }, cc);
+ }
}