Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: b2a05e6d373c768bc78159dde3f921117d762682 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<TITLE>Developer's Guide to the Extensible Type Registry</TITLE>
<SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript">
<!--
if (navigator.userAgent.toLowerCase().indexOf('microsoft') >= 0) {
    document.write('<LINK rel="stylesheet" href="./styles/technote-ie.css" type="text/css">')
} else {
    document.write('<LINK rel="stylesheet" href="./styles/technote.css" type="text/css">')
}
// -->
</SCRIPT>
<style type="text/css" media="screen">
    <!-- @import url("./styles/menuExpandable.css"); -->
</style>
<style type="text/css" media="print">
<!--
   /*BODY { width: 13in }*/
-->
</style>
<script type="text/javascript" src="./styles/menuExpandable.js"></script>
<script type="text/javascript">
<!--
    function initializeTable(table) {
        var rows = table.rows;
        for (i = 1; i < rows.length; i++) { // skip the header row
           if (i % 2 == 0) {
              rows[i].style.backgroundColor = "#D0F0FF";
           }
        }
    }
    
    window.onload = function() {
        initializeMenu("changeLogMenu", "changeLogActuator");
        initializeMenu("examplesMenu", "examplesActuator");
        initializeMenu("ex_txMenu", "ex_txActuator");
        
        var tables = document.getElementsByTagName("TABLE");
        
        var toProcess = new Array();
        var count = 0;
        for (i = 0; i < tables.length; i++) {
            if (tables[i].className == "high") {
                toProcess[count] = tables[i];
                count = count + 1;
            }
        }
        
        for (t in toProcess) {
            initializeTable(toProcess[t]);
        }
    }
//-->
</script>
</HEAD>

<BODY>
<A name="top"></A><IMG border="0" src="./icons/gmf_header.gif" width="347" height="134">
<H1 align="center">Developer's Guide to the Extensible Type Registry</H1>

<H2>Contents</H2>
Items marked with <img src="./icons/plus.gif"/> expand when selected.
<UL>
    <LI class="menuitem"><A href="#intro">Introduction</A></LI>
    <LI class="menuitem"><A href="#ext_points">Extension Points and API</A></LI>
    <LI class="menuitem"><A href="#concepts">Concepts</A></LI>
    <LI class="menuitem"><A href="#use">Use of the Extensible Type Registry in GMF</A></LI>
    <li class="menubar">
        <a href="#" id="examplesActuator"
           class="actuator">Examples</a>
        <ul id="examplesMenu" class="menu">
          <li><a href="#examples">Overview</a></li>
          <li><a href="#" id="ex_txActuator"
            class="actuator">Code Examples</a>
            <ul id="ex_txMenu" class="submenu">
              <li><a href="#ex_define">Defining an Element Type</a></li>
              <li><a href="#ex_bind">Binding Advice to an Existing Element Type</a></li>
              <li><a href="#ex_context">Changing the Edit Helper Context during Element Creation</a></li>
              <li><a href="#ex_configure">Configuring a new Element</a></li>
              <li><a href="#ex_factory">Defining a Factory to Instantiate Custom Element Types</a></li>
              <li><a href="#ex_registry">Using the Element Type Registry</a></li>
            </ul></li>
        </ul></li>
    <LI class="menuitem"><A href="#models">Design/Code/Interaction Models</A></LI>
</UL>
<HR>
<H2><A name="intro"></A>Introduction</H2>
<P class="backto"><FONT size="2">[<A href="#top">back to top</A>]</FONT></P>
<P>The Eclipse GMF project uses  EMF to build its structured data model. EMF defines a framework that allows users to create, modify and destroy model elements in an application. However, the metaclasses defined in an EMF Ecore metamodel are not always sufficient to build a full-featured graphical modeling application. As well, a third party may wish to extend the metamodel and provide specialized model elements in their application.  </P>
<P>The Extensible Type Registry provides a way for GMF clients to define an
application-specific classification system based on, but alternative to,
the metaclasses defined by an Ecore metamodel. It allows GMF clients to describe the domain elements in their application by:</P>
<UL>
	<LI>contributing icons and display names for EMF metamodel types and
	specializations</LI>
	<LI>defining reusable default editing behaviour for EMF metamodel types</LI>
	<LI>defining additional behaviour for specializations </LI>
	<LI>extending the default editing behaviour for metamodel types
	and specializations defined by other plugins</LI>
