Re: Undo/redo implementation & JMI compliance

Brian Smith <[email protected]>
Newsgroups gmane.comp.java.netbeans.modules.mdr.devel
Organization CollabNet Hosting
Message-ID <[email protected]>
Constantine and everybody,

I think that even without undo/redo, having the diagram item contain a 
reference to the model element will cause problems. In general, it seems 
like a bad idea to create long-lived references to JMI instance objects 
because the JMI implementation is free to create multiple instance 
objects to represent a single modeled element. For example, if you have 
code:

boolean isContainerIdentical(ModelElement me) {
     return me.getContainer() == me.getContainer();
}

This code could very well return false since the JMI implementation 
could create a new instance object each time me.getContainer() is 
called. So, potentially you could have a some diagram elements that 
reference the "same" model element, but referencing different instance 
objects.

Also, I would expect that MDR and other persistent JMI repositories 
would make good use of weak referencing to provide memory-efficient 
transparent persistence. But, if your diagram elements contain strong 
references to the model elements, this will be (partially) defeated.

So, in my view, no long-lived objects should contain references to JMI 
instance objects. Instead, everything needs to be done by a map (mof-id 
-> application-data). And, if you have this designed into your whole 
application, it seems a simple matter to add a little indirection to 
keep track of which objects have been "recreated" with a new ID, like 
this (untested):

class ObjectIdentityMap {
     synchronized RefObject getObject(String mofId) {
         Object replacement = replaced.get(mofId);
         if (replacement == null)
             return repository.getObjectByMofId(mofId);
          else
             return repository.getObjectByMofId((String) replacement);
     }
     synchronized void replaceIdentity(String oldId, String newId) {
         Object oldReplacement = replaced.get(oldId);
         if (oldReplacement != null)
             replaceObject((String) oldReplacement, new);
         replaced.put(oldId, newId);
     }
         // String oldId -> String newId
     WeakHashMap replaced = new WeakHashMap();
}

Then the diagram objects would keep track only of the MOF ID (and the 
identity map), and the problem you described should go away. But, this 
does require that the JMI implementation provide a method like 
"getObjectByMofId()".

- Brian


Constantine Plotnikov wrote:
> 3. You will likely hit some problems with previous undo/redo records
> referencing removed object. Deleted instances need to be revived
> rather then recreated,  so if previous swing undo contains
> reference to model element, this reference will be valid.
> 
> Consider followng:
> 
> diagramitem.remove(); // non jmi object but it aslo enlist something on 
> swing undo manager
> container.getContents().remove(me);
> ....
> some time later
> ....
> me.refDelete();
> ....
> some time later
> ....
> undo!
> 
> On undoing, you will need to live with fact that diagram
> item undo may have pointer to old object. Also
> container.getContents().remove(me); will have undo
> with removed element.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.