File: EMF.html

package info (click to toggle)
eclipse-emf 2.42.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 73,344 kB
  • sloc: java: 711,198; xml: 12,829; makefile: 5
file content (1616 lines) | stat: -rw-r--r-- 67,207 bytes parent folder | download | duplicates (2)
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
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<link rel="stylesheet" href="images/../../../css/book.css" type="text/css"/>
<link rel="stylesheet" href="images/../../../css/emf-book.css" type="text/css"/>
<title>EMF Overview</title>
</head>
<body lang="EN-US" xml:lang="EN-US">
<h1>The Eclipse Modeling Framework (EMF) Overview</h1>
<p>
Last updated: June 16, 2005 (accessibility update)
</p>
<p>
This paper presents a basic overview of EMF and its code generator patterns. For 
a more complete description of all the features of EMF, refer to
<a href="https://www.informit.com/title/9780321331885" target="_blank">EMF: Eclipse Modeling
Framework, Second Edition</a> (Addison-Wesley Professional, 2008) or to the
Javadoc for the framework classes themselves.
</p>

<h2>Contents</h2>
<p><a href="#introduction">Introduction</a><br/>
<a href="#definition">Defining an EMF Model</a><br/>
<a href="#generation">Generating a Java Implementation</a><br/>
<a href="#programming">Using the Generated EMF Classes</a><br/>
<a href="#advanced">Advanced Topics</a></p>

<h2><a name="introduction">Introduction</a></h2>
<p>
EMF is a Java framework and code generation facility for building tools and 
other applications based on a structured model. For those of you that have 
bought into the idea of object-oriented modeling, EMF helps you rapidly turn 
your models into efficient, correct, and easily customizable Java code. For 
those of you that aren't necessarily sold on the value of formal models, EMF is 
intended to provide you with the same benefits and a very low cost of entry.
</p>
<p>
So, what do we mean when we say model? When talking about modeling, we generally 
think about things like Class Diagrams, Collaboration Diagrams, State Diagrams, 
and so on. UML (Unified Modeling Language) defines a (the) standard notation for 
these kinds of diagrams. Using a combination of UML diagrams, a complete model 
of an application can be specified. This model may be used purely for 
documentation or, given appropriate tools, it can be used as the input from 
which to generate part of or, in simple cases, all of an application.
</p>
<p>
Given that this kind of modeling typically requires expensive Object Oriented
Analysis and Design (OOA/D) tools, you might be questioning our assertion,
above, that EMF provides a  low cost of entry. The reason we can say that is
because an EMF model requires just a small subset of the kinds of things that
you can model in UML, specifically simple definitions of the classes and their
attributes and relations, for which a full-scale graphical modeling tool is
unnecessary.
</p>
<p>
While EMF uses XMI (XML Metadata Interchange) as its canonical form of a model
definition<sup><a class="footnote" href="#fn1">[1]</a><a name="ref1">&nbsp;</a></sup>,
you have several ways of getting your model into that form:
</p>
<ul><li>Create the XMI document directly, using an XML or text editor</li>
    <li>Export the XMI document from a modeling tool such as Rational Rose</li>
    <li>Annotate Java interfaces with model properties</li>
    <li>Use XML Schema to describe the form of a serialization of the model</li></ul>