</UL>
<P>For example, consider a metamodel for the digital logic domain. It contains the basic building blocks for digital logic circuits, such as metaclasses for circuit, AND gate, OR gate and XOR gate. An editor for digital logic diagrams will provide creation tools for these fundamental elements. It should also provide creation tools for some commonly used 'canned' circuits, such as those for a Half Adder or a Full Adder. The Half Adder and the Full Adder are Circuits that contain a specific arrangement of AND, OR and XOR gates. As such, the Half Adder and the Full Adder are element types that add deeper meaning to the Circuit EClass with a specific arrangement of child gates. The editor will need to prevent the deletion of the individual AND, OR and XOR gates contained in a Half Adder or a Full Adder, because deleting them would change the function of the circuit. The Half and Full Adder types and their edit behaviour are defined in the extensible element type registry.</P>
<P>Element types can also be used by visual editing tools to set the values of existing elements in a model.</P>
<P>For example, consider the metamodel for the library domain. It contains, among other things, Writers that have a feature referencing the Books they have written. An editor for library diagrams may provide a drawing tool to connect a Writer to a Book, which means that the Writer is the author of that Book. This drawing tool creates the 'Writes' relationship between a Writer and a Book by adding the Book to the books feature of the Writer. This 'Writes' relationship can be expressed as an element type.</P>
<P>This document describes the concepts behind the  Extensible Type Registy and outlines how it is used in other parts of GMF. It includes code examples illustrating how to implement some of the key concepts as well as an overview of the registry design.</P><HR>
<H2><A name="ext_points"></A>Extension Points and API</H2>
<P class="backto"><FONT size="2">[<A href="#top">back to top</A>]</FONT></P>
The extensible type registry defines the following extension point:
<ul>
	<li><a href="../../../reference/extension-points/org_eclipse_gmf_runtime_emf_type_core_elementTypes.html">org.eclipse.gmf.runtime.emf.type.core.elementTypes</a></li>
</ul>
The extensible type registry API is defined in the following packages:
<ul>
	<li><a href="../../../reference/api/common/org/eclipse/gmf/runtime/emf/type/core/package-summary.html">org.eclipse.gmf.runtime.emf.type.core</a></li>
	<li><a href="../../../reference/api/common/org/eclipse/gmf/runtime/emf/type/core/commands/package-summary.html">org.eclipse.gmf.runtime.emf.type.core.commands</a></li>
	<li><a href="../../../reference/api/common/org/eclipse/gmf/runtime/emf/type/core/edithelper/package-summary.html">org.eclipse.gmf.runtime.emf.type.core.edihelper</a></li>
	<li><a href="../../../reference/api/common/org/eclipse/gmf/runtime/emf/type/core/requests/package-summary.html">org.eclipse.gmf.runtime.emf.type.core.requests</a></li>
	<li><a href="../../../reference/api/common/org/eclipse/gmf/runtime/emf/type/ui/package-summary.html">org.eclipse.gmf.runtime.emf.type.ui</a></li>
</ul>

<H2><A name="concepts"></A>Concepts</H2>
<P class="backto"><FONT size="2">[<A href="#top">back to top</A>]</FONT></P>
<H3>Element Types</H3>
<P></P>
<P></P>
<P>The domain-specific concepts that can be displayed, created, modified and
destroyed as logical elements in a GMF application are described using
element types. Each element type defines how model objects that match
its type are to be displayed (by icon and display name), as well as how
they are to be created, modified and deleted (by an edit helper and edit
helper advice).</P>
<P>There are two kinds of element types: <I>metamodel</I>
types and <I>specialization</I> types.</P>
<P>A <I>metamodel</I> type corresponds directly with an EClass in the
domain's EMF model, with no futher qualifications. It is not permitted
to define more than <I></I>one metamodel type for <I></I>a single
EClass. All model objects with the same EClass have the same metamodel
type. The metamodel type defines the editing behaviour for these
matching model objects in its <I>edit helper</I>. By defining a metamodel type for an EClass, the application-specific editing behaviour for that type of element can be defined, and third parties can extend the editing behaviour. An icon and display name other than those defined in the Ecore model can also be associated with this type of element.</P>
<P><I>Specialization</I> types can extend a single metamodel type or any
number of other specialization types. The purpose of a specialization type is to define bind points for advice, icons and display names for new classifications of model objects. It is not permitted to define a
specialization type that specializes (directly or indirectly) more than
a single metamodel type. All model objects matching the characteristics
described by the specialization type as well as those described by the type
it specializes will share the same specialization type. A specialization
type can extend the editing behaviour of the element type that it
specializes by its <I>edit helper advice</I>.</P><H3>Element Type Registry</H3>
<P>A registry of element types is maintained in GMF and it provides the
ability to find:</P>
<UL>
	<LI>element types by their unique identifiers</LI>
	<LI>the element types that match an existing model object or its EClass</LI>
	<LI>the edit helper advice that applies to an element type or an
	existing model object</LI>
	<LI>the element types that describe model objects which can be
	contained in a given feature of a given container object</LI>
