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.