<p>
The first approach is the most direct, but generally only appeals to XML gurus. 
The second choice is the most desirable if you are already using full-scale 
modeling tools. The third approach provides pure Java programmers a low-cost way 
to get the benefits of EMF and its code generator using just a basic Java 
development environment (for example, Eclipse's Java Development Tools). The
last approach is most applicable in creating an application that must read or
write a particular XML file format.
</p>
<p>
Once you specify an EMF model, the EMF generator can create a corresponding set 
of Java implementation classes. You can edit these generated classes to add 
methods and instance variables and still regenerate from the model as needed: 
your additions will be preserved during the regeneration. If the code you added 
depends on something that you changed in the model, you will still need to 
update the code to reflect those changes; otherwise, your code is completely 
unaffected by model changes and regeneration.
</p>
<p>
In addition to simply increasing your productivity, building your application 
using EMF provides several other benefits like model change notification, 
persistence support including default XMI and schema-based XML serialization, a
framework for model validation, and a very efficient reflective API for
manipulating EMF objects generically. Most important of all, EMF provides the
foundation for interoperability with other EMF-based tools and applications.
</p>
<p>
EMF consists of two fundamental frameworks: the core framework and EMF.Edit. The 
core framework provides basic generation and runtime support to create Java 
implementation classes for a model. EMF.Edit extends and builds on the core 
framework, adding support for generating adapter classes that enable viewing 
and command-based (undoable) editing of a model, and even a basic working 
model editor. The following sections describe the main features of the core 
EMF framework. EMF.Edit is described in a separate paper,
<a href="../../references/overview/EMF.Edit.html">EMF.Edit Overview</a>. For instructions on how to run the EMF and EMF.Edit generator,
refer to <a href="../../tutorials/clibmod/clibmod.html">Tutorial: Generating an
EMF Model</a>.
</p>
<h3>EMF Relation to OMG MOF</h3>
<p>
For those of you that are familiar with OMG (Object Management Group) MOF (Meta 
Object Facility), you may be wondering how EMF relates to it. Actually, EMF 
started out as an implementation of the MOF specification but evolved from there 
based on the experience we gained from implementing a large set of tools using 
it. EMF can be thought of as a highly efficient Java implementation of a core 
subset of the MOF API. However, to avoid any confusion, the MOF-like core meta 
model in EMF is called Ecore.
</p>
<p>
In the current proposal for MOF 2.0, a similar subset of the MOF model, which it
calls EMOF (Essential MOF), is separated out. There are small, mostly naming
differences between Ecore and EMOF; however, EMF can transparently read and
write serializations of EMOF.
</p>
<h2><a name="definition">Defining an EMF Model</a></h2>
<p>
To help describe EMF, we'll start by assuming we have a trivial, one-class model 
like this:
</p>
<img src="images/EMF/image001.gif" width="87" height="89" alt="One-class model: Book with title : String and pages : int"/>
<p>
The model shows a single class called Book with two attributes: title of type 
String and pages of type int.
</p>
<p>
Our model definition, trivial as it is, can be provided to the EMF code 
generator in a number of ways.
</p>
<h3>UML</h3>
<p>
If you have a modeling tool that works with
EMF<sup><a class="footnote" href="#fn2">[2]</a><a name="ref2">&nbsp;</a></sup>,
you can simply draw the class diagram as shown above.
</p>
<h3>XMI</h3>
<p>
Alternatively, we could describe the model directly in an XMI document that 
would look something like this:
</p>
<pre>
  &lt;ecore:EPackage xmi:version=&quot;2.0&quot; xmlns:xmi=&quot;http://www.omg.org/XMI&quot;
      xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
      xmlns:ecore=&quot;http://www.eclipse.org/emf/2002/Ecore&quot;
      name=&quot;library &quot;nsURI=&quot;http:///library.ecore&quot; nsPrefix=&quot;library&quot;&gt;
    &lt;eClassifiers xsi:type=&quot;ecore:EClass&quot; name=&quot;Book&quot;&gt;
      &lt;eStructuralFeatures xsi:type=&quot;ecore:EAttribute&quot; name=&quot;title&quot;
          eType=&quot;ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString&quot;/&gt;
      &lt;eStructuralFeatures xsi:type=&quot;ecore:EAttribute&quot; name=&quot;pages&quot;
          eType=&quot;ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt&quot;/&gt;
    &lt;/eClassifiers&gt;
  &lt;/ecore:EPackage&gt;</pre>
<p>
The XMI document contains all the same information as the class diagram, but a 
little less compactly. Every class and attribute in a diagram has a 
corresponding class or attribute definition in the XMI document.
</p>
<h3>Annotated Java</h3>
<p>
For those of you that have neither a graphical modeling tool nor an interest in 
trying to enter all the XMI syntax by hand, a third option is available for 
describing your model. Since the EMF generator is a code-merging generator, 
by providing partial Java interfaces (annotated with model information) 
ahead of time, the generator can use the interfaces as its generation 
metadata and merge the generated code with the rest of the implementation.
</p>
<p>
We could have defined our Book model class in Java like this:
</p>
<pre>
  /**
   * @model
   */
  public interface Book
  {
    /**
     * @model
     */
    String getTitle();

    /**
     * @model
     */
    int getPages();
  }</pre>
<p>
With this approach, we provide all the model information in the form of Java
interfaces with standard get
methods<sup><a class="footnote" href="#fn3">[3]</a><a name="ref3">&nbsp;</a></sup>
to identify the attributes and references. The @model tag is used to identify to
the code generator which interfaces, and parts of those interfaces, correspond
to model elements and therefore require code generation.
</p>
<p>
For our simple example, all of our model information is actually available 
though Java introspection of this interface, so no additional model information 
is needed. In the general case, however, the @model tag may be followed by 
additional details about the model element. If for example, we wanted the pages 
attribute to be read-only (that is, no generation of a set method), we would 
need to add the following to the annotation:
</p>
<pre>
  /**
   * @model changeable=&quot;false&quot;
   */
  int getPages();</pre>
<p>
Because only information that is different from the default needs to be 
specified, annotations can be kept simple and concise.
</p>
<h3>XML Schema</h3>
<p>
Sometimes, you might want to describe a model with a schema that specifies how
instance serializations should look. This can be useful for writing an
application that must use XML to integrate with an existing application or to
comply with a standard. Here is how we would specify a schema that's equivalent
to our simple book model:
</p>
<pre>
  &lt;xsd:schema targetNamespace=&quot;http:///library.ecore&quot;
      xmlns=&quot;http:///library.ecore&quot; xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot;&gt;
    &lt;xsd:complexType name=&quot;Book&quot;&gt;
      &lt;xsd:sequence&gt;
        &lt;xsd:element name=&quot;title&quot; type=&quot;xsd:string&quot;/&gt;
        &lt;xsd:element name=&quot;pages&quot; type=&quot;xsd:integer&quot;/&gt;
      &lt;/xsd:sequence&gt;
    &lt;/xsd:complexType&gt;
  &lt;/xsd:schema&gt;</pre>
<p>
This approach differs somewhat from the other three, mainly because EMF must
apply certain restrictions to the serialization that it eventually uses, to
ensure compliance with the schema. As a result, the model that is a created for
a schema looks slightly different from one specified in one of the other ways.
The details of these differences are beyond the scope of this overview.
</p>
<p>
In the remainder of this paper, we'll use UML diagrams for their clarity and
conciseness. All of the modeling concepts we'll illustrate could also be
expressed using annotated Java or directly with XMI, and most have XML Schema
equivalents. Regardless of how the information is provided, the code generated
by EMF will be the same.
</p>
<h2><a name="generation">Generating a Java Implementation</a></h2>
<p>
For each class in the model, a Java interface and corresponding implementation 
class will be generated. In our example, the generated interface for Book 
looks like this:
</p>
<pre>
  public interface Book extends EObject
  {
    String getTitle();
    void setTitle(String value);

    int getPages();
    void setPages(int value);
  }</pre>
<p>
Each generated interface contains getter and setter methods for each attribute 
and reference of the corresponding model class.
</p>
<p>
Interface Book extends the base interface EObject. EObject is the EMF equivalent 
of java.lang.Object, that is, it is the base of every EMF class. EObject and its 
corresponding implementation class EObjectImpl (which we will look at later) 
provide a relatively lightweight base class that lets Book participate in the 
EMF notification and persistence frameworks. Before we start looking at what 
exactly EObject brings into the mix, let's continue looking at how EMF generates 
Book.
</p>
<p>
Each generated implementation class includes implementations of the getters and 
setters defined in the corresponding interface, plus some other methods required 
by the EMF framework.
</p>
<p>
Class BookImpl will include, among other things, implementations of the title 
and pages accessors. The pages attribute, for example, has the following 
generated implementation:
</p>
<pre>
  public class BookImpl extends EObjectImpl implements Book
  {
    ...
    protected static final int PAGES_EDEFAULT = 0;
    protected int pages = PAGES_EDEFAULT;

    public int getPages()
    {
      return pages;
    }

    public void setPages(int newPages)
    {
      int oldPages = pages;
      pages = newPages;
      if (eNotificationRequired())
        eNotify(new ENotificationImpl(this, Notification.SET, ..., oldPages, pages));
    }

    ...
  }</pre>
<p>
The generated get method is optimally efficient. It simply returns an instance 
variable representing the attribute.
</p>
<p>
The set method, although a little more complicated, is also quite efficient. In 
addition to setting the instance variable pages, the set method needs to send 
change notification to any observers that may be listening to the object by 
calling the eNotify() method. To optimize the case where there are no observers 
(for example, in a batch application), construction of the notification object 
(ENotificationImpl) and the call to eNotify() are guarded by a call to 
eNotificationRequired(). The default implementation of eNotificationRequired() 
simply checks if there are any observers (adapters) attached to the object. 
Therefore, when EMF objects are used without observers, the call to 
eNotificationRequired() amounts to nothing more than an efficient null pointer 
check, which is inlined when using a JIT compiler.
</p>
<p>
The generated accessor patterns for other types of attributes, like the
String-typed title attribute, have some minor differences but are fundamentally
the same as those shown for
pages<sup><a class="footnote" href="#fn4">[4]</a><a name="ref4">&nbsp;</a></sup>.
</p>
<p>
The generated accessors for references, especially two-way ones, are a little 
more complicated and start to show the real value of the EMF generator.
</p>
<h3>One-way references</h3>
<p>
Let's expand our example model with another class Writer that has an association 
with class Book:
</p>
<img src="images/EMF/image002.gif" width="303" height="89" alt="One-way reference: Book has a single author of class Writer, which contains a name : String"/>
<p>
The association between a book and its writer is, in this example, a single 
one-way reference. The reference (role) name used to access the Writer from 
a Book is author.
</p>
<p>
Running this model through the EMF generator will, in addition to generating the 
new interface Writer and implementation class WriterImpl, generate 
additional get and set methods in interface Book:
</p>
<pre>
  Writer getAuthor();
  void setAuthor(Writer value);</pre>
<p>
Since the author reference is one-way, the implementation of the setAuthor() 
method looks much like a simple data setter, like the earlier one for
setPages():
</p>
<pre>
  public void setAuthor(Writer newAuthor)
  {
    Writer oldAuthor = author;
    author = newAuthor;
    if(eNotificationRequired())
      eNotify(new ENotificationImpl(this, ...));
  }</pre>
<p>
The only difference is that here we're setting an object pointer instead of just 
a simple data field.
</p>
<p>
Because we're dealing with an object reference, however, the getAuthor() method
is a little more complicated. This is because the get method for some types of
references, including the type of author, needs to deal with the possibility
that the referenced object (in this case Writer) may persist in a different
resource (document) from the source object (in this case Book). Because the EMF
persistence framework uses a lazy loading scheme, an object pointer (in this
case author) may at some point in time be a proxy for the object, instead of the
actual referenced
object<sup><a class="footnote" href="#fn5">[5]</a><a name="ref5">&nbsp;</a></sup>.
As a result, the getAuthor() method looks like this:
</p>
<pre>
  public Writer getAuthor()
  {
    if (author != null &amp;&amp; author.eIsProxy())
    {
      Writer oldAuthor = author;
      author = (Writer)eResolveProxy((InternalEObject)author);
      if (author != oldAuthor)
      {
        if (eNotificationRequired())
          eNotify(new ENotificationImpl(this, Notification.RESOLVE, ...));
      }
    }
    return author;
  }</pre>
<p>
Instead of simply returning the author instance variable, we first call the 
inherited framework method eIsProxy() method to check if the reference is a
proxy, and then call eResolveProxy() if it is. The latter method calls
EcoreUtil.resolve(), a static utility method that attempts to load the target
object's document, and consequently the object, using the proxy's URI. If
successful, it will return the resolved object. If, however, the document fails
to load, it will just return the proxy
again<sup><a class="footnote" href="#fn6">[6]</a><a name="ref6">&nbsp;</a></sup>.
</p>
<h3>Two-way references</h3>
<p>
Now that we understand how proxy resolution affects the get pattern for certain 
types of references, we can look at how the set pattern changes when an 
association is made two-way. Let's change our one-way author association to 
this:
</p>
<img src="images/EMF/image003.gif" width="303" height="89" alt="Two-way reference: an author may have written 0 or more books, but a book can only have one author"/>
<p>
The association is now two-way, as indicated by the lack of an arrowhead on the 
Writer end of the association line. The role name used to access Books from a 
Writer is books.
</p>
<p>
If we regenerate our model, the getAuthor() method will be unaffected, but 
setAuthor() will now look like this:
</p>
<pre>
  public void setAuthor(Writer newAuthor)
  {
    if (newAuthor != author)
    {
      NotificationChain msgs = null;
      if (author != null)
        msgs = ((InternalEObject)author).eInverseRemove(this, ..., msgs);
      if (newAuthor != null)
        msgs = ((InternalEObject)newAuthor).eInverseAdd(this, ..., msgs);
      msgs = basicSetAuthor(newAuthor, msgs);
      if (msgs != null) msgs.dispatch();
    }
    else if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, ...)); // send &quot;touch&quot; notification
  }</pre>
