### Eclipse Workspace Patch 1.0
#P org.eclipse.jdt.ui
Index: ui/org/eclipse/jdt/internal/ui/compare/JavaStructureDiffViewer.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/compare/JavaStructureDiffViewer.java,v
retrieving revision 1.16
diff -u -r1.16 JavaStructureDiffViewer.java
--- ui/org/eclipse/jdt/internal/ui/compare/JavaStructureDiffViewer.java 16 Dec 2008 10:20:24 -0000 1.16
+++ ui/org/eclipse/jdt/internal/ui/compare/JavaStructureDiffViewer.java 17 Apr 2009 13:05:21 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2009 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,12 @@
*******************************************************************************/
package org.eclipse.jdt.internal.ui.compare;
+import java.util.HashSet;
import java.util.Map;
import java.util.ResourceBundle;
+import java.util.Set;
+import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.ToolBar;
@@ -29,6 +32,7 @@
import org.eclipse.compare.CompareConfiguration;
import org.eclipse.compare.CompareViewerPane;
+import org.eclipse.compare.IContentChangeNotifier;
import org.eclipse.compare.IResourceProvider;
import org.eclipse.compare.ITypedElement;
import org.eclipse.compare.structuremergeviewer.DiffNode;
@@ -37,12 +41,18 @@
import org.eclipse.compare.structuremergeviewer.IDiffContainer;
import org.eclipse.compare.structuremergeviewer.StructureDiffViewer;
+import org.eclipse.jdt.core.ElementChangedEvent;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IElementChangedListener;
import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaElementDelta;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
+
// XXX: StructuredDiffViewer should allow subclassing, see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=258907
-class JavaStructureDiffViewer extends StructureDiffViewer {
+class JavaStructureDiffViewer extends StructureDiffViewer implements IElementChangedListener {
/**
* Toggles a boolean property of an CompareConfiguration
.
@@ -91,6 +101,7 @@
super(parent, configuration);
fStructureCreator= new JavaStructureCreator();
setStructureCreator(fStructureCreator);
+ JavaCore.addElementChangedListener(this);
}
/**
@@ -150,15 +161,29 @@
}
private Map getCompilerOptions(ITypedElement input) {
- if (input instanceof IResourceProvider) {
- IResource resource= ((IResourceProvider) input).getResource();
+ IJavaElement element= findJavaElement(input);
+ if (element != null) {
+ IJavaProject javaProject= element.getJavaProject();
+ if (javaProject != null)
+ return javaProject.getOptions(true);
+ }
+ return null;
+ }
+
+ /*
+ * @see org.eclipse.compare.structuremergeviewer.StructureDiffViewer#handleDispose(org.eclipse.swt.events.DisposeEvent)
+ * @since 3.5
+ */
+ protected void handleDispose(DisposeEvent event) {
+ JavaCore.removeElementChangedListener(this);
+ super.handleDispose(event);
+ }
+
+ private IJavaElement findJavaElement(ITypedElement element) {
+ if (element instanceof IResourceProvider) {
+ IResource resource= ((IResourceProvider)element).getResource();
if (resource != null) {
- IJavaElement element= JavaCore.create(resource);
- if (element != null) {
- IJavaProject javaProject= element.getJavaProject();
- if (javaProject != null)
- return javaProject.getOptions(true);
- }
+ return JavaCore.create(resource);
}
}
return null;
@@ -191,9 +216,10 @@
}
/**
- * Tracks property changes of the configuration object.
- * Clients may override to track their own property changes.
- * In this case they must call the inherited method.
+ * Tracks property changes of the configuration object. Clients may override to track their own
+ * property changes. In this case they must call the inherited method.
+ *
+ * @param event the property change event
*/
protected void propertyChange(PropertyChangeEvent event) {
if (event.getProperty().equals(SMART))
@@ -218,4 +244,117 @@
tb.getParent().layout(true);
}
}
-}
+
+ /*
+ * @see org.eclipse.jdt.core.IElementChangedListener#elementChanged(org.eclipse.jdt.core.ElementChangedEvent)
+ * @since 3.5
+ */
+ public void elementChanged(ElementChangedEvent event) {
+ ITypedElement[] elements= findAffectedElement(event);
+ for (int i= 0; i < elements.length; i++) {
+ ITypedElement e= elements[i];
+ if (e == null || !(e instanceof IContentChangeNotifier))
+ continue;
+ contentChanged((IContentChangeNotifier)e);
+ }
+ }
+
+ /**
+ * Tells which elements of the comparison are affected by the change.
+ *
+ * @param event element changed event
+ * @return array of typed elements affected by the event. May return an empty array.
+ * @since 3.5
+ */
+ private ITypedElement[] findAffectedElement(ElementChangedEvent event) {
+ Object input= getInput();
+ if (!(input instanceof ICompareInput))
+ return new ITypedElement[0];
+
+ Set affectedElements= new HashSet();
+ ICompareInput ci= (ICompareInput)input;
+ IJavaElementDelta delta= event.getDelta();
+ addAffectedElement(ci.getAncestor(), delta, affectedElements);
+ addAffectedElement(ci.getLeft(), delta, affectedElements);
+ addAffectedElement(ci.getRight(), delta, affectedElements);
+
+ return (ITypedElement[])affectedElements.toArray(new ITypedElement[affectedElements.size()]);
+ }
+
+ /**
+ * Tests whether the given element is affected by the change and if so, adds it to given set.
+ *
+ * @param element the element to test
+ * @param delta the Java element delta
+ * @param affectedElements the set of affected elements
+ * @since 3.5
+ */
+ private void addAffectedElement(ITypedElement element, IJavaElementDelta delta, Set affectedElements) {
+ IJavaElement javaElement= findJavaElement(element);
+ if (isEditable(javaElement) && findJavaElementDelta(javaElement, delta) != null)
+ affectedElements.add(element);
+ }
+
+ /**
+ * Tells whether the given Java element can be edited.
+ *
+ * @param javaElement the element to test
+ * @return true
if the element can be edited, false
otherwise
+ * @since 3.5
+ */
+ private boolean isEditable(IJavaElement javaElement) {
+ return (javaElement instanceof ICompilationUnit) && JavaModelUtil.isEditable((ICompilationUnit)javaElement);
+ }
+
+ /*
+ * This is a copy of the internal JavaOutlinePage.ElementChangedListener#isPossibleStructuralChange method.
+ * @see org.eclipse.jdt.internal.ui.javaeditor.JavaOutlinePage.ElementChangedListener#isPossibleStructuralChange(IJavaElementDelta)
+ * @since 3.5
+ */
+ private boolean isPossibleStructuralChange(IJavaElementDelta cuDelta) {
+ if (cuDelta.getKind() != IJavaElementDelta.CHANGED) {
+ return true; // add or remove
+ }
+ int flags= cuDelta.getFlags();
+ if ((flags & IJavaElementDelta.F_CHILDREN) != 0) {
+ return true;
+ }
+ return (flags & (IJavaElementDelta.F_CONTENT | IJavaElementDelta.F_FINE_GRAINED)) == IJavaElementDelta.F_CONTENT;
+ }
+
+ /*
+ * This is a copy of the internal JavaOutlinePage.ElementChangedListener#findElement method.
+ * @see org.eclipse.jdt.internal.ui.javaeditor.JavaOutlinePage.ElementChangedListener#findElement(IJavaElement, IJavaElementDelta)
+ * @since 3.5
+ */
+ protected IJavaElementDelta findJavaElementDelta(IJavaElement unit, IJavaElementDelta delta) {
+
+ if (delta == null || unit == null)
+ return null;
+
+ IJavaElement element= delta.getElement();
+
+ if (unit.equals(element)) {
+ if (isPossibleStructuralChange(delta)) {
+ return delta;
+ }
+ return null;
+ }
+
+
+ if (element.getElementType() > IJavaElement.CLASS_FILE)
+ return null;
+
+ IJavaElementDelta[] children= delta.getAffectedChildren();
+ if (children == null || children.length == 0)
+ return null;
+
+ for (int i= 0; i < children.length; i++) {
+ IJavaElementDelta d= findJavaElementDelta(unit, children[i]);
+ if (d != null)
+ return d;
+ }
+
+ return null;
+ }
+}
\ No newline at end of file