This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 86595 - Undo functionality is broken for actions performed on existing elements
Summary: Undo functionality is broken for actions performed on existing elements
Status: VERIFIED FIXED
Alias: None
Product: soa
Classification: Unclassified
Component: BPEL (show other bugs)
Version: 5.x
Hardware: All All
: P2 blocker (vote)
Assignee: Denis Anisimov
URL:
Keywords: REGRESSION
Depends on:
Blocks:
 
Reported: 2006-10-05 15:31 UTC by Mikhail Kondratyev
Modified: 2006-10-12 16:10 UTC (History)
1 user (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mikhail Kondratyev 2006-10-05 15:31:14 UTC
Steps to reproduce:
 - create a Sync project
 - drag Reply activity to the first position in the process
The undo action will not be enabled. Undo will be enabled only if you drag a new
element from palette, but still, no actions preceding creation of the new
activity  can't be rolled back.
Comment 1 Mikhail Kondratyev 2006-10-05 15:35:25 UTC
Workaround: 
 - close all BPEL editor tabs
 - create new Sync project
 - select BPEL process on diagram
 - select Sequence on diagram
 - click on Reply on diagram
 - now drag the Reply somewhere, the Undo action will be enabled
Comment 2 Denis Anisimov 2006-10-05 16:16:38 UTC
Strange issue.
It seems some problem in NB.
Bug is reproduced only when project is just opened and focus is not changed.
Undo/Redo manager is added to diagram when it is actiavated, but it doesn't appear
as active.
Comment 3 Denis Anisimov 2006-10-05 16:25:18 UTC
I believe the problem is inside code:
BpelModelLogicalBeanTree class 

    public void propertyChange(PropertyChangeEvent evt) {
        String propertyName = evt.getPropertyName();
        TopComponent navigatorTopComponent 
                = BpelNavigatorController.getNavigatorTC();
        
        if (propertyName.equals(TopComponent.Registry.PROP_ACTIVATED)) {
            if (TopComponent.getRegistry().getActivated() ==
navigatorTopComponent) {
                removeUndoManager();
                addUndoManager();
            }
            else {
                removeUndoManager();
            }
        }

That was added for fixing bug with undo/redo when one switches from navigator to
source.

This code is called after method componentActivated() is called in TopComponent.
So it removes previously added undo/redo manager from OM.
I don't understand why it works sometimes. It should never works.

Need to think how it should be corrected.
Comment 4 Denis Anisimov 2006-10-05 21:51:24 UTC
Fixed in _dev branch.

The reasons as I already said in bad fix for other bug with undo/redo.
The problem is in order that NB uses for calling componentActivated/Deactivated
methods and firing of PropertyChange event about activated TopComponent.
We cannot override TopComponent componentActivated()/Deactivated() methods for
Navigator TopComponent , so we need to use listener attached to 
TopComponentRegistry.
But in this case when we get event about activated component and this component
is not Navigator component then we should not delete Undo/Redo manager from OM
blindly. Because NB before this could called method componentActivated() for
Digram.  This is exactly whats happened.

I have modify all framework for adding/deleting Undo/Redo manager with 
remembering identifier of Multiview that perform addition or deletion.
Each multiview should be able delete Undo/Redo manager ONLY if it was added 
by this component ( last addition ).
Comment 5 Denis Anisimov 2006-10-06 11:14:36 UTC
File Changes:

Directory: /enterprise/bpel/editors/src/org/netbeans/modules/bpel/navigator/
============================================================================

File [changed]: BpelModelLogicalBeanTree.java
Url:
http://enterprise.netbeans.org/source/browse/enterprise/bpel/editors/src/org/netbeans/modules/bpel/navigator/BpelModelLogicalBeanTree.java?r1=1.1.2.12&r2=1.1.2.13
Delta lines:  +7 -8
-------------------
--- BpelModelLogicalBeanTree.java	4 Oct 2006 11:30:53 -0000	1.1.2.12
+++ BpelModelLogicalBeanTree.java	5 Oct 2006 20:43:49 -0000	1.1.2.13
@@ -28,8 +28,8 @@
 import javax.swing.tree.TreeSelectionModel;
 
 import org.netbeans.modules.bpel.core.BPELDataEditorSupport;
+import org.netbeans.modules.bpel.core.multiview.spi.MultiviewId;
 import org.netbeans.modules.bpel.design.nodes.NodeType;
-import org.netbeans.modules.bpel.editors.multiview.UndoRedoManagerUtils;
 import org.netbeans.modules.bpel.model.api.BpelEntity;
 import org.netbeans.modules.bpel.model.api.BpelModel;
 import org.netbeans.modules.bpel.model.api.events.ArrayUpdateEvent;
@@ -186,7 +186,6 @@
         
         if (propertyName.equals(TopComponent.Registry.PROP_ACTIVATED)) {
             if (TopComponent.getRegistry().getActivated() ==
navigatorTopComponent) {
-                removeUndoManager();
                 addUndoManager();
             }
             else {
@@ -297,9 +296,9 @@
      * edit listener, so it receives the edits onto the queue.
      */
     private void addUndoManager() {
-        UndoRedoManagerUtils.addUndoManager( myBpelModel , 
-                (BPELDataEditorSupport)myContextLookup.
-                lookup( BPELDataEditorSupport.class  ));
+        ((BPELDataEditorSupport) myContextLookup
+                .lookup(BPELDataEditorSupport.class))
+                .addUndoManager(MultiviewId.NAVIGATOR);
     }
     
     /**
@@ -307,9 +306,9 @@
      * schema model, to stop receiving undoable edits.
      */
     private void removeUndoManager() {
-        UndoRedoManagerUtils.removeUndoManager( myBpelModel , 
-                (BPELDataEditorSupport)myContextLookup.
-                lookup( BPELDataEditorSupport.class  ));
+        ((BPELDataEditorSupport) myContextLookup
+                .lookup(BPELDataEditorSupport.class))
+                .removeUndoManager(MultiviewId.NAVIGATOR);
 
     }
 }

Directory: /enterprise/bpel/core/src/org/netbeans/modules/bpel/core/multiview/spi/
==================================================================================

File [added]: MultiviewId.java
Url:
http://enterprise.netbeans.org/source/browse/enterprise/bpel/core/src/org/netbeans/modules/bpel/core/multiview/spi/MultiviewId.java?rev=1.1.2.1&content-type=text/vnd.viewcvs-markup
Added lines: 17
---------------
/**
 * 
 */
package org.netbeans.modules.bpel.core.multiview.spi;


/**
 * This is enumeration for identifying UI view that needs to 
 * operate with BPEL OM.
 * @author ads
 *
 */
public enum MultiviewId {

    ORCH_DESIGNER,      // Diagram View
    NAVIGATOR           // Navigator View
}

Directory: /enterprise/bpel/core/src/org/netbeans/modules/bpel/core/
====================================================================

File [changed]: BPELDataEditorSupport.java
Url:
http://enterprise.netbeans.org/source/browse/enterprise/bpel/core/src/org/netbeans/modules/bpel/core/BPELDataEditorSupport.java?r1=1.1.2.22&r2=1.1.2.23
Delta lines:  +84 -0
--------------------
--- BPELDataEditorSupport.java	25 Sep 2006 12:39:21 -0000	1.1.2.22
+++ BPELDataEditorSupport.java	5 Oct 2006 20:43:50 -0000	1.1.2.23
@@ -34,6 +34,7 @@
 import org.netbeans.core.spi.multiview.CloseOperationState;
 import org.netbeans.modules.bpel.core.multiview.BPELSourceMultiViewElementDesc;
 import org.netbeans.modules.bpel.core.multiview.BpelMultiViewSupport;
+import org.netbeans.modules.bpel.core.multiview.spi.MultiviewId;
 import org.netbeans.modules.bpel.core.validation.BPELValidationController;
 import org.netbeans.modules.bpel.core.validation.SelectBpelElement;
 import org.netbeans.modules.bpel.editors.canvas.Canvas;
@@ -304,6 +305,65 @@
         return true;
     }
     
+    
+    /**
+     * Adds the undo/redo manager to the bpel model as an undoable
+     * edit listener, so it receives the edits onto the queue.
+     * 
+     * I suppose that those methods are called always in one thread.
+     * Currently this is true. They are always called from AWT thread.
+     * 
+     * @param id Id of mutiview element for which we add undo/redo manager.
+     */
+    public void addUndoManager( MultiviewId id ) 
+    {
+        BpelModel model = getBpelModel();
+        if (model != null) {
+            QuietUndoManager undo = getUndoManager();
+            // Ensure the listener is not added twice.
+            removeUndoManager();
+            model.addUndoableEditListener(undo);
+            // Ensure the model is sync'd when undo/redo is invoked,
+            // otherwise the edits are added to the queue and eventually
+            // cause exceptions.
+            undo.setModel(model);
+            
+            // keep id of multiview 
+            setId(id);
+        }
+    }
+
+    /**
+     * Removes the undo/redo manager undoable edit listener from the
+     * bpel model, to stop receiving undoable edits.
+     * 
+     * I suppose that those methods are called always in one thread.
+     * Currently this is true. They are always called from AWT thread.
+     * 
+     * @param id Id of mutiview element for which we remove undo/redo manager.
+     */
+    public void removeUndoManager( MultiviewId id )
+    {
+        /*
+         *  we prevent deleting undo/redo manager if it was added by multiview
+         *  with different id. 
+         */ 
+        if ( id!= getId()) {
+            return;
+        }
+        
+        BpelModel model = getBpelModel();
+        if (model != null) {
+            QuietUndoManager undo = getUndoManager();
+            model.removeUndoableEditListener(undo);
+            // Must unset the model when leaving model view.
+            undo.setModel(null);
+            
+            // remove id
+            setId( null );
+        }
+    }
+    
     protected CloneableEditorSupport.Pane createPane() {
         TopComponent multiview = BpelMultiViewSupport
                 .createMultiView((BPELDataObject) getDataObject());
@@ -378,6 +438,28 @@
     ValidationAnnotation annotation = new ValidationAnnotation();
     
     
+    /**
+     * Removes the undo/redo manager undoable edit listener from the
+     * bpel model, to stop receiving undoable edits.
+     */
+    private void removeUndoManager( ) {
+        BpelModel model = getBpelModel();
+        if (model != null) {
+            QuietUndoManager undo = getUndoManager();
+            model.removeUndoableEditListener(undo);
+            // Must unset the model when leaving model view.
+            undo.setModel(null);
+        }
+    }
+    
+    private void setId( MultiviewId id) {
+        myMultiviewId = id;
+    }
+    
+    private MultiviewId getId() {
+        return myMultiviewId;
+    }
+    
     private List<TopComponent> getAssociatedTopComponents() {
         // Create a list of TopComponents associated with the
         // editor's schema data object, starting with the the
@@ -492,5 +574,7 @@
     
     /** Used for managing the prepareTask listener. */
     private transient Task prepareTask;
+    
+    private transient MultiviewId myMultiviewId;
     
 }

Directory: /enterprise/bpel/editors/src/org/netbeans/modules/bpel/editors/multiview/
====================================================================================

File [removed]: UndoRedoManagerUtils.java

File [changed]: DesignerMultiViewElement.java
Url:
http://enterprise.netbeans.org/source/browse/enterprise/bpel/editors/src/org/netbeans/modules/bpel/editors/multiview/DesignerMultiViewElement.java?r1=1.1.2.29&r2=1.1.2.30
Delta lines:  +33 -38
---------------------
--- DesignerMultiViewElement.java	3 Oct 2006 08:35:58 -0000	1.1.2.29
+++ DesignerMultiViewElement.java	5 Oct 2006 20:43:51 -0000	1.1.2.30
@@ -24,26 +24,11 @@
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
 import java.awt.event.ActionEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
 import java.io.IOException;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
-import javax.swing.Box;
-import javax.swing.JScrollPane;
-import javax.swing.JToggleButton;
-import org.netbeans.core.spi.multiview.CloseOperationState;
-import org.netbeans.core.spi.multiview.MultiViewElement;
-import org.netbeans.core.spi.multiview.MultiViewElementCallback;
-import org.netbeans.modules.bpel.core.BPELDataEditorSupport;
-import org.netbeans.modules.bpel.core.BPELDataObject;
-import org.netbeans.modules.bpel.design.DesignView;
-import org.netbeans.modules.bpel.design.PartnerLinkFilterButton;
-import org.netbeans.modules.bpel.design.SequenceFilterButton;
-import org.netbeans.modules.bpel.design.ViewFiltersSwitcher;
-import org.openide.awt.UndoRedo;
-import org.openide.windows.TopComponent;
-
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
 import java.io.Serializable;
 import java.util.Arrays;
 import java.util.Enumeration;
@@ -51,31 +36,35 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import javax.swing.JButton;
 
+import javax.swing.Box;
+import javax.swing.JButton;
 import javax.swing.JComponent;
+import javax.swing.JScrollPane;
 import javax.swing.JSlider;
+import javax.swing.JToggleButton;
 import javax.swing.JToolBar;
 import javax.swing.text.JTextComponent;
+
 import org.netbeans.core.api.multiview.MultiViewHandler;
 import org.netbeans.core.api.multiview.MultiViewPerspective;
 import org.netbeans.core.api.multiview.MultiViews;
-
+import org.netbeans.core.spi.multiview.CloseOperationState;
+import org.netbeans.core.spi.multiview.MultiViewElement;
+import org.netbeans.core.spi.multiview.MultiViewElementCallback;
 import org.netbeans.core.spi.multiview.MultiViewFactory;
+import org.netbeans.modules.bpel.core.BPELDataEditorSupport;
+import org.netbeans.modules.bpel.core.BPELDataObject;
+import org.netbeans.modules.bpel.core.multiview.spi.MultiviewId;
 import org.netbeans.modules.bpel.core.validation.BPELValidationController;
 import org.netbeans.modules.bpel.core.validation.SelectBpelElement;
+import org.netbeans.modules.bpel.design.DesignView;
+import org.netbeans.modules.bpel.design.PartnerLinkFilterButton;
+import org.netbeans.modules.bpel.design.SequenceFilterButton;
 import org.netbeans.modules.bpel.design.ZoomPanel;
 import org.netbeans.modules.bpel.design.nodes.NodeType;
 import org.netbeans.modules.bpel.model.api.Assign;
 import org.netbeans.modules.bpel.model.api.BpelEntity;
-import org.openide.util.Lookup;
-import org.openide.util.WeakListeners;
-import org.openide.util.lookup.Lookups;
-import org.openide.util.lookup.ProxyLookup;
-import org.openide.nodes.Node;
-import org.openide.util.lookup.AbstractLookup;
-import org.openide.util.lookup.InstanceContent;
-import org.openide.windows.CloneableTopComponent;
 import org.netbeans.modules.bpel.model.api.BpelModel;
 import org.netbeans.modules.bpel.model.api.Catch;
 import org.netbeans.modules.bpel.model.api.CatchAll;
@@ -106,33 +95,39 @@
 import org.netbeans.modules.bpel.model.api.PartnerLink;
 import org.netbeans.modules.bpel.model.api.PatternedCorrelation;
 import org.netbeans.modules.bpel.model.api.Pick;
+import org.netbeans.modules.bpel.model.api.Process;
 import org.netbeans.modules.bpel.model.api.Receive;
 import org.netbeans.modules.bpel.model.api.RepeatUntil;
 import org.netbeans.modules.bpel.model.api.Reply;
 import org.netbeans.modules.bpel.model.api.Scope;
 import org.netbeans.modules.bpel.model.api.Sequence;
-import org.netbeans.modules.bpel.model.api.Throw;
-import org.netbeans.modules.bpel.model.api.Wait;
-import org.netbeans.modules.bpel.model.api.While;
-import org.netbeans.modules.bpel.model.api.Process;
 import org.netbeans.modules.bpel.model.api.TerminationHandler;
+import org.netbeans.modules.bpel.model.api.Throw;
 import org.netbeans.modules.bpel.model.api.ToPart;
 import org.netbeans.modules.bpel.model.api.Variable;
 import org.netbeans.modules.bpel.model.api.VariableContainer;
 import org.netbeans.modules.bpel.model.api.VariableDeclarationScope;
-import org.netbeans.modules.bpel.model.api.events.ChangeEventListener;
+import org.netbeans.modules.bpel.model.api.Wait;
+import org.netbeans.modules.bpel.model.api.While;
 import org.netbeans.modules.bpel.model.api.events.ChangeEventListenerAdapter;
 import org.netbeans.modules.bpel.model.api.events.PropertyUpdateEvent;
 import org.netbeans.modules.bpel.palette.SoaPaletteFactory;
 import org.netbeans.modules.bpel.properties.PropertyNodeFactory;
 import org.netbeans.modules.xml.validation.ValidateAction;
-import org.netbeans.modules.xml.validation.ValidateAction.RunAction;
 import org.netbeans.modules.xml.xam.Model;
 import org.netbeans.modules.xml.xam.Model.State;
 import org.netbeans.modules.xml.xam.spi.Validator.ResultItem;
-import org.netbeans.modules.xml.xam.ui.undo.QuietUndoManager;
+import org.openide.awt.UndoRedo;
+import org.openide.nodes.Node;
+import org.openide.util.Lookup;
 import org.openide.util.RequestProcessor;
+import org.openide.util.lookup.AbstractLookup;
+import org.openide.util.lookup.InstanceContent;
+import org.openide.util.lookup.Lookups;
+import org.openide.util.lookup.ProxyLookup;
+import org.openide.windows.CloneableTopComponent;
 import org.openide.windows.Mode;
+import org.openide.windows.TopComponent;
 import org.openide.windows.TopComponentGroup;
 import org.openide.windows.WindowManager;
 
@@ -565,8 +560,8 @@
      * edit listener, so it receives the edits onto the queue.
      */
     private void addUndoManager() {
-        UndoRedoManagerUtils.addUndoManager( getBpelModel() , 
-                myDataObject.getEditorSupport());
+        myDataObject.getEditorSupport().addUndoManager( 
+                MultiviewId.ORCH_DESIGNER );
     }
 
     /**
@@ -574,8 +569,8 @@
      * bpel model, to stop receiving undoable edits.
      */
     private void removeUndoManager() {
-        UndoRedoManagerUtils.removeUndoManager( getBpelModel() , 
-                myDataObject.getEditorSupport());
+        myDataObject.getEditorSupport().removeUndoManager( 
+                MultiviewId.ORCH_DESIGNER );
     }
     
     private BpelModel getBpelModel() {

Comment 6 Michael Frisino 2006-10-06 12:31:36 UTC
code looks ok. Please commit to releae55 so we get maximum test time for
regressions. 
Comment 7 Denis Anisimov 2006-10-06 13:40:27 UTC
Fixed in both branches.
Comment 8 Mikhail Kondratyev 2006-10-12 16:10:32 UTC
Verified in build m22