</UL>
<P>Static declarations of element types in the <A href="../../../reference/extension-points/org_eclipse_gmf_runtime_emf_type_core_elementTypes.html"><CODE>elementTypes</CODE></A>
extension point are added automatically to this registry the first time
the registry is used. Element types can also be registered dynamically,
and interested parties can listen for notification of dynamic changes to
the registry.<SPAN
	style="font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:
Symbol"><SPAN
	style="mso-list:Ignore"><SPAN style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN></SPAN></SPAN></P>
<P>Only one metamodel type  matches a model object, but many specialization types can match the same object. Edit helper advice bound to all matching element types will be considered when editing the model object.</P>
<H3>Element Type Factory</H3>
<P>Default implementations of metamodel and specialization types are
used to instantiate types registered through the <A href="../../../reference/extension-points/org_eclipse_gmf_runtime_emf_type_core_elementTypes.html"><CODE>elementTypes</CODE></A>
extension point. If a custom element type implementation is required
(e.g., if there are additional properties associated with an element
type, or there is a need to replace the default editing behaviour), an
element type factory can be declared to instantiate specific element
types . The factory is identified by its 'kind', and element types that want to be created by this factory
must specify its factory kind in their extension. Alternatively, custom element type implementations can be instantiated by a client and registered dynamically with the element type registry.</P>
<H3>Edit Helpers</H3>
<P>Editing behaviour for a metamodel type is defined in its <I>edit
helper</I>. The edit helper is a factory for edit commands. These
commands are instantiated in response to requests to edit a model object
whose EClass matches the metamodel type. By default, the edit commands
returned by an edit helper are decorated with commands from advice that
matches the model object being edited.</P>
<H3>Edit Helper Advice</H3>
<P class="MsoBodyText">Editing behaviour for a specialization type is
defined in its <I>edit helper advice</I>. The specialized behaviour
decorates the default behaviour provided by the edit helper of the
metamodel type that it specializes. When an edit is performed on a model
object, advice from all of the specializations that match that object is
contributed to the command. Advice can be contributed before or after
the default behaviour. Note that there is no guarantee in which order
advice commands will be applied relative to each other, except to say
that all 'before' advice occurs before the basic edit and all  'after' advice occurs after the basic edit.</P><P class="MsoBodyText">Edit helper advice returns a null command when there is no advice to contribute. It returns an unexecutable command when it wishes to disable the editing gesture.</P>
<P class="MsoBodyText">Edit helper advice belonging to a specialization
type will also apply to all further specializations of that type. </P>
<H3>Advice Bindings</H3>
<P>Edit helper advice can be bound to any existing metamodel type or
specialization type to extend the editing behaviour for model objects of
its kind.</P>
<P>The scope of an advice binding is an optional attribute specified in the binding XML (the attribute name is 'inheritance'). It can be one of the following:</P>
<UL>
	<LI>The advice will apply to the target element type, and to all
	metamodel types whose EClasses are subtypes of the target type, and to
	all specializations of those metamodel types. For example, </LI>
	<LI>The advice will apply only to the target element type and its
	specializations. It is not applied to related metamodel types or their
	specializations.
	</LI>
</UL>
<P></P>
<H3>Edit Requests</H3>
<P>An edit request carries the information required to obtain an edit
command from an edit helper.</P>
<P>The edit request carries a collection of parameters which are used to
communicate arbitrary data to the edit helpers and advice. It is
recommended that any client contributing element types to the extensible
type registry publish a list of the edit request parameters that are
understood by its edit helpers and advice.</P>
<P>Each edit request has an edit helper context which is used to
identify the model element being edited by the request, from which is
derived the edit helper and advice to honour the edit request. For
element creation, the model object being edited is the one that will
contain the new element. By default, the edit helper context is the
container specified in the request. However, the default implementation
of the create request will in turn ask the type that is being created
for the edit helper context. Edit helpers and advice bound to the type
being created can change the default container by finding or creating a
different container for the new element in response to the request for
the edit helper context.</P>
<P>The edit request for element creation may have specified the feature
that should contain the new element. It is recommended that edit helpers
be equipped to use a default containment feature, if possible, in the
event that one is not specified in the request. This is recommended for
the convenience of clients that do not wish to be aware of the feature
that should contain a certain kind of element. A specialization type
that declares that model objects of its kind must be contained in a
specific feature will be created in that feature by default if the
request does not specify a feature.</P>
<H2><A name="use"></A>Use of the Extensible Type Registry in GMF</H2>
<P class="backto"><FONT size="2">[<A href="#top">back to top</A>]</FONT></P>
<H3>Diagram Assistant and Palette Creation Tools</H3>
<P>Items in the diagram popup bar and connection handles are associated with the element type that will be created when the item is selected. Creation tools on the diagram palette are likewise associated with the element type that will be created when the tool is selected and applied to the diagram.</P>
<H3>Semantic Edit Policy</H3>
<P>The default semantic edit policy installed on edit parts on a diagram uses the extensible type registry to obtain the command to honour the semantic edit request. It does a lookup in the registry for the type
matching the edit context of the request, and obtains the edit command from that type. If the edit command is null or
non-executable, the editing gesture cannot be performed.</P>
<H3>Icon Service</H3>
<P>A lowest-priority icon provider is registered with the Icon Service that  returns the icon for an element type by resolving its icon URL. </P>
<P>The same icon provider will also provide the icon for an existing model object by finding the icon for its matching element type from the registry. In cases where many
specialized types apply to the model object, the  provider will return the
icon defined by the first specialization it encounters<SPAN
	style="mso-spacerun:yes">&nbsp; </SPAN>(searching breadth-first from
most specialized to least specialized).</P><H3>View Service</H3>
<P class="MsoBodyText">Element types can be used as the semantic adapter  in a request to the View Service. In this capacity, the element type communicates the kind of model object for which a view is requested.</P>
<P class="MsoBodyText">The element type semantic adapter is used by the view service in one of two ways:</P>
<OL>
	<LI>the EClass associated with the element type is used to identify the view</LI>
	<LI>the element type is a kind of IHintedType, and its semantic hint is used to identify the view</LI>
