blob: 0dd24eadce0095969b73bd7b5208cbe246e0aa8b [file] [log] [blame]
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>Page Title</title>
<link href="../book.css" rel="Stylesheet" type="text/css">
<link href="../code.css" rel="Stylesheet" type="text/css">
</head>
<body>
<h1>Non-EMF Domain Objects</h1>
<p>By default Graphiti supports domain models from the EMF world and offers automated
support for reacting to changes and updating the editor. Since not only EObjects
but simple POJOs can be passed to all relevant framework APIs, it is also possible
to use non-EMF domain objects with Graphiti. This page describes the differences
the user of Graphiti has to deal with when using non-EMF domain models.</p>
<h2>Domain Model Change Notifications</h2>
<p>Of course the framework cannot support automated notification to changes in such
domain models, so the tool builder needs to hook an appropriate listener into the
framework. Here&#39;s the process how to do this:</p>
<ol>
<li>Create an appropriate specific domain listener class. As an example you
can have a look at <span class="inlinecode">DomainModelChangeListener</span>
in the Graphiti framework; this class does this job for EMF models.</li>
<li>Subclass <span class="inlinecode">DiagramEditor</span> and override its
method <span class="inlinecode">registerBOListener</span>. In that method create
an instance of your listener from step 1 and register it.</li>
<li>Create an appropriate notification service class by subclassing
<span class="inlinecode">DefaultNotificationService</span> or implementing its
interface. An instance of this class is used by the framework to get the connection
between domain objects and their graphical representation (method
<span class="inlinecode">calculateLinkedPictogramElements</span>) and triggers
the actual update of the graphical representation in the diagram (method
<span class="inlinecode">updatePictogramElements</span>) using the appropriate
update features. The class <span class="inlinecode">DefaultNotificationService</span>
does the job for EMF models.</li>
<li>In your Diagram Type Provider implementation create and return an instance
of the class from step 3 within the method <span class="inlinecode">getNotificationService</span>.</li>
</ol>
<h2>Support for Undo and Redo</h2>
<p>For standard EMF domain models users do not need to care about implementing undo/redo
functionality within their features. This is all cared about by the framework by
using EMF <span class="inlinecode">TransactionalCommandStacks</span> and
<span class="inlinecode">RecordingCommands</span> for executing features. But in
case users have domain models implemented in another technology than EMF, they need
to care about implementing undo/redo for their domain model changes by themself.
(The changes done to the graphical representation (Graphiti<em> PictogramElements</em>
and <em>GraphicsAlgorithms)</em> are still handled automatically.)</p>
<p>In order to provide undo/redo for non-EMF domain models users can implement the
new interface <span class="inlinecode">ICustomUndoableFeature</span> within their
features. In case a feature implements this interface the Graphiti command stack
will care about the EMF undo/redo and additionally to the standard EMF-undo/redo
call the appropriate methods (<span class="inlinecode">canUndo</span> and
<span class="inlinecode">undo</span> resp. <span class="inlinecode">canRedo</span>
and <span class="inlinecode">redo</span>) within the feature.</p>
<p>Inside the feature coding for those methods users can use the information passed
(the executed feature instance will be called with the instance of its context)
to undo the operations done while executing the feature. Within the features
<span class="inlinecode">execute</span> method users might add additional information
needed to perform the undo to the context object.</p>
<p>The decision to implement <span class="inlinecode">ICustomUndoableFeature</span>
can be taken individually for each feature.</p>
<p>For the pattern approach a similar interface has been introduced:
<span class="inlinecode">ICustomUndoablePattern</span>, for which the before mentioned
also applies accordingly.</p>
<p>By introducing this functionality it is now possible for users of Graphiti to
implement undo and redo functionalities also for non-EMF domain changes; nevertheless
this functionality might also by used for EMF domain models in case they need to
implement additional undo/redo functionality.</p>
<p>Still there is one thing to be aware of: All changes done inside the Graphiti
diagram editor (no matter if EMF changes or non-EMF changes) will write an
<span class="inlinecode">IExecutionInfo</span> entry to the stack that will be available
with the according feature and context for undo/redo. External changes (e.g. changes
done from the standard property sheet) will not break the editor, but will not necessarily
lead to data being available inside the <span class="inlinecode">IExecutionInfo</span>
object written:</p>
<ul>
<li>EMF changes done on the EMF command stack (e.g. from the standard property
sheet) have no associated feature and context. Therefore an empty
<span class="inlinecode">IExecutionInfo</span> entry will be written. On the
other hand all changes done in that case will automatically be undone/redone
by the EMF command stack, so there should be no need to do additional stuff</li>
<li>Non-EMF changes done e.g. from a standard property sheet will naturally
not go through the EMF command stack of the editor, so no
<span class="inlinecode">IExecutionInfo</span> stack entry will be written (in
fact also no EMF command stack entry will be written so there is no issue within
the editor). In this case users are responsible to add their own undo/redo functionality
relying on whatever technology they use for their domain model.</li>
</ul>
</body>
</html>