diff --git org.eclipse.compare/plugin.properties org.eclipse.compare/plugin.properties index c31d2f8..76a213b 100644 --- org.eclipse.compare/plugin.properties +++ org.eclipse.compare/plugin.properties @@ -86,6 +86,9 @@ CompareWithMenu.label= Comp&are With CompareWithEachOtherAction.label= &Each Other CompareWithEachOtherAction.tooltip= Compare the Selected Resources +CompareWithEachOtherActionFiltered.label= Each Other (&filtered) +CompareWithEachOtherAction.tooltip= Compare the Selected Resources ignoring rules defined in the Preferences. + CompareWithOtherResource.label= &Other Resource... CompareWithOtherResource.tooltip= Open the 'Compare With' Dialog @@ -162,6 +165,16 @@ compareResolvedColor.description= The color used to indicate a resolved change i compareFontDefiniton.label= Compare text font compareFontDefiniton.description= The compare text font is used by textual compare/merge tools. +# filtered compare +ComparePreferencePage.filteredCompareTab.label= &Filtered Compare +ComparePreferencePage.filteredCompareTab.text= Patterns to ignore in 'Compare with each other (filtered)' +ComparePreferencePage.filteredCompareTab.addExpression= &Add Expression +ComparePreferencePage.filteredCompareTab.addExpression.dialog.title= Add Ignore Regexp +ComparePreferencePage.filteredCompareTab.addExpression.dialog.message= Enter a Regexp to at it to the ignore list. +ComparePreferencePage.filteredCompareTab.addExpression.dialog.initialValue= +ComparePreferencePage.filteredCompareTab.addExpression.dialog.valueAlreadyExists.title=Pattern already exists +ComparePreferencePage.filteredCompareTab.addExpression.dialog.valueAlreadyExists.message=Your Pattern is already in the ignore list. +ComparePreferencePage.filteredCompareTab.removeExpression= &Remove Expression preferenceKeywords.general=merge merging whitespace filter synchronize scrolling ancestor conflict line pseudo navigation next previous diff --git org.eclipse.compare/plugin.xml org.eclipse.compare/plugin.xml index f3acf46..c71a9c2 100644 --- org.eclipse.compare/plugin.xml +++ org.eclipse.compare/plugin.xml @@ -222,6 +222,19 @@ + + + + diff --git org.eclipse.compare/src/org/eclipse/compare/internal/CompareActionFiltered.java org.eclipse.compare/src/org/eclipse/compare/internal/CompareActionFiltered.java new file mode 100644 index 0000000..a05a8ec --- /dev/null +++ org.eclipse.compare/src/org/eclipse/compare/internal/CompareActionFiltered.java @@ -0,0 +1,52 @@ +package org.eclipse.compare.internal; + +import org.eclipse.compare.CompareConfiguration; +import org.eclipse.compare.CompareUI; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.IObjectActionDelegate; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; + +/* + * The "Compare with each other (filtered)" action + */ +public class CompareActionFiltered extends BaseCompareAction implements IObjectActionDelegate { + + protected ResourceCompareInput fInput; + protected IWorkbenchPage fWorkbenchPage; + protected boolean showSelectAncestorDialog = true; + + public void run(ISelection selection) { + if (fInput != null) { + // Pass the shell so setSelection can prompt the user for which + // resource should be the ancestor + boolean ok = fInput.setSelection(selection, fWorkbenchPage + .getWorkbenchWindow().getShell(), showSelectAncestorDialog); + if (!ok) return; + fInput.initializeCompareConfiguration(); + CompareUI.openCompareEditorOnPage(fInput, fWorkbenchPage); + fInput= null; // don't reuse this input! + } + } + + protected boolean isEnabled(ISelection selection) { + if (fInput == null) { + CompareConfiguration cc= new CompareConfiguration(); + // buffered merge mode: don't ask for confirmation + // when switching between modified resources + cc.setProperty(CompareEditor.CONFIRM_SAVE_PROPERTY, new Boolean(false)); + cc.setProperty("filtered", new Boolean(true)); + + // uncomment following line to have separate outline view + //cc.setProperty(CompareConfiguration.USE_OUTLINE_VIEW, new Boolean(true)); + + fInput= new ResourceCompareInput(cc); + } + return fInput.isEnabled(selection); + } + + public void setActivePart(IAction action, IWorkbenchPart targetPart) { + fWorkbenchPage= targetPart.getSite().getPage(); + } +} diff --git org.eclipse.compare/src/org/eclipse/compare/internal/ComparePreferencePage.java org.eclipse.compare/src/org/eclipse/compare/internal/ComparePreferencePage.java index 2a58149..e8e08c8 100644 --- org.eclipse.compare/src/org/eclipse/compare/internal/ComparePreferencePage.java +++ org.eclipse.compare/src/org/eclipse/compare/internal/ComparePreferencePage.java @@ -15,7 +15,24 @@ import java.io.InputStream; import java.util.HashMap; import java.util.Iterator; import java.util.Map; +import java.util.StringTokenizer; +import org.eclipse.compare.CompareConfiguration; +import org.eclipse.compare.IEncodedStreamContentAccessor; +import org.eclipse.compare.ITypedElement; +import org.eclipse.compare.contentmergeviewer.TextMergeViewer; +import org.eclipse.compare.internal.core.ComparePlugin; +import org.eclipse.compare.structuremergeviewer.DiffNode; +import org.eclipse.compare.structuremergeviewer.Differencer; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.InputDialog; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.jface.preference.RadioGroupFieldEditor; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; @@ -30,32 +47,20 @@ import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.TabFolder; import org.eclipse.swt.widgets.TabItem; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; - -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.preference.PreferencePage; -import org.eclipse.jface.preference.RadioGroupFieldEditor; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; - import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.dialogs.PreferenceLinkArea; import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer; -import org.eclipse.compare.CompareConfiguration; -import org.eclipse.compare.IEncodedStreamContentAccessor; -import org.eclipse.compare.ITypedElement; -import org.eclipse.compare.contentmergeviewer.TextMergeViewer; -import org.eclipse.compare.internal.core.ComparePlugin; -import org.eclipse.compare.structuremergeviewer.DiffNode; -import org.eclipse.compare.structuremergeviewer.Differencer; - public class ComparePreferencePage extends PreferencePage implements IWorkbenchPreferencePage { @@ -101,6 +106,8 @@ public class ComparePreferencePage extends PreferencePage implements IWorkbenchP public static final String ADDED_LINES_REGEX= PREFIX + "AddedLinesRegex"; //$NON-NLS-1$ public static final String REMOVED_LINES_REGEX= PREFIX + "RemovedLinesRegex"; //$NON-NLS-1$ + public static final String IGNORES_REGEXP= PREFIX + "IgnorePatterns"; + private static final String IGNORES_REGEXP_DELIMITER = ">#<"; private TextMergeViewer fPreviewViewer; private IPropertyChangeListener fPreferenceChangeListener; @@ -131,8 +138,10 @@ public class ComparePreferencePage extends PreferencePage implements IWorkbenchP new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PATH_FILTER), new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, ICompareUIConstants.PREF_NAVIGATION_END_ACTION), new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, ICompareUIConstants.PREF_NAVIGATION_END_ACTION_LOCAL), + new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, IGNORES_REGEXP), }; private RadioGroupFieldEditor editor; + private Table ignoreTable; public static void initDefaults(IPreferenceStore store) { @@ -153,6 +162,12 @@ public class ComparePreferencePage extends PreferencePage implements IWorkbenchP store.setDefault(PATH_FILTER, ""); //$NON-NLS-1$ store.setDefault(ICompareUIConstants.PREF_NAVIGATION_END_ACTION, ICompareUIConstants.PREF_VALUE_PROMPT); store.setDefault(ICompareUIConstants.PREF_NAVIGATION_END_ACTION_LOCAL, ICompareUIConstants.PREF_VALUE_LOOP); + + store.setDefault( + IGNORES_REGEXP, + ".*\\$Id:.*" + IGNORES_REGEXP_DELIMITER + + "^import.*" + IGNORES_REGEXP_DELIMITER + + "^\\s*$"); } public ComparePreferencePage() { @@ -189,6 +204,14 @@ public class ComparePreferencePage extends PreferencePage implements IWorkbenchP public boolean performOk() { fOverlayStore.setValue(ADDED_LINES_REGEX, addedLinesRegex.getText()); fOverlayStore.setValue(REMOVED_LINES_REGEX, removedLinesRegex.getText()); + + // store ignore list + TableItem[] items = ignoreTable.getItems(); + String[] elements = new String[items.length]; + for (int ti = 0; ti < items.length; ti++) { + elements[ti] = items[ti].getText(); + } + storeIgnoreRegexpPreferences(elements); editor.store(); fOverlayStore.propagate(); @@ -261,6 +284,11 @@ public class ComparePreferencePage extends PreferencePage implements IWorkbenchP //item.setImage(JavaPluginImages.get(JavaPluginImages.IMG_OBJS_CFILE)); item.setControl(createTextComparePage(folder)); + item= new TabItem(folder, SWT.NONE); + item.setText(Utilities.getString("ComparePreferencePage.filteredCompareTab.label")); //$NON-NLS-1$ + //item.setImage(JavaPluginImages.get(JavaPluginImages.IMG_OBJS_CFILE)); + item.setControl(createFilteredComparePage(folder)); + initializeFields(); Dialog.applyDialogFont(folder); return folder; @@ -423,6 +451,99 @@ public class ComparePreferencePage extends PreferencePage implements IWorkbenchP return c; } + + private Control createFilteredComparePage(TabFolder folder) { + Composite pageComponent= new Composite(folder, SWT.NULL); + GridLayout layout= new GridLayout(); + layout.numColumns = 2; + pageComponent.setLayout(layout); + GridData data = new GridData(); + data.verticalAlignment = GridData.FILL; + data.horizontalAlignment = GridData.FILL; + pageComponent.setLayoutData(data); + + // layout the ignore table & its buttons + Label ignoreLabel = new Label(pageComponent, SWT.LEFT); + ignoreLabel.setText(Utilities.getString("ComparePreferencePage.filteredCompareTab.text")); + data = new GridData(); + data.horizontalAlignment = GridData.FILL; + data.horizontalSpan = 2; + ignoreLabel.setLayoutData(data); + + ignoreTable = new Table(pageComponent, SWT.MULTI | SWT.BORDER); + data = new GridData(GridData.FILL_BOTH); + data.heightHint = ignoreTable.getItemHeight() * 7; + ignoreTable.setLayoutData(data); + + Composite groupComponent = new Composite(pageComponent, SWT.NULL); + GridLayout groupLayout = new GridLayout(); + groupLayout.marginWidth = 0; + groupLayout.marginHeight = 0; + groupComponent.setLayout(groupLayout); + data = new GridData(); + data.verticalAlignment = GridData.FILL; + data.horizontalAlignment = GridData.FILL; + groupComponent.setLayoutData(data); + + Button addIgnoreButton = new Button(groupComponent, SWT.PUSH); + addIgnoreButton.setText(Utilities.getString("ComparePreferencePage.filteredCompareTab.addExpression")); + addIgnoreButton.setLayoutData(data); + setButtonLayoutData(addIgnoreButton); + + final Button removeIgnoreButton = new Button(groupComponent, SWT.PUSH); + removeIgnoreButton.setText(Utilities.getString("ComparePreferencePage.filteredCompareTab.removeExpression")); + setButtonLayoutData(removeIgnoreButton); + + // the listeners + ignoreTable.addListener(SWT.Selection, new Listener() { + public void handleEvent(Event event) { + if (ignoreTable.getSelectionCount() > 0) { + removeIgnoreButton.setEnabled(true); + } else { + removeIgnoreButton.setEnabled(false); + } + } + }); + addIgnoreButton.addListener(SWT.Selection, new Listener() { + public void handleEvent(Event event) { + InputDialog dialog = new InputDialog( + getShell(), + Utilities.getString("ComparePreferencePage.filteredCompareTab.addExpression.dialog.title"), + Utilities.getString("ComparePreferencePage.filteredCompareTab.addExpression.dialog.message"), + Utilities.getString("ComparePreferencePage.filteredCompareTab.addExpression.dialog.initialValue"), + new RegexpInputValidator()); + if (dialog.open() == Window.OK) { + String value = dialog.getValue(); + addIgnoreRegexp(value); + } + } + }); + removeIgnoreButton.addListener(SWT.Selection, new Listener() { + public void handleEvent(Event event) { + int[] selection = ignoreTable.getSelectionIndices(); + ignoreTable.remove(selection); + } + }); + + removeIgnoreButton.setEnabled(false); + return pageComponent; + } + + private void addIgnoreRegexp(String value) { + // Check if the item already exists + TableItem[] items = ignoreTable.getItems(); + for (int i = 0; i < items.length; i++) { + if (items[i].getText().equals(value)) { + MessageDialog.openWarning( + getShell(), + Utilities.getString("ComparePreferencePage.filteredCompareTab.addExpression.dialog.valueAlreadyExists.title"), + Utilities.getString("ComparePreferencePage.filteredCompareTab.addExpression.dialog.valueAlreadyExists.message")); + return; + } + } + TableItem item = new TableItem(ignoreTable, SWT.NONE); + item.setText(value); + } private void initializeFields() { @@ -441,7 +562,18 @@ public class ComparePreferencePage extends PreferencePage implements IWorkbenchP removedLinesRegex.setText(fOverlayStore.getString(REMOVED_LINES_REGEX)); editor.load(); + + fillIgnoreTable(); } + + private void fillIgnoreTable() { + ignoreTable.removeAll(); + String[] ignoresPreference = getIgnoreRegexpPreference(); + for (int i = 0; i < ignoresPreference.length; i++) { + TableItem item = new TableItem(ignoreTable, SWT.NULL); + item.setText(ignoresPreference[i]); + } + } // overlay stuff @@ -486,4 +618,36 @@ public class ComparePreferencePage extends PreferencePage implements IWorkbenchP } return buffer.toString(); } + + /* + * stores a list of ignore patterns. + */ + public void storeIgnoreRegexpPreferences(String[] elements) { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < elements.length; i++) { + buffer.append(elements[i]); + buffer.append(IGNORES_REGEXP_DELIMITER); + } + fOverlayStore.setValue(IGNORES_REGEXP, buffer.toString()); + } + + /* + * loads the list of ignore patterns. + */ + private String[] getIgnoreRegexpPreference() { + return convertListOfIgnoreRegexp(fOverlayStore.getString(IGNORES_REGEXP)); + } + + /* + * converts the list of ignore regexp to and from values in preference store. + */ + public static String[] convertListOfIgnoreRegexp(String preferenceValue) { + StringTokenizer tokenizer = new StringTokenizer(preferenceValue, IGNORES_REGEXP_DELIMITER); + int tokenCount = tokenizer.countTokens(); + String[] elements = new String[tokenCount]; + for (int i = 0; i < tokenCount; i++) { + elements[i] = tokenizer.nextToken(); + } + return elements; + } } diff --git org.eclipse.compare/src/org/eclipse/compare/internal/RegexpInputValidator.java org.eclipse.compare/src/org/eclipse/compare/internal/RegexpInputValidator.java new file mode 100644 index 0000000..224d713 --- /dev/null +++ org.eclipse.compare/src/org/eclipse/compare/internal/RegexpInputValidator.java @@ -0,0 +1,19 @@ +package org.eclipse.compare.internal; + +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +import org.eclipse.jface.dialogs.IInputValidator; + +public class RegexpInputValidator implements IInputValidator { + + public String isValid(String newText) { + try { + Pattern.compile(newText); + } catch (PatternSyntaxException exception) { + return "'" + newText + "' is not a valid Regexp!"; + } + return null; + } + +} diff --git org.eclipse.compare/src/org/eclipse/compare/internal/ResourceCompareInput.java org.eclipse.compare/src/org/eclipse/compare/internal/ResourceCompareInput.java index 4c01f86..420c01f 100644 --- org.eclipse.compare/src/org/eclipse/compare/internal/ResourceCompareInput.java +++ org.eclipse.compare/src/org/eclipse/compare/internal/ResourceCompareInput.java @@ -23,6 +23,7 @@ import org.eclipse.compare.ZipFileStructureCreator; import org.eclipse.compare.structuremergeviewer.DiffNode; import org.eclipse.compare.structuremergeviewer.DiffTreeViewer; import org.eclipse.compare.structuremergeviewer.Differencer; +import org.eclipse.compare.structuremergeviewer.DifferencerFiltered; import org.eclipse.compare.structuremergeviewer.IDiffContainer; import org.eclipse.compare.structuremergeviewer.IDiffElement; import org.eclipse.compare.structuremergeviewer.IStructureComparator; @@ -403,11 +404,22 @@ class ResourceCompareInput extends CompareEditorInput { } setTitle(title); - Differencer d= new Differencer() { - protected Object visit(Object parent, int description, Object ancestor, Object left, Object right) { - return new MyDiffNode((IDiffContainer) parent, description, (ITypedElement)ancestor, (ITypedElement)left, (ITypedElement)right); - } - }; + Boolean isFiltered = (Boolean) getCompareConfiguration().getProperty("filtered"); + + Differencer d = null; + if (isFiltered != null && isFiltered.booleanValue()) { + d = new DifferencerFiltered() { + protected Object visit(Object parent, int description, Object ancestor, Object left, Object right) { + return new MyDiffNode((IDiffContainer) parent, description, (ITypedElement)ancestor, (ITypedElement)left, (ITypedElement)right); + } + }; + } else { + d= new Differencer() { + protected Object visit(Object parent, int description, Object ancestor, Object left, Object right) { + return new MyDiffNode((IDiffContainer) parent, description, (ITypedElement)ancestor, (ITypedElement)left, (ITypedElement)right); + } + }; + } fRoot= d.findDifferences(fThreeWay, pm, null, fAncestor, fLeft, fRight); return fRoot; diff --git org.eclipse.compare/src/org/eclipse/compare/structuremergeviewer/DifferencerFiltered.java org.eclipse.compare/src/org/eclipse/compare/structuremergeviewer/DifferencerFiltered.java new file mode 100644 index 0000000..894fad5 --- /dev/null +++ org.eclipse.compare/src/org/eclipse/compare/structuremergeviewer/DifferencerFiltered.java @@ -0,0 +1,223 @@ +package org.eclipse.compare.structuremergeviewer; + +import java.io.BufferedReader; +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.compare.ResourceNode; +import org.eclipse.compare.internal.ComparePreferencePage; +import org.eclipse.compare.internal.CompareUIPlugin; +import org.eclipse.compare.internal.patch.Utilities; +import org.eclipse.compare.rangedifferencer.IRangeComparator; +import org.eclipse.compare.rangedifferencer.RangeDifference; +import org.eclipse.compare.rangedifferencer.RangeDifferencer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.Platform; + +/** + * A Differencer who will ignore changed lines which matches at least one of the stored pattern(s). + */ +public class DifferencerFiltered extends Differencer { + + /** + * This implementation of IRangeComparator breaks an input stream into lines. + * @see org.eclipse.compare.internal.merge.LineComparator + */ + class LineComparator implements IRangeComparator { + + private String[] fLines; + + public LineComparator(InputStream is, String encoding) throws IOException { + + BufferedReader br = new BufferedReader(new InputStreamReader(is, encoding)); + String line; + ArrayList ar = new ArrayList(); + while ((line = br.readLine()) != null) { + ar.add(line); + } + // It is the responsibility of the caller to close the stream + fLines = (String[]) ar.toArray(new String[ar.size()]); + } + + String getLine(int ix) { + return fLines[ix]; + } + + /* (non-Javadoc) + * @see org.eclipse.compare.rangedifferencer.IRangeComparator#getRangeCount() + */ + public int getRangeCount() { + return fLines.length; + } + + /* (non-Javadoc) + * @see org.eclipse.compare.rangedifferencer.IRangeComparator#rangesEqual(int, org.eclipse.compare.rangedifferencer.IRangeComparator, int) + */ + public boolean rangesEqual(int thisIndex, IRangeComparator other, + int otherIndex) { + String s1 = fLines[thisIndex]; + String s2 = ((LineComparator) other).fLines[otherIndex]; + return s1.equals(s2); + } + + /* (non-Javadoc) + * @see org.eclipse.compare.rangedifferencer.IRangeComparator#skipRangeComparison(int, int, org.eclipse.compare.rangedifferencer.IRangeComparator) + */ + public boolean skipRangeComparison(int length, int maxLength, IRangeComparator other) { + return false; + } + } + + protected boolean contentsEqual(Object input1, Object input2) { + if (input1 instanceof ResourceNode && input2 instanceof ResourceNode) { + ResourceNode resLeft = (ResourceNode) input1; + ResourceNode resRight = (ResourceNode) input2; + if (resLeft.getResource() instanceof IFile && resRight.getResource() instanceof IFile) { + IFile left = (IFile) resLeft.getResource(); + IFile right = (IFile) resRight.getResource(); + + InputStream leftInput = null; + InputStream rightInput = null; + try { + leftInput = left.getContents(); + rightInput = right.getContents(); + + LineComparator leftLineComparator = new LineComparator(leftInput, Utilities.getCharset(resLeft)); + LineComparator rightLineComparator = new LineComparator(rightInput, Utilities.getCharset(resRight)); + + RangeDifference[] differences = RangeDifferencer.findDifferences(leftLineComparator, rightLineComparator); + + if (differences.length == 0) { + // no diffs -> contents are equal + return true; + } + + for (int d = 0; d < differences.length; d++) { + if (! isDiffIgnorable(left, right, differences[d])) { + // we found a diff which isn't on our ignore list. +// System.out.println("I can't ignore " + left.getName() + " because of diff " + df); + return false; + } + } + // we found diffs, but all these diffs are on our ignore list. +// System.out.println("All lines with diff in file matches the ignores: " + left.getName()); + return true; + + } catch (Exception e) { + e.printStackTrace(); + return false; + } finally { + closeQuietly(leftInput); + closeQuietly(rightInput); + } + } + } + // not a resourceNode ... go the normal way... + return super.contentsEqual(input1, input2); + } + + private boolean isDiffIgnorable(IFile left, IFile right, RangeDifference diff) { + + try { + + List linesLeft = readLines(left); + List linesRight = readLines(right); + + // left + for (int line = diff.leftStart(); line < diff.leftEnd(); line++) { + String candidateLeft = (String) linesLeft.get(line); + if (matches(candidateLeft)) { + // ignore line in left + continue; + } else { + // found a diff which we can not ignore. + return false; + } + } + + // right + for (int line = diff.rightStart(); line < diff.rightEnd(); line++) { + String candidateRight = (String) linesRight.get(line); + if (matches(candidateRight)) { + // ignore line in right + continue; + } else { + // found a diff which we can not ignore. + return false; + } + } + + } catch (Exception e) { + e.printStackTrace(); + return false; + } + // diffs we found should be ignored. + return true; + } + + private boolean matches(String candidate) { + String regexp = getIgnoresAsRegexp(); + if (candidate != null && candidate.matches(regexp) ) { +// System.out.println("!BINGO! Ignoring because of line: '" + candidate + "'"); + return true; + } + return false; + } + + private String getIgnoresAsRegexp() { + String ignoresFromStore = Platform.getPreferencesService() + .getString(CompareUIPlugin.PLUGIN_ID, ComparePreferencePage.IGNORES_REGEXP, "", null); + + String[] ignores = ComparePreferencePage.convertListOfIgnoreRegexp(ignoresFromStore); + + StringBuilder regexp = new StringBuilder(); + for (int i = 0; i < ignores.length; i++) { + regexp.append("("); + regexp.append(ignores[i]); + regexp.append(")|"); + } + if (regexp.length() > 0) { + // cut off last '|' + regexp.setLength(regexp.length() - 1); + } + String result = regexp.toString(); +// System.out.println(result); + return result; + + } + + + /** + * Get the contents of an InputStream as a list of Strings, + * one entry per line, using the specified character encoding. + */ + public static List readLines(IFile file) throws IOException, CoreException { + String charset = Utilities.getCharset(file); + InputStream input = file.getContents(); + InputStreamReader reader = new InputStreamReader(input, charset); + BufferedReader bufferedReader = new BufferedReader(reader); + List list = new ArrayList(); + String line = bufferedReader.readLine(); + while (line != null) { + list.add(line); + line = bufferedReader.readLine(); + } + return list; + } + + public void closeQuietly(Closeable closeable) { + if (closeable != null) { + try { + closeable.close(); + } catch (IOException ex) { + // ignore + } + } + } + +}