</OL><H3>Modeling Assistant Service</H3>
<P>The modeling assistant service returns element types to describe the kinds of elements and relationships that can be created in a given modeling gesture. For example, if a connection handle is used to create a relationship between two model objects, a popup menu will appear listing the kinds of relationships that can be created between the two objects. This list is populated with element types that describe the relationships.</P>
<H2><A name="examples"></A>Examples</H2>
<P class="backto"><FONT size="2">[<A href="#top">back to top</A>]</FONT></P>
<P>This section illustrates the usage of the Extensible Type Registry using code examples.
Many of these examples are taken from the GMF logic and library examples.</P>
<H3><A name="ex_define"></A>Defining an Element Type</H3>
<P>Element types are declared on the <A href="../../../reference/extension-points/org_eclipse_gmf_runtime_emf_type_core_elementTypes.html"><CODE>elementTypes</CODE></A>
extension point.</P>
<P>When the type describes a metaclass in the domain model with no
further matching conditions, a <I>metamodel</I> type can be defined:</P>
<PRE class="snippet">&lt;extension point=&quot;org.eclipse.gmf.runtime.emf.type.core.elementTypes&quot;&gt;
   &lt;metamodel
         nsURI=&quot;http://www.ibm.com/xtools/1.5.0/logicsemantic&quot;&gt;
      &lt;metamodelType
             id=&quot;logic.circuit&quot;     
             icon=&quot;icons/circuit16.gif&quot;
             name=&quot;%CircuitTool.Label&quot;
             eclass=&quot;Circuit&quot;
             edithelper=&quot;org.eclipse.gmf.examples.logic.CircuitEditHelper&quot;&gt;
      &lt;/metamodelType&gt;
   &lt;/metamodel&gt;
&lt;/extension&gt;</PRE>
<P>When the type describes a specialization of a metaclass in the domain
model to which further characteristics have been ascribed, a <I>specialization</I>
type can be defined with an Eclipse enablement expression (<CODE>org.eclipse.core.expressions</CODE>) that captures those further characteristics:</P>
<PRE class="snippet">&lt;extension point=&quot;org.eclipse.gmf.runtime.emf.type.core.elementTypes&quot;&gt;
   &lt;metamodel
         nsURI=&quot;http://www.ibm.com/xtools/1.5.0/logicsemantic&quot;&gt;
      &lt;specializationType
             id=&quot;logic.halfAdder&quot;
             icon=&quot;icons/halfAdder.gif&quot;
             name=&quot;%HalfAdderTool.Label&quot;
             edithelperadvice=&quot;org.eclipse.gmf.examples.logic.HalfAdderAdvice&quot;&gt; 
         &lt;specializes id=&quot;logic.circuit&quot;/&gt;
         &lt;enablement&gt;
            &lt;test 
                property=&quot;org.eclipse.gmf.examples.logic.isHalfAdder&quot; 
                value=&quot;true&quot;/&gt;
         &lt;/enablement&gt;
      &lt;/specializationType&gt;
   &lt;/metamodel&gt;