<p>
As you can see, when setting a two-way reference like author, the other end of
the reference needs to be set as well (by calling eInverseAdd()). We also need
to remove the inverse of any previous author (by calling eInverseRemove())
because in our model the  author reference is singular (that is, a book can only
have one
author)<sup><a class="footnote" href="#fn7">[7]</a><a name="ref7">&nbsp;</a></sup>
and therefore this book cannot be in more than one Writer's books reference.
Finally, we set the author reference by calling another generated method
(basicSetAuthor()) which looks like this:
</p>
<pre>
  public NotificationChain basicSetAuthor(Writer newAuthor, NotificationChain msgs)
  {
    Writer oldAuthor = author;
    author = newAuthor;
    if (eNotificationRequired())
    {
      ENotificationImpl notification = new ENotificationImpl(this, ...);
      if (msgs == null) msgs = notification; else msgs.add(notification);
    }
    return msgs;
  }</pre>
<p>
This method looks very similar to the one-way reference set method, except that
if the msgs argument is non-null, the notification gets added to it, intsead of
being fired
directly<sup><a class="footnote" href="#fn8">[8]</a><a name="ref8">&nbsp;</a></sup>.
Because of all the forward/reverse adding/removing during a two-way reference
set operation, as many as four (three in this particular example) different
notifications may be generated. A NotificationChain is used to collect all these
individual notifications so their firing can be deferred until after all the
state changes have been made. The queued-up notifications are sent by calling
msgs.dispatch(), as shown in the setAuthor() method, above.
</p>
<h3>Multiplicity-many references</h3>
<p>
You may have noticed in our example that the books association (from Writer to 
Book) is multiplicity many (that is, 0..*). In other words, one writer may 
have written many books. Multiplicity-many references (that is, any 
reference where the upper bound is greater than 1) in EMF are manipulated 
using a collection API, so only a get method is generated in the 
interface:
</p>
<pre>
  public interface Writer extends EObject
  {
    ...
    EList getBooks();
  }</pre>
<p>
Notice that getBooks() returns an EList as opposed to a  java.util.List. 
Actually, they are almost the same. EList is an EMF subclass of 
java.util.List that adds two move methods to the API. Other than that, from 
a client perspective, you can consider it a standard Java List. For 
example, to add a book to the books association, you can simply call:
</p>
<pre>
  aWriter.getBooks().add(aBook);</pre>
<p>
or to iterate over them you would do something like this:
</p>
<pre>
  for (Iterator iter = aWriter.getBooks().iterator(); iter.hasNext(); )
  {
    Book book = (Book)iter.next();
    ...
  }</pre>
<p>
As you can see, from a client perspective, the API for manipulating 
multiplicity-many references is nothing special. However, because the books 
reference is part of a two-way association (it's the inverse of Book.author),  
we still need to do all the fancy inverse handshaking that we showed for the 
setAuthor() method. Looking at the implementation of the getBooks() method in 
WriterImpl shows us how the multiplicity-many case gets handled:
</p>
<pre>
  public EList getBooks()
  {
    if (books == null)
    {
      books = new EObjectWithInverseResolvingEList(Book.class, this,
                    LibraryPackage.WRITER__BOOKS, LibraryPackage.BOOK__AUTHOR);
    }
    return books;
  }</pre>
<p>
The getBooks() method returns a special implementation class,
EObjectWithInverseResolvingEList, which is constructed with all the information
it needs to do the reverse handshaking during add and remove calls. EMF actually
provides 20 different specialized EList
implementations<sup><a class="footnote" href="#fn9">[9]</a><a name="ref9">&nbsp;</a></sup>
to efficiently implement all types of multiplicity-many features.
For one-way associations (that is, those with no inverse) we use
EObjectResolvingEList. If the reference doesn't need proxy resolution we'd use
EObjectWithInverseEList or EObjectEList, and so on.
</p>
<p>
So for our example, the list used to implement the books reference is created 
with the argument LibraryPackage.BOOK__AUTHOR (a generated static int constant 
representing the reverse feature). This will be used during the add() call to 
call eInverseAdd() on the Book, similar to the way eInverseAdd() was called on 
the Writer during setAuthor(). Here's what eInverseAdd() looks like in class 
BookImpl:
</p>
<pre>
  public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID,
                                       Class baseClass, NotificationChain msgs)
  {
    if (featureID >= 0)
    {
      switch (eDerivedStructuralFeatureID(featureID, baseClass))
      {
        case LibraryPackage.BOOK__AUTHOR:
          if (author != null)
            msgs = ((InternalEObject)author).eInverseRemove(this, .., msgs);
          return basicSetAuthor((Writer)otherEnd, msgs);
        default:
          ...
      }
    }
    ...
  }</pre>
<p>
It first calls eInverseRemove() to remove any previous author (as we described
previously when we looked at the setAuthor() method), and then it calls
basicSetAuthor() to actually set the reference. Although our particular example
only has one two-way reference, eInverseAdd() uses a switch statement that
includes a case for every two-way reference available on class
Book<sup><a class="footnote" href="#fn10">[10]</a><a name="ref10">&nbsp;</a></sup>.
</p>
<h3><a name="containment">Containment references</a></h3>
<p>
Let's add a new class, Library, which will act as the container for Books.
</p>
<img src="images/EMF/image004.gif" width="308" height="89" alt="Containment reference: a Library contains 0 or more books"/>
<p>
The containment reference is indicated by the black diamond on the Library end 
of the association. In full, the association indicates that a Library 
aggregates, by value, 0 or more Books. By-value aggregation (containment) 
associations are particularly important because they identify the parent or 
owner of a target instance, which implies the physical location of the object 
when persisted.
</p>
<p>
Containment affects the generated code in several ways. First of all, because a 
contained object is guaranteed to be in the same resource as its container, 
proxy resolution isn't needed. Therefore, the generated get method in
LibraryImpl will use a non-resolving EList implementation class:
</p>
<pre>
  public EList getBooks()
  {
    if (books == null)
    {
      books = new EObjectContainmentEList(Book.class, this, ...);
    }
    return books;
  }</pre>
