blob: d1d7551fb0f26f220ad1dac441f2bb7ac515aa94 [file] [log] [blame]
jpaschbac87cf2011-07-21 12:45:27 +00001<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2<html>
mwenzb5dc2f92010-06-16 13:24:52 +00003
4<head>
jpaschf57b3d22011-07-04 12:22:21 +00005<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
mwenzb5dc2f92010-06-16 13:24:52 +00006<title>Providing drill-down behavior</title>
jpaschf57b3d22011-07-04 12:22:21 +00007<link href="../book.css" rel="Stylesheet" type="text/css">
8<link href="../code.css" rel="Stylesheet" type="text/css">
mwenzb5dc2f92010-06-16 13:24:52 +00009</head>
10
jpaschf57b3d22011-07-04 12:22:21 +000011<body>
mwenzb5dc2f92010-06-16 13:24:52 +000012
jpaschf57b3d22011-07-04 12:22:21 +000013<h1>Providing Drill-Down Behavior</h1>
14<p>Often the information which is shown in a diagram has a certain abstraction level,
15and the further details are shown in a separate diagram. For example if a workflow
16connects several sub-workflows, then one overview-diagram might show the complete
17workflow without the inner details of the sub-workflows, and several detail-diagrams
18show the inner details of each sub-workflow.</p>
19<p>In this case the user wants to have an easy possibility to navigate from the
20overview-diagram into the detail-diagrams and vice versa. We call this &quot;drill-down&quot;
21behavior.</p>
22<p>Although going from overview to detail is the most typical example, there are
23other examples, where the user navigates to more independent diagrams. </p>
24<p>All those use cases have one thing in common: the user wants to navigate to a
jpaschbac87cf2011-07-21 12:45:27 +000025diagram, which &quot;represents&quot; the selected business object (meaning this business
jpaschf57b3d22011-07-04 12:22:21 +000026object is central for the diagram). </p>
27<p>Graphiti offers the possibility to link business objects to pictogram elements
28(including the diagram). The drill-down feature works in a way that it searches
29for all diagrams having a given business object associated. Then the user can choose
30from the found diagrams to which to navigate (if only one diagram is found, than
31this is directly opened).</p>
32<p>This is different to a where-used functionality, where the user would search
33for all diagrams using a business object, no matter if the diagram really &quot;represents&quot;
34the business object.</p>
35<h2>Creating a Drill-Down Feature</h2>
36<p>In this example we want to enable the users to navigate to the diagram(s) which
37have the currently selected EClass associated. Therefore we have to create a drill-down
38feature and make it available in the feature provider.</p>
jpaschbac87cf2011-07-21 12:45:27 +000039<ul>
40 <li>A drill-down feature is a <a href="custom-feature.htm">custom feature</a>
41 which can easily be implemented by extending the base class
42 <a href="../../../javadoc/org/eclipse/graphiti/ui/features/AbstractDrillDownFeature.html">
43 AbstractDrillDownFeature</a>.</li>
44</ul>
45<p>The functionality of the <span class="inlinecode">AbstractDrillDownFeature</span>
46is not tool-independent, so the method <span class="inlinecode">getDiagrams()</span>
47can be implemented only by the tool efficiently. Furthermore we just overwrite the
48<span class="inlinecode">canExecute()</span> method, so that the feature is only
49enabled if exactly one EClass is selected.</p>
jpaschf57b3d22011-07-04 12:22:21 +000050<p>You can see the complete implementation of the drill-down feature here:</p>
51<!-- Begin code ------------------------------------------------------------------------------- -->
52<p>&nbsp;</p>
53<div class="literallayout">
54 <div class="incode">
55 <p class="code"><span class="keyword">package </span>org.eclipse.graphiti.examples.tutorial.features;<br>&nbsp;<br>
56 <span class="keyword">public class</span> TutorialDrillDownEClassFeature
57 <span class="keyword">extends </span>AbstractDrillDownFeature {<br>&nbsp;<br>&nbsp;&nbsp;&nbsp;
58 <span class="keyword">public </span>TutorialDrillDownEClassFeature(IFeatureProvider
59 fp) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
60 <span class="keyword">super</span>(fp);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;<br>&nbsp;&nbsp;&nbsp;
61 @Override<br>&nbsp;&nbsp;&nbsp; <span class="keyword">public </span>String
62 getName() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
63 <span class="keyword">return </span><span class="string">&quot;Open associated
64 diagram&quot;</span>;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;<br>&nbsp;&nbsp;&nbsp;
65 @Override<br>&nbsp;&nbsp;&nbsp; <span class="keyword">public </span>String
66 getDescription() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
67 <span class="keyword">return </span><span class="string">&quot;Open the diagram
68 associated with this EClass&quot;</span>;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;<br>&nbsp;&nbsp;&nbsp;
69 @Override<br>&nbsp;&nbsp;&nbsp; <span class="keyword">public boolean</span>
70 canExecute(ICustomContext context) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
71 PictogramElement[] pes = context.getPictogramElements();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
72 <span class="comment">// first check, if one EClass is selected</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
73 <span class="keyword">if</span> (pes != <span class="keyword">null
74 </span>&amp;&amp; pes.<span class="string"><em>length</em></span> == 1) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
75 Object bo = getBusinessObjectForPictogramElement(pes[0]);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
76 <span class="keyword">if</span> (bo <span class="keyword">instanceof</span>
77 EClass) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
78 <span class="comment">// then forward to super-implementation, which checks
79 if<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
80 // this EClass is associated with other diagrams</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
81 <span class="keyword">return super</span>.canExecute(context);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
82 }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
83 <span class="keyword">return false</span>;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;<br>&nbsp;&nbsp;&nbsp;
84 @Override<br>&nbsp;&nbsp;&nbsp; <span class="keyword">protected </span>Collection&lt;Diagram&gt;
85 getDiagrams() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Collection&lt;Diagram&gt;
86 result = Collections.emptyList();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
87 Resource resource = getDiagram().eResource();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
88 URI uri = resource.getURI();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; URI
89 uriTrimmed = uri.trimFragment();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
90 <span class="keyword">if</span> (uriTrimmed.isPlatformResource()){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
91 String platformString = uriTrimmed.toPlatformString(<span class="keyword">true</span>);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
92 IResource fileResource = ResourcesPlugin.getWorkspace()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
93 .getRoot().findMember(platformString);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
94 <span class="keyword">if</span> (fileResource != <span class="keyword">null</span>){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
95 IProject project = fileResource.getProject();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
96 result = TutorialUtil.getDiagrams(project);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
97 }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
98 <span class="keyword">return</span> result;<br>&nbsp;&nbsp;&nbsp; }<br>}<br>
99 </p>
100 </div>
101</div>
102<p>&nbsp;</p>
103<!-- End code ------------------------------------------------------------------------------- -->
jpaschbac87cf2011-07-21 12:45:27 +0000104<p>The complete implementation of class <span class="inlinecode">TutorialUtil</span>
105can be seen here:</p>
jpaschf57b3d22011-07-04 12:22:21 +0000106<!-- Begin code ------------------------------------------------------------------------------- -->
107<p>&nbsp;</p>
108<div class="literallayout">
109 <div class="incode">
110 <p class="code"><span class="keyword">package </span>org.eclipse.graphiti.examples.tutorial;<br>
111 <br><span class="keyword">public class</span> TutorialUtil {<br>&nbsp;<br>&nbsp;&nbsp;&nbsp;
112 <span class="keyword">public static</span> Collection&lt;Diagram&gt; getDiagrams(IProject
113 p) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="keyword">final</span>
114 List&lt;IFile&gt; files = getDiagramFiles(p);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
115 <span class="keyword">final</span> List&lt;Diagram&gt; diagramList =
jpaschda3428a2012-05-25 11:10:26 +0200116 <span class="keyword">new </span>ArrayList&lt;Diagram&gt;();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jpaschf57b3d22011-07-04 12:22:21 +0000117 <span class="keyword">final</span> ResourceSet rSet =
118 <span class="keyword">new</span> ResourceSetImpl();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
119 <span class="keyword">for</span> (<span class="keyword">final</span> IFile
120 file : files) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
121 <span class="keyword">final</span> Diagram diagram = getDiagramFromFile(file,
122 rSet);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
123 if (diagram != <span class="keyword">null</span>) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
124 diagramList.add(diagram);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
125 }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
126 <span class="keyword">return</span> diagramList;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;<br>&nbsp;&nbsp;&nbsp;
127 <span class="keyword">private static</span> List&lt;IFile&gt; getDiagramFiles(IContainer
128 folder) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="keyword">
129 final</span> List&lt;IFile&gt; ret = <span class="keyword">new</span> ArrayList&lt;IFile&gt;();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
130 <span class="keyword">try</span> {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
131 final IResource[] members = folder.members();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
132 <span class="keyword">for</span> (<span class="keyword">final</span> IResource
133 resource : members) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
134 <span class="keyword">if</span> (resource <span class="keyword">instanceof</span>
135 IContainer) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
136 ret.addAll(getDiagramFiles((IContainer) resource));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
137 } <span class="keyword">else if</span> (resource <span class="keyword">instanceof</span>
138 IFile) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
139 <span class="keyword">final</span> IFile file = (IFile) resource;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
140 <span class="keyword">if</span> (file.getName().endsWith(<span class="string">&quot;.diagram&quot;</span>))
141 {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
142 ret.add(file);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
143 }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
144 }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
145 }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <span class="keyword">catch</span>
146 (<span class="keyword">final</span> CoreException e) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
147 e.printStackTrace();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
148 <span class="keyword">&nbsp;return</span> ret;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;<br>&nbsp;&nbsp;
149 <span class="keyword">&nbsp;private static</span> Diagram getDiagramFromFile(IFile
150 file, <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
151 ResourceSet resourceSet) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
152 <span class="comment">// Get the URI of the model file.</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
153 <span class="keyword">final</span> URI resourceURI = getFileURI(file, resourceSet);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
154 <span class="comment">// Demand load the resource for this file.</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
155 Resource resource;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jpasch363344b2011-07-04 12:27:23 +0000156 <span class="keyword">try</span> {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
jpaschf57b3d22011-07-04 12:22:21 +0000157 resource = resourceSet.getResource(resourceURI, <span class="keyword">true</span>);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
158 <span class="keyword">if</span> (resource != <span class="keyword">null</span>)
159 {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
160 <span class="comment">&nbsp;// does resource contain a diagram as root object?</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
161 <span class="keyword">final</span> EList&lt;EObject&gt; contents = resource.getContents();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
162 <span class="keyword">for</span> (<span class="keyword">final</span> EObject
163 object : contents) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
164 <span class="keyword">if</span> (object <span class="keyword">instanceof</span>
165 Diagram) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
166 <span class="keyword">return</span> (Diagram) object;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
167 }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
168 }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
169 } <span class="keyword">catch</span> (<span class="keyword">final</span>
170 WrappedException e) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
171 e.printStackTrace();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
172 <span class="keyword">return null</span>;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;<br>&nbsp;&nbsp;&nbsp;
173 <span class="keyword">private static</span> URI getFileURI(IFile file, ResourceSet
174 resourceSet) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="keyword">&nbsp;final</span>
175 String pathName = file.getFullPath().toString();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
176 URI resourceURI = URI.createFileURI(pathName);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
177 resourceURI = resourceSet.getURIConverter().normalize(resourceURI);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
178 <span class="keyword">return</span> resourceURI;<br>&nbsp;&nbsp;&nbsp; }<br>
179 }<br>&nbsp; </p>
180 </div>
181</div>
182<p>&nbsp;</p>
183<!-- End code ------------------------------------------------------------------------------- -->
184<p>Before we test our drill-down feature, we have link EClasses to our diagrams.
185In our small example there is no obvious reasoning, which EClass to assign to a
186diagram. Because of that we create a new custom feature, where the user himself
187can assign selected EClasses to the current diagram. </p>
188<p>You can see the complete implementation of this custom feature here:</p>
189<!-- Begin code ------------------------------------------------------------------------------- -->
190<p>&nbsp;</p>
191<div class="literallayout">
192 <div class="incode">
193 <p class="code"><span class="keyword">package</span> org.eclipse.graphiti.examples.tutorial.features;<br>&nbsp;<br>
194 <span class="keyword">public class</span> TutorialAssociateDiagramEClassFeature
195 <span class="keyword">extends</span><br>&nbsp;&nbsp;&nbsp; AbstractCustomFeature
196 {<br>&nbsp;<br>&nbsp;&nbsp;&nbsp; <span class="keyword">public </span>TutorialAssociateDiagramEClassFeature(IFeatureProvider
197 fp) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
198 <span class="keyword">super</span>(fp);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;<br>&nbsp;&nbsp;&nbsp;
199 @Override<br>&nbsp;&nbsp;&nbsp; <span class="keyword">public </span>String
200 getName() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
201 <span class="keyword">return </span><span class="string">&quot;Associate diagram&quot;</span>;<br>&nbsp;&nbsp;&nbsp;
202 }<br>&nbsp;<br>&nbsp;&nbsp;&nbsp; @Override<br>&nbsp;&nbsp;&nbsp;
203 <span class="keyword">public </span>String getDescription() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
204 <span class="keyword">return </span><span class="string">&quot;Associate the
205 diagram with this EClass&quot;</span>;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;<br>&nbsp;&nbsp;&nbsp;
206 @Override<br>&nbsp;&nbsp;&nbsp; <span class="keyword">public boolean</span>
207 canExecute(ICustomContext context) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
208 <span class="keyword">boolean</span> ret = <span class="keyword">false</span>;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
209 PictogramElement[] pes = context.getPictogramElements();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
210 <span class="keyword">if</span> (pes != <span class="keyword">null
211 </span>&amp;&amp; pes.<span class="string"><em>length</em> </span>&gt;= 1) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
212 ret = <span class="keyword">true</span>;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
213 <span class="keyword">for</span> (PictogramElement pe : pes) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
214 Object bo = getBusinessObjectForPictogramElement(pe);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
215 <span class="keyword">if</span> (! (bo <span class="keyword">instanceof</span>
216 EClass)) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
217 ret = <span class="keyword">false</span>;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
218 }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
219 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
220 }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="keyword">return</span>
221 ret;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;<br>&nbsp;&nbsp;
222 <span class="keyword">&nbsp;public</span> <span class="keyword">void</span>
223 execute(ICustomContext context) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
224 PictogramElement[] pes = context.getPictogramElements();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
225 EClass eClasses[] = <span class="keyword">new</span> EClass[pes.<span class="string"><em>length</em></span>];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
226 <span class="keyword">&nbsp;for</span> (int i = 0; i &lt; eClasses.<span class="string"><em>length</em></span>;
227 i++) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
228 eClasses[i] =<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
229 (EClass) getBusinessObjectForPictogramElement(pes[i]);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
230 }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
231 <span class="comment">// associate selected EClass with diagram</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
232 link(getDiagram(), eClasses);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;<br>}<br>
233 </p>
234 </div>
235</div>
236<p>&nbsp;</p>
237<!-- End code ------------------------------------------------------------------------------- -->
238<p>Finally the feature provider has to deliver our newly created custom features
239(overwrite the method
240<a href="../../../javadoc/org/eclipse/graphiti/features/IFeatureProvider.html#getCustomFeatures(org.eclipse.graphiti.features.context.ICustomContext)">
241getCustomFeatures</a>). </p>
242<p>This implementation can be seen here:</p>
243<!-- Begin code ------------------------------------------------------------------------------- -->
244<p>&nbsp;</p>
245<div class="literallayout">
246 <div class="incode">
247 <p class="code">@Override<br><span class="keyword">public </span>ICustomFeature[]
248 getCustomFeatures(ICustomContext context) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
249 <span class="keyword">return new</span> ICustomFeature[] <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
250 { <span class="keyword">new</span> TutorialRenameEClassFeature(this),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
251 <span class="keyword">new</span> TutorialDrillDownEClassFeature(this),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
252 <span class="keyword">new</span> TutorialAssociateDiagramEClassFeature(this)};<br>
253 }<br></p>
254 </div>
255</div>
256<p>&nbsp;</p>
257<!-- End code ------------------------------------------------------------------------------- -->
258<h2>Test: Navigate to Diagram Associated with a EClass</h2>
259<p>Now start the editor and test this new drill-down feature:</p>
260<ol>
261 <li>create or open two diagrams</li>
262 <li>in the first diagram create a new EClass</li>
263 <li>use &quot;copy &amp; paste&quot; to copy this EClass to the second diagram (the underlying
264 business object is remains the same!)</li>
265 <li>open the context menu on the EClass in the second diagram; choose &quot;Associate
266 diagram&quot;</li>
267 <li>save both diagrams and close the second diagram</li>
268 <li>open the context menu on the EClass in the first diagram; choose &quot;Open associated
269 diagram&quot;</li>
270 <li>now the second diagram is opened again</li>
mwenzb5dc2f92010-06-16 13:24:52 +0000271</ol>
jpaschbac87cf2011-07-21 12:45:27 +0000272<p>&nbsp;</p>
mwenzb5dc2f92010-06-16 13:24:52 +0000273
mwenzb5dc2f92010-06-16 13:24:52 +0000274</body>
275
276</html>