&lt;/extension&gt;</PRE>
<P>When the Eclipse expression language (<CODE>org.eclipse.core.expressions</CODE>) is not effective in specifying the
matching conditions, a custom matcher may be provided:</P>
<PRE class="snippet">&lt;extension point=&quot;org.eclipse.gmf.runtime.emf.type.core.elementTypes&quot;&gt;
   &lt;metamodel
         nsURI=&quot;http://www.ibm.com/xtools/1.5.0/logicsemantic&quot;&gt;
      &lt;specializationType
             id=&quot;logic.fullAdder&quot;
             icon=&quot;icons/fullAdder.gif&quot;
             name=&quot;%FullAdderTool.Label&quot;
             edithelperadvice=&quot;org.eclipse.gmf.examples.logic.FullAdderAdvice&quot;&gt; 
         &lt;specializes id=&quot;logic.circuit&quot;/&gt;
         &lt;matcher class=&quot;org.eclipse.gmf.examples.logic.FullAdderMatcher&quot;/&gt;
      &lt;/specializationType&gt;
   &lt;/metamodel&gt;
&lt;/extension&gt;</PRE>
<P>with the particular matcher implementation perhaps looking like:</P>
<PRE class="snippet">public class FullAdderMatcher implements IElementMatcher {
    public boolean matches(EObject eObject) {
        boolean result = false;
        
        if (eObject instanceof Circuit) {
            // it should be a Circuit, but we'll be defensive
            Circuit circuit = (Circuit) eObject;

            result = isFullAdder(FullAdder);
        }
        
        return result;
    }
    
    private boolean isFullAdder(Circuit circuit) {
        // ... determine whether 'circuit' is a
        //     full adder
    }
}</PRE>
<P>When the type describes something that has no direct relationship to
a metaclass in the domain model, such as a reference relationship, a
specialization of the <I>null</I> element type can be defined:</P>
<PRE class="snippet">&lt;extension point=&quot;org.eclipse.gmf.runtime.emf.type.core.elementTypes&quot;&gt;
    &lt;specializationType
            id=&quot;library.writeBook&quot;     
            icon=&quot;icons/writeBook.gif&quot;
            name=&quot;%WriteBook.Label&quot;
            edithelperadvice=&quot;org.eclipse.gmf.examples.library.WriteBookAdvice&quot;&gt; 
        &lt;specializes id=&quot;org.eclipse.gmf.runtime.emf.type.core.null&quot;/&gt;
    &lt;/specializationType&gt;
&lt;/extension&gt;</PRE>
<P>with the particular edit helper advice implementation perhaps looking
like:</P>
<PRE class="snippet">public class WriteBookAdvice extends AbstractEditHelperAdvice {
    protected ICommand getBeforeConfigureCommand(ConfigureRequest request) {
        ICommand result = null;

        Object sourceObject = request.getParameter(
                                       CreateRelationshipRequest.SOURCE);
        Object targetObject = request.getParameter(
                                       CreateRelationshipRequest.TARGET);
        
        if (sourceObject instanceof Writer &amp;&amp; targetObject instanceof Book) {
            // the source should be a Writer and the target a Book, 
            // but we'll be defensive
            final Writer writer = (Writer) sourceObject;
            final Book book = (Book) targetObject;

            result = new ConfigureElementCommand(request) {
                protected CommandResult doExecute(
                                           IProgressMonitor progressMonitor) {
                    
                    // relate the book to the writer
                    writer.getBooks().add(book);
                    
                    return newOKCommandResult();
                }
            };
        }
        
        return result;
    }
}</PRE>
<P>Note that in this last case, it was not necessary to specify the
metamodel namespace URI, because there are no references to the domain
model (e.g., EClasses, reference features) in the XML definition.</P>
<H3><A name="ex_bind"></A>Binding Advice to an Existing Element Type</H3>
<P class="MsoBodyText">Edit advice can be bound to any existing element
type to decorate the resulting edit command with additional behaviour.
Example of a binding for the Writer element type that limits the
creation of the WriteBook relationship from Writers to Books:</P>
<PRE class="snippet">&lt;extension point=&quot;org.eclipse.gmf.runtime.emf.type.core.elementTypes&quot;&gt;
   &lt;metamodel
           nsURI=&quot;http://org/eclipse/emf/examples/library/extlibrary.ecore/1.0.0&quot;&gt;
       &lt;adviceBinding
               id=&quot;library.writerAdvice&quot;
               typeId=&quot;library.writer&quot;
               class=&quot;org.eclipse.gmf.examples.library.WriterAdviceBinding&quot;
               inheritance=&quot;all&quot;&gt;
       &lt;/adviceBinding&gt;
   &lt;/metamodel&gt;