<p>
In addition to not performing proxy resolution, an EObjectContainmentEList also 
implements the contains() operation very efficiently (that is, in a constant 
time, vs. linear time in the general case). This is particularly important
because duplicate entries are not allowed in EMF reference lists, so contains()
is called during add() operations as well.
</p>
<p>
Because an object can only have one container, adding an object to a containment
association also means removing the object from any container it's currently in,
regardless of the actual association. For example, adding a Book to a Library's
books list may involve removing it from some other Library's books list. That's
no different than any other two-way association where the inverse has
multiplicity 1. Let's assume, however, that the Writer class also had a
containment association to Book, called ownedBooks.  Then, if a given book
instance is in the ownedBooks list of some Writer, when we add it to a Library's
books reference, it would need to be removed from the Writer first.
</p>
<p>
To implement this kind of thing efficiently, the base class EObjectImpl has an 
instance variable (eContainer) of type EObject that it uses to store the 
container generically. As a result, containment references are always 
implicitly two-way. To access the Library from a Book, you can write something 
like this:
</p>
<pre>
  EObject container = book.eContainer();
  if (container instanceof Library)
    library = (Library)container;</pre>
<p>
If you want to avoid the downcast, you can change the association to be 
explicitly two-way instead:
</p>
<img src="images/EMF/image005.gif" width="308" height="89" alt="Two-way containment reference: a Library contains 0 or more books; books are contained by a Library"/>
<p>
and let EMF generate a nice typesafe get method for you:
</p>
<pre>
  public Library getLibrary()
  {
    if (eContainerFeatureID != LibraryPackage.BOOK__LIBRARY) return null;
    return (Library)eContainer;
  }</pre>
<p>
Notice that the explicit get method uses the eContainer variable from 
EObjectImpl instead of a generated instance variable as we saw previously 
for non-container references (like getAuthor(),
above)<sup><a class="footnote" href="#fn11">[11]</a><a name="ref11">&nbsp;</a></sup>.
</p>
<h3>Enumeration attributes</h3>
<p>
So far, we've looked at how EMF handles simple attributes and various types of
references. Another commonly used type of attribute is an enumeration.
Enumeration-type attributes are implemented using the Java typesafe enum
pattern<sup><a class="footnote" href="#fn12">[12]</a><a name="ref12">&nbsp;</a></sup>.
</p>
<p>
If we add an enumeration attribute, category, to class Book:
</p>
<img src="images/EMF/image006.gif" width="354" height="108" alt="Enumeration attribute and definition: Book has a category of class BookCategory, which is an enumeration of Mystery, ScienceFiction, and Biography"/>
<p>
and regenerate the implementation classes, interface Book will now include a 
getter and setter for category:
</p>
<pre>
  BookCategory getCategory();
  void setCategory(BookCategory value);</pre>
<p>
In the generated interface, the category methods use a typesafe enumeration
class called BookCategory. This class defines static constants for the
enumeration's values and other convenience methods, like this:
</p>
<pre>
  public final class BookCategory extends AbstractEnumerator
  {
    public static final int MYSTERY = 0;
    public static final int SCIENCE_FICTION = 1;
    public static final int BIOGRAPHY = 2;

    public static final BookCategory MYSTERY_LITERAL =
      new BookCategory(MYSTERY, &quot;Mystery&quot;);
    public static final BookCategory SCIENCE_FICTION_LITERAL =
      new BookCategory(SCIENCE_FICTION, &quot;ScienceFiction&quot;);
    public static final BookCategory BIOGRAPHY_LITERAL =
      new BookCategory(BIOGRAPHY, &quot;Biography&quot;);
  
    public static final List VALUES = Collections.unmodifiableList(...));

    public static BookCategory get(String name)
    {
      ...
    }

    public static BookCategory get(int value)
    {
      ...
    }
  
    private BookCategory(int value, String name)
    {
      super(value, name);
    }
  }</pre>
<p>
As shown, the enumeration class provides static int constants for the 
enumerations's values as well as static constants for the enumeration's
singleton literal objects themselves. The int constants have the same names as
the model's literal names<sup><a class="footnote" href="#fn13">[13]</a><a name="ref13">&nbsp;</a></sup>.
The literal constants have the same names with _LITERAL appended.
</p>
<p>
The constants provide convenient access to the literals when, for example, 
setting the category of a book:
</p>
<pre>
  book.setCategory(BookCategory.SCIENCE_FICTION_LITERAL);</pre>
<p>
The BookCategory constructor is private and therefore the only instances of the 
enumeration class that will ever exist are the ones used for the statics 
MYSTERY_LITERAL, SCIENCE_FICTION_LITERAL, and BIOGRAPHY_LITERAL. As a result, 
equality comparisons (that is .equals() calls) are never needed. Literals can 
always be reliably compared using the simpler and more efficient == operator, 
like this:
</p>
<pre>
  book.getCategory() == BookCategory.MYSTERY_LITERAL</pre>
<p>
When comparing against many values, a switch statement using the int values is 
better yet:
</p>
<pre>
  switch (book.getCategory().value()) {
    case BookCategory.MYSTERY:
      // do something ...
      break;
    case BookCategory.SCIENCE_FICTION:
      ...
  }</pre>
<p>
For situations where only the literal name (String) or value (int) is available,
convenience get() methods, which can be used to retrieve the corresponding
literal object, are also generated in the enumeration class.
</p>
<h3>Factories and packages</h3>
<p>
In addition to the model interfaces and implementation classes, EMF generates 
at least two more interfaces (and implementation classes): a factory and a
package.
</p>
<p>
The factory, as its name implies, is used for creating instances of your model
classes, while the package provides some static constants (for example, the
feature constants used by the generated methods) and convenience methods for
accessing your model's
metadata<sup><a class="footnote" href="#fn14">[14]</a><a name="ref14">&nbsp;</a></sup>.
</p>
<p>
Here is the factory interface for the book example:
</p>
<pre>
  public interface LibraryFactory extends EFactory
  {
    LibraryFactory eINSTANCE = new LibraryFactoryImpl();

    Book createBook();
    Writer createWriter();
    Library createLibrary();

    LibraryPackage getLibraryPackage();
  }</pre>
<p>
As shown, the generated factory provides a factory method (create) for each 
class defined in the model, an accessor for your model's package, and a static 
constant reference (that is, eINSTANCE) to the factory singleton.
</p>
<p>
The LibraryPackage interface provides convenient access to all the metadata of 
our model:
</p>
<pre>
  public interface LibraryPackage extends EPackage
  {
    ...
    LibraryPackage eINSTANCE = LibraryPackageImpl.init();
    
    static final int BOOK = 0;
    static final int BOOK__TITLE = 0;
    static final int BOOK__PAGES = 1;
    static final int BOOK__CATEGORY = 2;
    static final int BOOK__AUTHOR = 3;
    ...
    
    static final int WRITER = 1;
    static final int WRITER__NAME = 0;
    ...
    
    EClass getBook();
    EAttribute getBook_Title();
    EAttribute getBook_Pages();
    EAttribute getBook_Category();
    EReference getBook_Author();

    ...
  }</pre>
<p>
As you can see, the metadata is available in two forms: int constants and the 
Ecore meta objects themselves. The int constants provide the most efficient way 
to pass around meta information. You may have noticed that the generated methods 
use these constants in their implementations. Later, when we look at how EMF 
adapters can be implemented, you'll see that the constants also provide the most 
efficient way to determine what has changed when handling notifications. Also,
just like the factory, the generated package interface provides a static
constant reference to its singleton implementation.
</p>
<h3>Generating classes with super classes</h3>
<p>
Let's say we want to create a subclass, SchoolBook, of our Book model class,
like this:
</p>
<img src="images/EMF/image007.gif" width="164" height="198" alt="Single inheritance: a SchoolBook extends Book"/>
<p>
The EMF generator handles single inheritance as you'd expect: the generated 
interface extends the super interface:
</p>
<pre>
  public interface SchoolBook extends Book</pre>
<p>
and the implementation class extends the super implementation class:
</p>
<pre>
  public class SchoolBookImpl extends BookImpl implements SchoolBook</pre>
<p>
As in Java itself, multiple interface inheritance is supported, but each EMF 
class can only extend one implementation base class. Therefore, when we have a 
model with multiple inheritance, we need to identify which of the multiple bases 
should be used as the implementation base class. The others will then be simply 
treated as mixin interfaces, with their implementations generated into the 
derived implementation class.
</p>
<p>
Consider the following example:
</p>
<img src="images/EMF/image008.gif" width="284" height="213" alt="Multiple inheritance: a SchoolBook extends Book and Asset (Asset has a value : float)"/>
<p>
Here we've made SchoolBook derive from two classes: Book and Asset. We've
identified Book as the implementation base (extended) class as
shown<sup><a class="footnote" href="#fn15">[15]</a><a name="ref15">&nbsp;</a></sup>.
If we regenerate the model, interface SchoolBook will now extend the two
interfaces:
</p>
<pre>
  public interface SchoolBook extends Book, Asset</pre>
<p>
The implementation class looks the same as before, only now it includes 
implementations of the mixed-in methods getValue() and setValue():
</p>
<pre>
  public class SchoolBookImpl extends BookImpl implements SchoolBook
  {
    public float getValue()
    {
      ...
    }

    public void setValue(float newValue)
    {
      ...
    }
    
    ...
  }</pre>
<h3>Customizing the generated implementation classes</h3>
<p>
You can add behavior (methods and instance variables) to the generated Java 
classes without having to worry about losing your changes if you later decide to 
modify the model and then regenerate. For example, let's add a method, 
isRecommended(), to class Book. To do this you simply go ahead and add the new 
method signature to the Java interface Book:
</p>
<pre>
  public interface Book ...
  {
    boolean isRecommended();
    ...
  }</pre>
<p>
and its implementation in class BookImpl:
</p>
<pre>
  public boolean isRecommended()
  {
    return getAuthor().getName().equals(&quot;William Shakespeare&quot;);
  }</pre>
<p>
The EMF generator won't wipe out this change because it isn't a generated method 
to begin with.  Every method generated by EMF includes a Javadoc comment that 
contains an @generated tag, like this:
</p>
<pre>
  /**
   * ...
   * @generated
   */
  public String getTitle()
  {
    return title;
  }</pre>
<p>
Any method in the file that doesn't contain this tag (like isRecommended()) will
be left untouched whenever we regenerate. In fact, if we want to change the
implementation of a generated method, we can do that by removing the @generated
tag from
it<sup><a class="footnote" href="#fn16">[16]</a><a name="ref16">&nbsp;</a></sup>:
</p>
<pre>
  /**
   * ...
   * <strike>@generated</strike> // (removed)
   */
  public String getTitle()
  {
    // our custom implementation ...
  }</pre>
<p>
Now, because of the missing @generated tag, the getTitle() method is considered 
to be user code; if we regenerate the model, the generator will detect the 
collision and simply discard the generated version of the method.
</p>
<p>
Actually, before discarding a generated method, the generator first checks if 
there is another generated method in the file with the same name, but with Gen 
appended. If it finds one, then instead of discarding the newly generated 
version of the method it redirects the output to it. For example, if we want to 
extend the generated getTitle() implementation, instead of completely discarding 
it, then we can do that by simply renaming it like this:
</p>
<pre>
  /**
   * ...
   * @generated
   */
  public String getTitleGen()
  {
    return title;
  }</pre>
<p>
and then adding our override as a user method that does whatever we want:
</p>
<pre>
  public String getTitle()
  {
    String result = getTitleGen();
    if (result == null)
      result = ...
    return result;
  }</pre>
<p>
If we regenerate now, the generator will detect the collision with our user 
version of getTitle(), but because we also have the @generated getTitleGen() 
method in the class, it will redirect the newly generated implementation to it, 
instead of discarding it.
</p>
<h3>Operations in EMF models</h3>
<p>
In addition to attributes and references, you can add operations to your model
classes. If you do, the EMF generator will generate their signature into the
interface and a method skeleton into the implementation class. EMF does not
model behavior, so the implementation must be provided by user-written Java
code.
</p>
<p>
This may be done by removing the @generated tag from the generated
implementation, as described above, and adding the code right there.
Alternatively, the Java code can be included right in the model. In Rose, you
can enter it in the text box on the Semantics tab of an Operation Specification
dialog.  The code will then be stored in the EMF model as an annotation on the
operation<sup><a class="footnote" href="#fn17">[17]</a><a name="ref17">&nbsp;</a></sup>,
and will be generated into its body.
</p>
<h2><a name="programming">Using the Generated EMF Classes</a></h2>
<h3>Creating and accessing instances</h3>
<p>
Using the generated classes, a client program can create and initialize a Book 
with the following simple Java statements:
</p>
<pre>
  LibraryFactory factory = LibraryFactory.eINSTANCE;

  Book book = factory.createBook();

  Writer writer = factory.createWriter();
  writer.setName(&quot;William Shakespeare&quot;);

  book.setTitle(&quot;King Lear&quot;);
  book.setAuthor(writer);</pre>
<p>
Because the Book to Writer association (author) is two-way, the inverse 
reference (books) is automatically initialized. We can verify this by iterating 
over the books reference like this:
</p>
<pre>
  System.out.println(&quot;Shakespeare books:&quot;);
  for (Iterator iter = writer.getBooks().iterator(); iter.hasNext(); )
  {
    Book shakespeareBook = (Book)iter.next();
    System.out.println(&quot;  title: &quot; + shakespeareBook.getTitle());
  }</pre>
<p>
Running this program would produce output something like this:
</p>
<pre>
  Shakespeare books:
    title: King Lear</pre>
<h3>Saving and loading resources</h3>
<p>
To create a document named mylibrary.xmi containing the above model, all we need
to do is create an EMF resource at the beginning of the program, put the book
and writer into the resource, and call save() at the end:
</p>
<pre>
  // Create a resource set.
  ResourceSet resourceSet = new ResourceSetImpl();

  // Register the default resource factory -- only needed for stand-alone!
  resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put(
    Resource.Factory.Registry.DEFAULT_EXTENSION, new XMIResourceFactoryImpl());

  // Get the URI of the model file.
  URI fileURI = URI.createFileURI(new File(&quot;mylibrary.xmi&quot;).getAbsolutePath());

  // Create a resource for this file.
  Resource resource = resourceSet.createResource(fileURI);

  // Add the book and writer objects to the contents.
  resource.getContents().add(book);
  resource.getContents().add(writer);

  // Save the contents of the resource to the file system.
  try
  {
    resource.save(Collections.EMPTY_MAP);
  }
  catch (IOException e) {}</pre>