&lt;/extension&gt;</PRE>
<P>with the particular advice binding implementation perhaps looking
like:</P>
<PRE class="snippet">public class WriterAdviceBinding extends AbstractEditHelperAdvice {
    protected ICommand getBeforeCreateRelationshipCommand(
                          CreateRelationshipRequest request) {
        
        if (request.getElementType != LibraryElementTypes.WRITE_BOOK) {
            // only advise the creation of WRITE_BOOK types
            return null;
        }

        ICommand result = null;

        EObject source = request.getSource();
        EObject target = request.getTarget();

        if (source != null &amp;&amp; !(source instanceof Writer)) {
            // the source is specified but it's not a Writer
            // don't permit the creation of the relationship
            result = UnexecutableCommand.INSTANCE;
        }

        if (target != null &amp;&amp; !(target instanceof Book)) {
            // the target is specified but it's not a Book
            // don't permit the creation of the relationship
            result = UnexecutableCommand.INSTANCE;
        }

        return result;
    }
}</PRE>
<H3><A name="ex_context"></A>Changing the Edit Helper Context during Element Creation</H3>
<P>When a request is made to create a new model object, the edit helper
(or edit helper advice) of the element type being created can change the
edit helper context used to identify the model element being edited by
the request. In short, the element type to be created can suggest a new
container for itself other than the one supplied in the request.</P>
<P>Example of an edit helper that changes the edit helper context from a
Diagram to the element that contains, or is associated with that
diagram:</P>
<PRE class="snippet">protected ICommand getEditContextCommand(GetEditContextRequest req) {

    GetEditContextCommand result = null;  
		
    IEditCommandRequest editRequest = req.getEditCommandRequest();
		
    if (editRequest instanceof CreateElementRequest) {
        result = new GetEditContextCommand(req);
        EObject container = ((CreateElementRequest) editRequest).getContainer();

        if (container instanceof Diagram) {
            EObject element = ((Diagram) container).getElement();
	
            if (element == null) {
                // some diagrams have no element
                EObject diagramContainer = ((Diagram) container).eContainer();
	
                if (diagramContainer instanceof EAnnotation) {
                    element = diagramContainer.eContainer();
                }
            }
            container = element;
        }
        result.setEditContext(container);
    }
    return result;
}</PRE>
<H3><A name="ex_configure"></A>Configuring a new Element</H3>
<P>When a request is made to create a new model object, the edit helper
(or edit helper advice) of the element type being created is given the
opportunity to configure the new model object to conform to its
specifications.</P>
<P>Example of an edit helper that configures a new logic gate with two
input terminals and an output terminal:</P>
<PRE class="snippet">protected ICommand getConfigureCommand(final ConfigureRequest req) {

    return new ConfigureLogicElementCommand(req, 
                        SemanticPackage.eINSTANCE.getGate()) {

        protected CommandResult doExecute(IProgressMonitor progressMonitor) {

            Gate oGate = (Gate) req.getElementToConfigure();

            createInputTerminal(oGate, &quot;A&quot;, progressMonitor); //$NON-NLS-1$  
            createInputTerminal(oGate, &quot;B&quot;, progressMonitor); //$NON-NLS-1$ 
            createOutputTerminal(oGate, &quot;1&quot;, progressMonitor); //$NON-NLS-1$

            return newOKCommandResult(oGate);
        }
    };
}</PRE>

<H3><A name="ex_factory"></A>Defining a Factory to Instantiate Custom Element Types</H3>
<P>A factory can be registered to instantiate elements types with a
custom implementation.</P>
<P>Example of a factory that instantiates element types with additional
parameters:</P>
<PRE class="snippet">&lt;extension point=&quot;org.eclipse.gmf.runtime.emf.type.core.elementTypes&quot;&gt;
    &lt;elementTypeFactory
        factory=&quot;org.eclipse.gmf.examples.logic.AdderTypeFactory&quot;
        kind=&quot;org.eclipse.gmf.examples.logic.AdderType&quot;
        params=&quot;adderKind&quot;&gt;
    &lt;/elementTypeFactory&gt;
&lt;/extension&gt;</PRE>


<P>with the particular factory implementation perhaps looking like:</P>