<p>
Notice that a resource set (interface ResourceSet) is used to create the EMF 
resource. A resource set is used by the EMF framework to manage resources that
may have cross document references. Using a registry (interface
Resource.Factory.Registry), it creates the right type of resource for a given 
URI based on its scheme, file extension, or other possible criteria. Here,
we register the XMI resource implementation as the default for this resource
set<sup><a class="footnote" href="#fn18">[18]</a><a name="ref18">&nbsp;</a></sup>.
During load, the resource set also manages the demand-loading of cross document
references.
</p>
<p>
Running this program will produce the file mylibrary.xmi with contents something 
like this:
</p>
<pre>
  &lt;xmi:XMI xmi:version=&quot;2.0&quot; xmlns:xmi=&quot;http://www.omg.org/XMI&quot;
      xmlns:library=&quot;http:///library.ecore&quot;&gt;
    &lt;library:Book title=&quot;King Lear&quot; author=&quot;/1&quot;/&gt;
    &lt;library:Writer name=&quot;William Shakespeare&quot; books=&quot;/0&quot;/&gt;
  &lt;/xmi:XMI&gt;</pre>
<p>
To load the document mylibrary.xmi, as saved above, we set up a resource set,
and then simply demand-load the resource into it, as follows:
</p>
<pre>
   // Create a resource set.
   ResourceSet resourceSet = new ResourceSetImpl();

  // Register the default resource factory -- only needed for stand-alone!
  resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put(
    Resource.Factory.Registry.DEFAULT_EXTENSION, new XMIResourceFactoryImpl());

  // Register the package -- only needed for stand-alone!
  LibraryPackage libraryPackage = LibraryPackage.eINSTANCE;

   // Get the URI of the model file.
   URI fileURI = URI.createFileURI(new File("mylibrary.xmi").getAbsolutePath());

   // Demand load the resource for this file.
   Resource resource = resourceSet.getResource(fileURI, true);

   // Print the contents of the resource to System.out.
   try
   {
     resource.save(System.out, Collections.EMPTY_MAP);
   }
   catch (IOException e) {}</pre>

<p>
Again, we create a resource set and, for the stand-alone case, register a
default resource implementation. Also, we need to ensure that our package is
registered in the package registry, which the resource uses to obtain the
appropriate metadata and factory for the model it is loading. Simply
accessing the eINSTANCE field of a generated package interface is sufficient
to ensure that it is registered.
</p>
<p>
This example uses the second form of save(), which takes an OutputStream, to
print the serialization to the console.
</p>
<p>
Splitting a model into multiple documents, with cross references between them,
is simple. If we wanted to serialize the books and writers, in the save example
above, into separate documents, all we need to do is create a second resource:
</p>
<pre>
  Resource anotherResource = resourceSet.createResource(anotherFileURI);</pre>
<p>
and add the writer to it, instead of the first:
</p>
<pre>
  <strike>resource.getContents().add(writer);</strike> // (replaced)
  anotherResource.getContents().add(writer);</pre>
<p>
This would produce two resources, each containing one object, with a cross
document reference to the other.
</p>
<p>
Note that a containment reference necessarily implies that the contained object
is in the same resource as its container. So, for example, suppose that we had
created an instance of Library containing our Book via the books containment
reference. That would have automatically removed the Book from the contents of
the resource, which in this sense, also behaves like a containment reference.
If we then added the Library to the resource, the book would implicitly belong
to the resource as well, and its details would again be serialized in it.
</p>
<p>
If you want to serialize your objects in a format other than XMI, that can be
arranged as well. You will need to supply your own serialization and parsing
code. Create your own resource class (as a subclass of ResourceImpl) that
implements your preferred serialization format, and then either register it
locally with your resource set, or with the global factory registry if you want
it to always be used with your model.
</p>
<h3>Observing (adapting) EMF objects</h3>
<p>
Previously, when we looked at set methods in generated EMF classes, we saw that 
notifications are always sent when an attribute or reference is changed. For
example, the BookImpl.setPages() method included the following line:
</p>
<pre>
  eNotify(newENotificationImpl(this, ..., oldPages, pages));</pre>
<p>
Every EObject can maintain a list of observers (also referred to as adapters),
which will be notified whenever a state change occurs. The framework eNotify()
method iterates through this list and forwards the notification to the
observers.
</p>
<p>
An observer can be attached to any EObject (for example, book) by adding to the 
eAdapters list like this:
</p>
<pre>
  Adapter bookObserver = ...
  book.eAdapters().add(bookObserver);</pre>
<p>
More commonly, however, adapters are added to EObjects using an adapter factory. 
In addition to their observer role, adapters are more generally used as a way
to extend the behavior of the object they're attached to. A client generally
attaches such extended behavior by asking an
adapter factory to adapt an object with an extension of the required type. 
Typically it looks something like this:
</p>
<pre>
  EObject someObject = ...;
  AdapterFactory someAdapterFactory = ...;
  Object requiredType = ...;
  if(someAdapterFactory.isFactoryForType(requiredType))
  {
    Adapter theAdapter = someAdapterFactory.adapt(someObject, requiredType);
    ...
  }</pre>
<p>
Usually, the requiredType represents some interface supported by the adapter. 
For example, the argument might be the actual java.lang.Class for an interface 
of the chosen adapter. The returned adapter could then be downcast to the 
requested interface like this:
</p>
<pre>
  MyAdapter theAdapter =
    (MyAdapter)someAdapterFactory.adapt(someObject, MyAdapter.class);</pre>
<p>
Adapters are often used this way to extend the behavior of an object without 
subclassing.
</p>
<p>
To handle notifications in an adapter we need to override the eNotifyChanged()
method, which is called on every registered adapter by eNotify(). A typical
adapter implements eNotifyChanged() to perform some action for some or all of
the notifications, based on the notification's type.
</p>
<p>
Sometimes adapters are designed to adapt a specific class (for example, Book). 
In this case, the notifyChanged() method might look something like this:
</p>
<pre>
  public void notifyChanged(Notification notification)
  {
    Book book = (Book)notification.getNotifier();
    switch (notification.getFeatureID(Book.class))
    {
      case LibraryPackage.BOOK__TITLE:
        // book title changed
        doSomething();
        break;
      caseLibraryPackage.BOOK__CATEGORY:
        // book category changed
        ...
      case ...
    }
  }</pre>
<p>
The call to notification.getFeatureID() is passed the argument Book.class to
handle the possibility that the object being adapted is not an instance of
class BookImpl, but is instead an instance of a multiple-inheritance subclass
where Book is not the primary (first) interface. In that case, the feature ID
passed in the notification will be a number relative to the other class and
therefore needs to be adjusted before we can switch using the BOOK__ constants.
In single-inheritance situations, this argument is ignored.
</p>
<p>
Another common type of adapter is not bound to any specific class, but instead
uses the reflective EMF API to perform its function. Instead of calling
getFeatureID() on the notification, it might call getFeature() instead, which
returns the actual Ecore feature (that is, the object in the metamodel that
represents the feature).
</p>
<h3>Using the reflective API</h3>
<p>
Every generated model class can also be manipulated using the reflective API 
defined in interface EObject:
</p>
<pre>
  public interface EObject ...
  {
    ..
    Object eGet(EStructuralFeature feature);
    void eSet(EStructuralFeature feature, Object newValue);

    boolean eIsSet(EStructuralFeature feature);
    void eUnset(EStructuralFeature feature);
  }</pre>
<p>
Using the reflective API, we could set the name of an author like this:
</p>
<pre>
  writer.eSet(LibraryPackage.eINSTANCE.getWriter_Name(), &quot;William Shakespeare&quot;);</pre>
<p>
or get the name like this:
</p>
<pre>
  String name = (String)writer.eGet(LibraryPackage.eINSTANCE.getWriter_Name());</pre>
<p>
Notice that the feature being accessed is identified by metadata obtained from
the singleton instance of the library package.
</p>
<p>
Using the reflective API is slightly less efficient then calling the generated
getName() and setName() methods
directly<sup><a class="footnote" href="#fn19">[19]</a><a name="ref19">&nbsp;</a></sup>,
but opens up the model for completely generic access. For example, the
reflective methods are used by the EMF.Edit framework to implement a full set of
generic commands (for example, AddCommand, RemoveCommand, SetCommand) that can
be used with any model. See the <a href="../../references/overview/EMF.Edit.html">EMF.Edit
Overview</a> for details.
</p>
<p>
In addition to eGet() and eSet(), the reflective API includes two other related
methods: eIsSet() and eUnset(). The eIsSet() method can be used to find out if
an attribute is set or
not<sup><a class="footnote" href="#fn20">[20]</a><a name="ref20">&nbsp;</a></sup>,
while eUnset() can be used to unset (or reset) it. The generic XMI serializer,
for example, uses eIsSet() to determine which attributes need to be serialized
during a resource save operation.
</p>
<h2><a name="advanced">Advanced Topics</a></h2>
<h3><a name="flags">Generation control flags</a></h3>
<p>
There are several flags that can be set on a model feature to control the 
generated code pattern for that feature. Typically, the default settings of 
these flags will be fine, so you shouldn't need to change them very often.
</p>
<ul>
<li><p><strong>Unsettable</strong> (default is false)</p>
<p>
A feature that is declared to be unsettable has a notion of an explicit unset or
no-value state. For example, a boolean attribute that is not unsettable can take
on one of two values: true or false. If, instead, the attribute is declared to
be unsettable, it can then have any of three values: true, false, or unset.
</p>
<p>
The get method on a feature that is not set will return its default value, but
for an unsettable feature, there is a distinction between this state and when
the feature has been explicitly set to the default value. Since the unset state
is outside of the set of allowed values, we need to generate additional methods
to put a feature in the unset state and to determine if it is in that state. For
example, if the pages attribute in class Book is declared to be unsettable, then
we'll get two more generated methods:
</p>
<pre>
  boolean isSetPages();
  void unsetPages();</pre>
<p>
in addition to the original two:
</p>
<pre>
  int getPages();
  void setPages(int value);</pre>
<p>
The isSet method returns true if the feature has been explicitly set. The unset
method changes an attribute that has been set back to its unset state.
</p>
<p>
When unsettable is false, we don't get the generated isSet or unset methods, but
we still get implementations of the reflective versions: eIsSet() and eUnset()
(which every EObject must implement). For non-unsettable attributes, eIsSet()
returns true if the current value is different from the default value, and
eUnset() sets the feature to the default value (more like a reset).
</p>
</li>
<li><p><strong>ResolveProxies</strong> (default is true)</p>
<p>
ResolveProxies only applies to non-containment references. ResolveProxies
implies that the reference may span documents, and therefore needs to
include proxy checking and resolution in the get method, as described earlier
in this paper.
</p>
<p>
You can optimize the generated get pattern for references that you know will
never be used in a cross document scenario by setting resolveProxies to false.
In that case, the generated get method will be optimally
efficient<sup><a class="footnote" href="#fn21">[21]</a><a name="ref21">&nbsp;</a></sup>.
</p>
</li>
<li><p><strong>Unique</strong> (default is true)</p>
<p>
Unique only applies to multiplicity-many attributes, indicating that such an
attribute may not contain multiple equal objects. References are always treated
as unique.
</p>
</li>
<li><p><strong>Changeable</strong> (default is true)</p>
<p>
A feature that is not changeable will not include a generated set method, and
the reflective eSet() method will throw an exception if you try to set it.
Declaring one end of a bi-directional relationship to be not changeable is a
good way to force clients to always set the reference from the other end, but
still provide convenient navigation methods from either end. Declaring one-way
references or attributes to be not changeable usually implies that the feature
will be set or changed by some other (user-written) code.
</p>
</li>
<li><p><strong>Volatile</strong> (default is false)</p>
<p>
A feature that is declared volatile is generated without storage fields and with
empty implementation method bodies, which you are required to fill in. Volatile
is commonly used for a feature whose value is derived from some other feature,
or for a feature that is to be implemented by hand using a different storage
and implementation pattern.
</p>
</li>
<li><p><strong>Derived</strong> (default is false)</p>
<p>
The value of a derived feature is computed from other features, so it doesn't
represent any additional object state. Framework classes, such as
EcoreUtil.Copier, that copy model objects will not attempt to copy such
features. The generated code is unaffected by the value of the derived flag,
except for the package implementation class, which initializes the metadata for
the model. Derived features are typically also marked volatile and transient.
</p>
</li>
<li><p><strong>Transient</strong> (default is false)</p>
<p>
Transient features are used to declare (modeled) data whose lifetime never spans 
application invocations and therefore doesn't need to be persisted. The (default 
XMI) serializer will not save features that are declared to be transient. Like
derived, transient's only effect on the generated code is the metadata
initialization in the package implementation class.
</p>
</li>
</ul>

<h3>Data types</h3>
<p>
As mentioned previously, all the classes defined in a model (for example, Book, 
Writer) implicitly derive from the EMF base class EObject. However, all the 
classes that a model uses are not necessarily EObjects. For example, assume we 
want to add an attribute of type java.util.Date to our model. Before we can do 
so, we need to define an EMF DataType to represent the external type. In UML, we 
use a class with the datatype stereotype for this purpose:
</p>
<img src="images/EMF/image009.gif" width="183" height="75" alt="Data type definition: datatype JavaDate is of javaclass java.util.Date"/>
<p>
As shown, a data type is simply a named element in the model that acts as a
proxy for some Java class. The actual Java class is provided as an attribute
with the javaclass stereotype, whose name is the fully qualified class being
represented. With this data type defined, we  can now declare attributes of type
java.util.Date like this:
</p>
<img src="images/EMF/image010.gif" width="173" height="122" alt="Attribute with data type as attribute type: Book has a publicationDate : JavaDate"/>
<p>
If we regenerate, the publicationDate attribute will now appear in the Book
interface:
</p>
<pre>
  import java.util.Date;

  public interface Book extends EObject
  {
    ...

    Date getPublicationDate();
    void setPublicationDate(Date value);
  }</pre>
<p>
As you can see, this Date-typed attribute is handled pretty much like any other.
In fact, all attributes, including ones of type String, int, and so on, have a
data type as their type. The only thing special about the standard Java types is
that their corresponding data types are predefined in the Ecore model, so they
don't need to be redefined in every model that uses them.
</p>
<p>
A data type definition has one other effect on the generated model. Since data 
types represent some arbitrary class, a generic serializer and parser (for
example, the default XMI serializer) has no way of knowing how to save the state
of an attribute of that type. Should it call toString()? That's a reasonable
default, but the EMF framework doesn't want to require that, so it generates two
more methods in the factory implementation class for every data type defined in
the model:
</p>
<pre>
  /**
   * @generated
   */
  public Date createJavaDateFromString(EDataType eDataType, String initialValue)
  {
    return (Date)super.createFromString(eDataType, initialValue);
  }

  /**
   * @generated
   */
  public String convertJavaDateToString(EDataType eDataType, Object instanceValue)
  {
    return super.convertToString(eDataType, instanceValue);
  }</pre>