<PRE class="snippet">public class NotationTypeFactory extends AbstractElementTypeFactory {

    private static final class AdderType
            extends SpecializationType
            implements IAdderType {
       
        private final AdderKind adderKind;

        public AdderType(ISpecializationTypeDescriptor descriptor, 
                         String adderKindName) {

            super(descriptor);
            this.adderKind = AdderKind.get(adderKindName);
        }
 
        // AdderKind is an enumeration of types of adders
        public AdderKind getAdderKind() {
            return adderKind;
        }
    }

    public ISpecializationType createSpecializationType(
                   ISpecializationTypeDescriptor descriptor) {

        String parameterName = &quot;adderKind&quot;; //$NON-NLS-1$
        
        String semanticHint = descriptor.getParamValue(parameterName);                       
        return new AdderType(descriptor, semanticHint);
    }
}</PRE>
<P>and an element type declaring that it should be instantiated by this
factory like this:</P>
<PRE class="snippet">&lt;extension point=&quot;org.eclipse.gmf.runtime.emf.type.core.elementTypes&quot;&gt;
   &lt;metamodel
         nsURI=&quot;http://www.ibm.com/xtools/1.5.0/logicsemantic&quot;&gt;
      &lt;specializationType
             id=&quot;logic.fullAdder&quot;
             icon=&quot;icons/fullAdder.gif&quot;
             name=&quot;%FullAdderTool.Label&quot;
             <B>kind=&quot;org.eclipse.gmf.examples.logic.AdderType&quot;</B>
             edithelperadvice=&quot;org.eclipse.gmf.examples.logic.AdderAdvice&quot;&gt; 
         &lt;specializes id=&quot;logic.circuit&quot;/&gt;
         &lt;param name=&quot;adderKind&quot; value=&quot;full&quot;/&gt;
         &lt;enablement&gt;
            &lt;test 
                property=&quot;org.eclipse.gmf.examples.logic.isAdder&quot; 
                value=&quot;full&quot;/&gt;
         &lt;/enablement&gt;
      &lt;/specializationType&gt;
   &lt;/metamodel&gt;
&lt;/extension&gt;</PRE>




<P>If a specialization element types wishes to completely replace the
editing behaviour of the type that it specializes, a factory can be
registered to instantiate the element type:</P>
<PRE class="snippet">&lt;extension point=&quot;org.eclipse.gmf.runtime.emf.type.core.elementTypes&quot;&gt;
    &lt;elementTypeFactory
        factory=&quot;org.eclipse.gmf.examples.logic.HalfAdderTypeFactory&quot;
        kind=&quot;org.eclipse.gmf.examples.logic.HalfAdderType&quot;&gt;
    &lt;/elementTypeFactory&gt;
&lt;/extension&gt;</PRE>


<P>with the particular factory implementation perhaps looking like:</P>


<PRE class="snippet">public class HalfAdderTypeFactory extends AbstractElementTypeFactory {

    // a custom element type implementation for half adders
    public static final class HalfAdderType extends SpecializationType {

        IEditHelper editHelper;

        public HalfAdderType(ISpecializationTypeDescriptor descriptor) {
	    super(descriptor);
        }

        public IEditHelper getEditHelper() {

            if (editHelper == null) {
                // use the half adder edit helper which completely 
                // replaces the circuit edit helper behaviour
                editHelper = new HalfAdderEditHelper();
	    }
	    return editHelper;
        }
    }



    public ISpecializationType createSpecializationType(
                   ISpecializationTypeDescriptor descriptor) {

        // instantiate the custom element type
        return new HalfAdderType(descriptor);
    }
}</PRE>

<P>and an element type declaring that it should be instantiated by this
factory like this:</P>
<PRE class="snippet">&lt;extension point=&quot;org.eclipse.gmf.runtime.emf.type.core.elementTypes&quot;&gt;
   &lt;metamodel
         nsURI=&quot;http://www.ibm.com/xtools/1.5.0/logicsemantic&quot;&gt;
      &lt;specializationType
             id=&quot;logic.halfAdder&quot;
             icon=&quot;icons/halfAdder.gif&quot;
             name=&quot;%HalfAdderTool.Label&quot;
             <B>kind=&quot;org.eclipse.gmf.examples.logic.HalfAdderType&quot;&gt; </B>
         &lt;specializes id=&quot;logic.circuit&quot;/&gt;
         &lt;enablement&gt;
            &lt;test 
                property=&quot;org.eclipse.gmf.examples.logic.isHalfAdder&quot; 
                value=&quot;true&quot;/&gt;
         &lt;/enablement&gt;
      &lt;/specializationType&gt;
   &lt;/metamodel&gt;
&lt;/extension&gt;</PRE>



<H3><A name="ex_registry"></A>Using the Element Type Registry</H3>
<P>The element type registry is used to find element types by ID:</P>



<PRE class="snippet">
String logicCircuitID = &quot;logic.circuit&quot;; //$NON-NLS-1$
ElementTypeRegistry registry = ElementTypeRegistry.getInstance();
IElementType logicCircuitType = registry.getType(logicCircuitID);</PRE>
<P>The element type registry is used to find the kinds model objects
that can be contained in a specific feature of a container object:</P>