<p>
By default, these methods simply invoke the superclass implementations, which
provide reasonable, but inefficient, defaults: convertToString() simply calls
toString() on the instanceValue, but createFromString() tries, using Java
reflection, to call a String constructor or, failing that, a static valueOf()
method, if one exists.  Typically you should take over these methods (by
removing the @generated tags) and change them to appropriate custom
implementations:
</p>
<pre>
  /**
   * <strike>@generated</strike> // (removed)
   */
  public String convertJavaDateToString(EDataType eDataType, Object instanceValue)
  {
    return instanceValue.toString();
  )</pre>
<h3>Ecore Model</h3>
<p>
Here is the complete class hierarchy of the Ecore model (shaded boxes are
abstract classes):
</p>
<img src="images/EMF/image011.gif" width="611" height="456" alt="Ecore class hierarchy"/>
<p>
This hierarchy includes the classes that represent the EMF model elements 
described in this paper: classes (and their attributes, references and 
operations) data types, enumerations, packages and factories.
</p>
<p>
EMF's implementation of Ecore is itself generated using the EMF generator and as
such has the same lightweight and efficient implementation as described in the
previous sections of this paper.
</p>
<br/><hr noshade="noshade" size="1"/>
<p>
<sup><a class="footnote" href="#ref1">[1]</a><a name="fn1">&nbsp;</a></sup>Actually,
the EMF meta model is itself an EMF model, the default serialized form of which
is XMI.</p>
<p>
<sup><a class="footnote" href="#ref2">[2]</a><a name="fn2">&nbsp;</a></sup>Currently,
EMF supports import from Rational Rose, but the generator architecture can
easily accommodate other modeling tools as well.
</p>
<p>
<sup><a class="footnote" href="#ref3">[3]</a><a name="fn3">&nbsp;</a></sup>EMF
uses a subset of the JavaBean simple property accessor naming patterns.
</p>
<p>
<sup><a class="footnote" href="#ref4">[4]</a><a name="fn4">&nbsp;</a></sup>There
are several user-specifiable options that can be used to change the generated
patterns. We'll describe some of them later (see
<a href="#flags">Generation control flags</a>, later in this document).
</p>
<p>
<sup><a class="footnote" href="#ref5">[5]</a><a name="fn5">&nbsp;</a></sup>Containment
references, which we'll describe later (see <a href="#containment">Containment
references</a>), cannot span documents. There is also a flag that users can set
in a reference's meta data to indicate that resolve does not need to be called
because the reference will never be used in a cross document scenario (see
<a href="#flags">Generation control flags</a>). In these cases, the
generated get method simply returns the pointer.
</p>
<p>
<sup><a class="footnote" href="#ref6">[6]</a><a name="fn6">&nbsp;</a></sup>Applications 
that need to deal with and handle broken links should call eIsProxy() on the
object returned by a get method to see if it is resolved or not (for example,
book.getAuthor().eIsProxy()).
</p>
<p>
<sup><a class="footnote" href="#ref7">[7]</a><a name="fn7">&nbsp;</a></sup>This
clearly fails to allow for multiple authors, but it keeps the example model
simple.
</p>
<p>
<sup><a class="footnote" href="#ref8">[8]</a><a name="fn8">&nbsp;</a></sup>The
reason we bother to delegate to a basicSet() method at all is because it's also
needed by the eInverseAdd() and eInverseRemove() methods, which we'll look at a
little later.
</p>
<p>
<sup><a class="footnote" href="#ref9">[9]</a><a name="fn9">&nbsp;</a></sup>Actually,
all of the concrete EList implementations are simple subclasses of one very
functional and efficient base implementation class, EcoreEList.
</p>
<p>
<sup><a class="footnote" href="#ref10">[10]</a><a name="fn10">&nbsp;</a></sup>In
eInverseAdd(), instead of simply switching on the supplied feature id, it first
calls eDerivedStructuralFeatureID(featureID, baseClass). For simple single
inheritance models, this method has a default implementation that ignores the
second argument and returns the featureID passed in. For models that use
multiple inheritance, eDerivedStructuralFeatureID() may have a generated
override that adjusts a feature ID relative to a mixin class (that is,
baseClass) to a feature ID relative to the concrete derived class of the
instance.
</p>
<p>
<sup><a class="footnote" href="#ref11">[11]</a><a name="fn11">&nbsp;</a></sup>EObjectImpl 
also has an int-typed eContainerFeatureID instance variable to keep track of
which reference is currently used for the eContainer.
</p>
<p>
<sup><a class="footnote" href="#ref12">[12]</a><a name="fn12">&nbsp;</a></sup>See 
<a href="https://www.oracle.com/technical-resources/articles/java/substitutes-missing-c-constructs.html" target="_blank">Replace Enums with Classes</a>.
</p>
<p>
<sup><a class="footnote" href="#ref13">[13]</a><a name="fn13">&nbsp;</a></sup>To
conform to proper Java programming style, the static constant names are
converted to upper case if the modeled enumeration's literal names are not
already upper case.
</p>
<p>
<sup><a class="footnote" href="#ref14">[14]</a><a name="fn14">&nbsp;</a></sup> While
your program isn't strictly required to use the Factory or Package interfaces,
EMF does encourage clients to use the factory to create instances by generating
protected constructors on the model classes, thereby preventing you from simply
calling new to create your instances. You can, however, change the access to
public in the generated classes manually, if that's what you really want. Your
preferences will not be overwritten if you later decide to regenerate the
classes.
</p>
<p>
<sup><a class="footnote" href="#ref15">[15]</a><a name="fn15">&nbsp;</a></sup>Actually,
the first base class in the Ecore model is the one used as the implementation
base class. In the UML diagram, the &lt;&lt;extend>> stereotype is needed to
indicate that Book should be first in the Ecore representation.
</p>
<p>
<sup><a class="footnote" href="#ref16">[16]</a><a name="fn16">&nbsp;</a></sup>If
you know ahead of time that you're going to want to provide your own custom
implementation for some feature, then a better way of doing this is to model the
attribute as volatile, which instructs the generator to only generate a skeleton
method body in the first place, which you are then expected to implement.
</p>
<p>
<sup><a class="footnote" href="#ref17">[17]</a><a name="fn17">&nbsp;</a></sup>EMF
includes a generic mechanism for annotating metamodel objects with additional
information. This mechanism can also be used to attach user documentation to
elements of the model, and when a model is created from XML Schema, EMF
relies on it to capture serialization details that cannot be expressed
directly using Ecore.
</p>
<p>
<sup><a class="footnote" href="#ref18">[18]</a><a name="fn18">&nbsp;</a></sup>The
second line of the above code is only required when run stand-alone (that is,
directly invoked in a JVM, with the required EMF JAR files on the class path).
The same registration is automatically made in the global resource factory
registry when EMF is run within Eclipse.
</p>
<p>
<sup><a class="footnote" href="#ref19">[19]</a><a name="fn19">&nbsp;</a></sup>Implementations
of the reflective methods are also generated for each model class. They
switch on the feature type, and simply call the appropriate generated typesafe
methods.
</p>
<p>
<sup><a class="footnote" href="#ref20">[20]</a><a name="fn20">&nbsp;</a></sup>See
the Unsettable flag under <a href="#flags">Generation control flags</a> for
what constitutes a set attribute.
</p>
<p>
<sup><a class="footnote" href="#ref21">[21]</a><a name="fn21">&nbsp;</a></sup>Think 
carefully before declaring a feature to not resolve proxies. Just because you
don't need to use the reference in a cross document situation doesn't mean that
someone else who wants to use your model may not. Declaring a feature to not
resolve proxies is kind of like declaring a Java class to be final.
</p>
</body>
</html>