<PRE class="snippet">
private void fillMenu(Menu menu, EObject container, EReference feature) {

    // fills a menu with items that create model objects in the 
    // specified feature of the container

    IElementType elementType = ElementTypeRegistry.getInstance()
                                                  .getElementType(container);
    IEditHelper editHelper = elementType.getEditHelper();

    List values = editHelper.getContainedValues(container, feature);

    if (values != null) {

        for (Iterator i = values.iterator(); i.hasNext();) {
            Object nextValue = i.next();

            if (nextValue instanceof IElementType) {
                IElementType nextElementType = (IElementType) nextValue;
                CreateElementRequest request = 
                                       new CreateElementRequest(getSelectedElement(), 
                                                                nextElementType, 
                                                                feature);
                ICommand command = elementType.getEditCommand(request);

                if (command != null &amp;&amp; command.isExecutable()) {
                    Action action = new CreateElementAction(command);
                    addActionToMenu(menu, action);
                }
            }
        }
    }
}</PRE>

<P>The element type registry is used to find edit commands:</P>



<PRE class="snippet">
public ICommand getEditCommand(IEditCommandRequest request) {

    ICommand result = null;

    ElementTypeRegistry registry = ElementTypeRegistry.getInstance();
    Object editHelperContext = request.getEditHelperContext();
    IElementType elementType = registry.getElementType(editHelperContext);

    if (elementType != null) {
        result = elementType.getEditCommand(request);
    }

    return result;
}</PRE>
<H3></H3>
<H2><A name="models"></A>Design/Code/Interaction Models</H2>
<P class="backto"><FONT size="2">[<A href="#top">back to top</A>]</FONT></P>
<P>The main part of the extensible type registry API is depicted in the
figure below.</P>
<P><IMG border="1" src="./icons/ETR Class Diagram.gif"></P>
<P><MAP name="ClientContexts">
	<AREA shape="rect" href="#ClientContextManager_api"
		coords="43,1,523,200">
	<AREA shape="rect" target="_blank"
		href="http://help.eclipse.org/help30/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/core/expressions/Expression.html"
		coords="448,514,590,612">
	<AREA shape="rect" href="#IClientContext_api" coords="123,219,450,365">
	<AREA shape="rect" href="#IClientSelector_api" coords="3,398,265,496">
	<AREA shape="default" nohref>
</MAP></P>
<P>The ElementTypeRegistry
is responsible for loading the element types and advice bindings from the <A href="../../../reference/extension-points/org_eclipse_gmf_runtime_emf_type_core_elementTypes.html"><CODE>elementTypes</CODE></A> extension
point, and for filtering the edit helper advice applicable to an object
according to its container descriptor and its matcher criteria.</P>
<P>The sequence diagram below shows how the AbstractEditHelper  uses the <CODE>ElementTypeRegistry</CODE>
to decorate an edit command with advice before and after the default editing behaviour supplied by the edit helper itself. </P>
<P><IMG border="1" src="icons/getEditCommand.gif"></P>
<P>The steps are as follows:</P>
<OL>
	<LI>The edit helper asks the extensible type registry for all element types that apply to a specific edit helper context <CODE>(EObject</CODE> or <CODE>IElementType</CODE>). The registry iterates over the registered edit advice and  tests the container descriptor and matcher of each advice against the edit helper context.</LI>
	<LI>The registry returns all of the advice whose criteria matched the <CODE>EObject</CODE> or <CODE>IElementType</CODE>.</LI>
	<LI>The edit helper constructs a new composite command.</LI>
	<BR>
	The edit helper iterates the advice returned by the
	registry:
	<OL>
		<LI>For each advice, the edit helper asks it for a before command for
		the edit request.</LI>
		<LI>The advice returns a before command, or <CODE>null</CODE> if it
		has no advice to offer for that request.</LI>
		<LI>The edit helper adds the advice to the composite command, if it is not
		<CODE>null</CODE>.</LI>
		<LI>The composite command returns itself.<BR>
		</LI>
	</OL>
	<LI>The edit helper gets the default edit behaviour.</LI>
	<LI>The default edit behaviour is returned. Subclasses will override the default behaviour as required.</LI>
	<LI>The edit helper adds the default edit behaviour to the composite command.</LI>
	<LI>The composite command returns itself.<BR>
	<BR>The edit helper iterates the advice returned by the
	registry:
	<OL>
		<LI>For each advice, the edit helper asks it for an  after command for
		the edit request.</LI>
		<LI>The advice returns an after  command, or <CODE>null</CODE> if it
		has no advice to offer for that request.</LI>
		<LI>The edit helper adds the advice to the composite command, if it is not
		<CODE>null</CODE>.</LI>
		<LI>The composite command returns itself.
		<BR>
		</LI>
	</OL>
	The edit helper returns the composite command. </OL>
<P><MAP name="ClientContextUsage">
</MAP></P>
<P></P><P></P>
<DL>
	<DD></DD>
</DL>
<HR>
</BODY>
</HTML>

Back to the top