Your SlideShare is downloading. ×
0
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Building RESTful Java Applications with EMF
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Building RESTful Java Applications with EMF

6,355

Published on

Representational State Transfer (REST) is a style of software architecture for distributed hypermedia systems such as the World Wide Web. However, it is possible to design any enterprise software …

Representational State Transfer (REST) is a style of software architecture for distributed hypermedia systems such as the World Wide Web. However, it is possible to design any enterprise software system in accordance with the REST architectural style without using the HTTP protocol and without interacting with the World Wide Web.

Systems that follow the principles of REST often referred to as RESTful. Proponents of REST argue that the Web enjoyed the scalability and growth that it has had as a direct result of a few key design principles. Among these principles are the notions that application state and functionality are divided into resources and that every resource is uniquely addressable using a universal syntax for use in hypermedia links. Another key principle of REST is that all resources share a uniform interface for the transfer of state between client and resource, consisting of a constrained set of content types and a constrained set of well-defined operations.

The Eclipse Modeling Framework (EMF) provides a Java runtime framework and tools for generative application development and fine-grained data integration based on simple models. Models can be specified directly using EMF's metamodel, Ecore, or imported from other forms, including UML and XML Schema. Given a model specification, EMF can generate a corresponding set of Java interfaces and implementation classes that can easily be mixed with hand-written code for maximum flexibility. When deployed, applications developed with EMF benefit from a powerful and extensible runtime, which, among other features, includes a persistence mechanism which has always supported the principles of REST – perhaps even before the term "REST" became popular. This tutorial will provide an introduction to EMF, including alternatives for specifying a model, EMF's code generation tools, and key runtime framework concepts. As a practical usage of this knowledge, the presenters will show how EMF can be used to build RESTful applications, exploring some best practices for working with resources and other features of the framework.

Published in: Technology
0 Comments
14 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
6,355
On Slideshare
0
From Embeds
0
Number of Embeds
13
Actions
Shares
0
Downloads
506
Comments
0
Likes
14
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Building RESTful Java™ Applications with EMF Marcelo Paternostro, IBM Kenn Hussey, Embarcadero Technologies Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 1
  • 2. Model Driven Software Development • Software is focused on manipulating data • Data has abstract structure – It can be described at a high level – It can be represented in different ways – It’s always a model of something • The description of the data is yet more data – It’s commonly referred to as metadata – Meta is a bit confusing – The model of a model is a model • Whether it’s recognized or not, models drive software development Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 2
  • 3. What is REST? • Representational State Transfer is a style of software architecture for distributed hypermedia systems such as the World Wide Web • The term was introduced in the doctoral dissertation of Roy Fielding, one of the principal authors of the Hypertext Transfer Protocol™ (HTTP™) specification, in 2000, and has come into widespread use in the networking community • Strictly speaking, REST refers to a collection of network architecture principles that outline how resources are defined and addressed Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 3
  • 4. REST is Not Just for the Web • The term REST is often used in a looser sense to describe any simple interface that transmits domain-specific data over HTTP without an additional messaging layer such as SOAP or session tracking via HTTP cookies • In fact, it is possible to design any enterprise software system in accordance with Fielding's REST architectural style without using the HTTP protocol and without interacting with the World Wide Web • Systems that follow the principles of REST often referred to as RESTful Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 4
  • 5. REST Principles • Proponents of REST argue that the Web enjoyed the scalability and growth that it has had as a direct result of a few key design principles – application state and functionality are divided into resources – every resource is uniquely addressable using a universal syntax for use in hypermedia links – all resources share a uniform interface for the transfer of state between client and resource, consisting of a constrained set of content types and a constrained set of well-defined operations Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 5
  • 6. CRUD • The four basic operations of persistent storage – create, read, update and delete – are a major part of nearly all computer software • The acronym CRUD refers to all of the major functions that need to be implemented in a relational database application or RESTful application to consider it complete • We’ll look at how Java applications based on these operations, and the REST principles in general, are supported by EMF APIs and suggest some best practices for working with resources in EMF Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 6
  • 7. Eclipse Modeling Framework • A simple, pragmatic, Java-based framework that provides – The Ecore API for describing models – The EObject API for manipulating instances – A resource framework for RESTful persistence – A generator framework for producing development artifacts – A runtime along with utilities for traversing, indexing, copy, change recording, and so on – Tools for working with models and their instances • EMF was used to develop EMF Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 7
  • 8. A Brief History of EMF • Started at IBM in the late 90’s – It supported Object Management Group™ (OMG™) specifications – It implemented Meta Object Facility (MOF™) – It used XML™ Metadata Interchange (XMI®) – It’s closely related to Java Metadata Interface (JMI) • Problems surfaced for adopters – The MOF model was far too complex – The generated code and runtime were bloated and performed poorly • “ETools Modeling Framework” (EMF) was kicked off in 2000 – Boiled MOF down to its essential components, resulting in Ecore – Revamped the runtime and tools to make them lean and mean • Contributed to Eclipse in September 2002 – Rebranded as the Eclipse Modeling Framework – Fed back to OMG resulting in Essential MOF/Complete MOF split Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 8
  • 9. Ecore: The Model of Models • A simple model for describing models – Classification of objects – Attributes of those objects – Relationships/associations between those objects – Operations on those objects – Simple constraints on those objects, and their attributes and relationships • Ecore is self describing, i.e., it is its own model • Models higher up in the meta levels tend to all look the same – They begin to conform to our mental model Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 9
  • 10. Relationship of Ecore to Other Models UML® XML Schema Ecore Java Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 10
  • 11. A Model is a Model is a Model UML XML Schema <xsd:complexType name=quot;Nodequot;> <xsd:sequence> <xsd:element Ecore name=quot;childrenquot; type=quot;tree:Nodequot; minOccurs=quot;0quot; maxOccurs=quot;unboundedquot; ecore:opposite=quot;parentquot;/> </xsd:sequence> <xsd:attribute name=quot;labelquot; type=quot;xsd:stringquot;/> </xsd:complexType> Java public interface Node { String getLabel(); void setLabel(String value); List<Node> getChildren(); Node getParent(); void setParent(Node value); } // Node Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 11
  • 12. Ecore Overview Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 12
  • 13. Ecore Data Types Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 13
  • 14. Ecore Annotations and EObject Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 14
  • 15. Ecore Generics Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 15
  • 16. The Tree Ecore Model EPackage name tree nsURI http://www.example.org/tree eClassifiers Node EClass name Node eStructuralFeatures label, children, parent EAttribute EReference EReference name label name children name parent eType EString eType Node eType Node lowerBound 0 lowerBound 0 lowerBound 0 upperBound 0 upperBound -1 upperBound 1 containment true containment false eOpposite parent eOpposite children Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 16
  • 17. The Tree Ecore Model Serialized as XMI <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> <ecore:EPackage xmi:version=quot;2.0quot; xmlns:xmi=quot;http://www.omg.org/XMIquot; xmlns:xsi=quot;http://www.w3.org/2001/XMLSchema-instancequot; xmlns:ecore=quot;http://www.eclipse.org/emf/2002/Ecorequot; name=quot;treequot; nsURI=quot;http://www.example.org/treequot; nsPrefix=quot;treequot;> <eClassifiers xsi:type=quot;ecore:EClassquot; name=quot;Nodequot;> <eStructuralFeatures xsi:type=quot;ecore:EAttributequot; name=quot;labelquot; eType=quot;ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EStringquot;/> <eStructuralFeatures xsi:type=quot;ecore:EReferencequot; name=quot;childrenquot; upperBound=quot;-1quot; eType=quot;#//Nodequot; containment=quot;truequot; eOpposite=quot;#//Node/parentquot;/> <eStructuralFeatures xsi:type=quot;ecore:EReferencequot; name=quot;parentquot; eType=quot;#//Nodequot; eOpposite=quot;#//Node/childrenquot;/> </eClassifiers> </ecore:EPackage> Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 17
  • 18. The Tree Ecore Model Serialized as EMOF <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> <emof:Package xmi:version=quot;2.0quot; xmlns:xmi=quot;http://www.omg.org/XMIquot; xmlns:emof=quot;http://schema.omg.org/spec/MOF/2.0/emof.xmlquot; xmi:id=quot;treequot; name=quot;treequot; uri=quot;http://www.example.org/treequot;> <ownedType xmi:type=quot;emof:Classquot; xmi:id=quot;tree.Nodequot; name=quot;Nodequot;> <ownedAttribute xmi:id=quot;tree.Node.labelquot; name=quot;labelquot; isOrdered=quot;truequot; lower=quot;0quot;> <type xmi:type=quot;emof:PrimitiveTypequot; href=quot;http://schema.omg.org/spec/MOF/2.0/emof.xml#Stringquot;/> </ownedAttribute> <ownedAttribute xmi:id=quot;tree.Node.childrenquot; name=quot;childrenquot; isOrdered=quot;truequot; lower=quot;0quot; upper=quot;*quot; type=quot;tree.Nodequot; isComposite=quot;truequot; opposite=quot;tree.Node.parentquot;/> <ownedAttribute xmi:id=quot;tree.Node.parentquot; name=quot;parentquot; isOrdered=quot;truequot; lower=quot;0quot; type=quot;tree.Nodequot; opposite=quot;tree.Node.childrenquot;/> </ownedType> <xmi:Extension extender=quot;http://www.eclipse.org/emf/2002/Ecorequot;> <nsPrefix>tree</nsPrefix> </xmi:Extension> </emof:Package> Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 18
  • 19. A Tree Instance Model Node label Root children A, B parent Node Node label A label B children X children Y parent Root parent Root Node Node label X label Y children children parent A parent B Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 19
  • 20. A Tree Instance Model Serialized as XMI <tree:Node xmi:version=quot;2.0quot; xmlns:xmi=quot;http://www.omg.org/XMIquot; xmlns:tree=quot;http://www.example.org/treequot; label=quot;rootquot;> <children label=quot;Aquot;> <children label=quot;Xquot;/> </children> <children label=quot;Bquot;> <children label=quot;Yquot;/> </children> </tree:Node> Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 20
  • 21. The EMF Generator Model • The GenModel is a decorator for tailoring the generated code Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 21
  • 22. EMF Application Architecture Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 22
  • 23. EMF in Action • Demo time! – Show how to create the Ecore Tree model from scratch using the Sample Ecore Editor – Show how to use Ecore Tools for diagrams – Show how to exploit dynamic models to create Tree instances – Demonstrate the interchangeable nature of models • Generate the Java realization • Export to XML Schema • Show how these round trip • Show how to run the example • Show how to run the generated editor Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 23
  • 24. Completing the Picture • To show the full generation picture, we need examples of EDataTypes, EEnums, and EOperations • An EDataType is effectively just a named alias for some existing Java class – Most data types support conversion to and from a string representation in order to support persistence – Values of data types generally should be treated as immutable leaves • An EEnum is a specialized EDataType that specifies a list of EEnumLiterals which exhaustively enumerates all possible values of the data type • An EOperation is simply the specification of the signature of an operation that can be invoked on a class Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 24
  • 25. A Richer Tree Ecore Model Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 25
  • 26. Generated EPackage package org.example.tree; // ... public interface TreePackage extends EPackage { String eNAME = quot;treequot;; String eNS_URI = quot;http://www.example.org/treequot;; String eNS_PREFIX = quot;treequot;; TreePackage eINSTANCE = TreePackageImpl.init(); // ... interface Literals { // ... } } package org.example.tree.impl; // ... public class TreePackageImpl extends EPackageImpl implements TreePackage { // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 26
  • 27. Generated EFactory package org.example.tree; // ... public interface TreeFactory extends EFactory { TreeFactory eINSTANCE = TreeFactoryImpl.init(); // ... } package org.example.tree.impl; // ... public class TreeFactoryImpl extends EFactoryImpl implements TreeFactory { // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 27
  • 28. Generated EPackage Utility Classes package org.example.tree.util; // ... public class TreeAdapterFactory extends AdapterFactoryImpl { // ... } package org.example.tree.util; // ... public class TreeSwitch<T> { // ... } package org.example.tree.util; // ... public class TreeResourceImpl extends XMIResourceImpl { // ... } package org.example.tree.util; // ... public class TreeResourceFactoryImpl extends ResourceFactoryImpl { // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 28
  • 29. Generated EClass package org.example.tree; // ... public interface Node extends EObject { // ... } package org.example.tree.impl; // ... public class NodeImpl extends EObjectImpl implements Node { // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 29
  • 30. Generated EClass Impact TreePackage public interface //... { int NODE = 0; EClass getNode(); // ... interface Literals { EClass NODE = eINSTANCE.getNode(); // ... } } public interface TreeFactory //... { Node createNode(); // ... } public class TreeSwitch<T> { public T caseNode(Node object); // ... } public class TreeAdapterFactory //... { public Adapter createNodeAdapter(); // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 30
  • 31. Generated EStructuralFeature public interface Node // ... { String getLabel(); void setLabel(String value); // ... } public class NodeImpl // ... { protected static final String LABEL_EDEFAULT = null; protected String label = LABEL_EDEFAULT; public String getLabel() { return label; } public void setLabel(String newLabel) { String oldLabel = label; label = newLabel; // ... } // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 31
  • 32. Generated EStructuralFeature Impact public interface TreePackage //... { int NODE__LABEL = 0; EAttribute getNode_Label(); // ... interface Literals { EAttribute NODE__LABEL = eINSTANCE.getNode_Label(); // ... } } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 32
  • 33. Generated EOperation public interface Node // ... { boolean hasChildren(); // ... } public class NodeImpl // ... { public boolean hasChildren() { // TODO: implement this method // Ensure that you remove @generated or mark it @generated NOT throw new UnsupportedOperationException(); } // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 33
  • 34. Generated EDataType Impact public interface TreePackage //... { int LABEL= 2; EDataType getLabel(); // ... interface Literals { EDataType LABEL = eINSTANCE.getLabel(); // ... } } public class TreeFactoryImpl //... { public String createLabelFromString (EDataType eDataType, String initialValue) { return (String)super.createFromString(eDataType, initialValue); } public String convertLabelToString (EDataType eDataType, Object instanceValue) { return super.convertToString(eDataType, instanceValue); } // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 34
  • 35. Generated EEnum package org.example.tree; // ... public enum NodeKind implements Enumerator { // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 35
  • 36. Generated EEnum Impact TreePackage public interface //... { int NODE_KIND = 1; EEnum getNodeKind(); // ... interface Literals { EEnum NODE_KIND = eINSTANCE.getNodeKind(); // ... } } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 36
  • 37. Generated EEnumLiteral public enum NodeKind // ... { SINGLETON(0, quot;Singletonquot;, quot;Singletonquot;), // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 37
  • 38. Generated Project-level Artifacts • In addition to the generated Java code, generated projects also include the following artifacts – A MANIFEST.MF • Information used by Equinox/OSGI and the Plugin Development Environment PDE to manage dependencies and classpaths – A plugin.xml • Information used by Equinox to manage extension points – A plugin.properties • Properties that need to be translated – A build.properties • Information used to produce a deployed binary result Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 38
  • 39. Generated Manifest • The generated MANIFEST.MF is not regenerated once the corresponding plugin.xml exists so you can tailor it as needed Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.example.tree;singleton:=true Bundle-Version: 1.0.0 Bundle-ClassPath: . Bundle-Vendor: %providerName Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: J2SE-1.5 Export-Package: org.example.tree, org.example.tree.impl, org.example.tree.util Require-Bundle: org.eclipse.core.runtime, org.eclipse.emf.ecore;visibility:=reexport, org.eclipse.emf.ecore.xmi;visibility:=reexport Bundle-ActivationPolicy: lazy Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 39
  • 40. Generated Plug-in XML • The generated plugin.xml is not regenerated so you can tailor it as needed – But keep in mind that it contains extension points with data that might change when your model name changes <plugin> <extension point=quot;org.eclipse.emf.ecore.generated_packagequot;> <package uri=quot;http://www.example.org/treequot; class=quot;org.example.tree.TreePackagequot; genModel=quot;model/Tree.genmodelquot;/> </extension> <extension point=quot;org.eclipse.emf.ecore.extension_parserquot;> <parser type=quot;treequot; class=quot;org.example.tree.util.TreeResourceFactoryImplquot;/> </extension> </plugin> Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 40
  • 41. Generated Build and Plug-in Properties • The generated plugin.properties supports merging – Any property not already defined is added – Any property already defined retains it’s value pluginName = Tree Model providerName = www.example.org • The generated build.properties will not be modified once it exists it can be tailored as desired bin.includes = ., model/, META-INF/, plugin.xml, plugin.properties jars.compile.order = . source.. = src/ output.. = bin/ Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 41
  • 42. Modifying Generated Code • EMF’s generator supports merging generated changes with hand written changes – All generated code is marked with @generated • Anything so marked will be updated or even deleted during subsequent regeneration • Everything else is safe /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated NOT */ public NodeKind getKind() { return getParent() == null ? getChildren().isEmpty() ? NodeKind.SINGLETON : NodeKind.ROOT : getChildren().isEmpty() ? NodeKind.LEAF : NodeKind.INTERMEDIATE; } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 42
  • 43. Modifying Generated Javadoc • Javadoc containing “user-doc” sections support merging – The text inside that section will be preserved – The text outside that section will be updated – The feature accessor has a comment that should be changed /** * Returns the value of the '<em><b>Label</b></em>' attribute. * <!-- begin-user-doc --> * <p> * If the meaning of the '<em>Label</em>' attribute isn't clear, * there really should be more of a description here... * </p> * <!-- end-user-doc --> * @return the value of the '<em>Label</em>' attribute. * @see #setLabel(String) * @see org.example.tree.TreePackage#getNode_Label() * @model dataType=quot;org.example.tree.Label‚ * @generated */ String getLabel(); Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 43
  • 44. Augmenting Generated Methods • A generated method can be renamed by adding a “Gen” suffix and then the original signature can be used to provide additional behavior /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public void setLabelGen(String newLabel) { String oldLabel = label; label = newLabel; if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, TreePackage.NODE__LABEL, oldLabel, label)); } public void setLabel(String newLabel) { setLabelGen(newLabel == null ? null : newLabel.intern()); } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 44
  • 45. Creating a Tree Instance Model Node TreeFactory tree = TreeFactory.eINSTANCE; label Root Node root = tree.createNode(); children A, AB root.setLabel(quot;Rootquot;); parent Node a = tree.createNode(); a.setLabel(quot;Aquot;); Node Node root.getChildren().add(a); label A label B Node x = tree.createNode(); children X children Y x.setLabel(quot;Xquot;); parent Root parent Root a.getChildren().add(x); Node b = tree.createNode(); b.setLabel(quot;Bquot;); Node Node root.getChildren().add(b); label X label Y Node y = tree.createNode(); children children y.setLabel(quot;Yquot;); parent A parent B b.getChildren().add(y); Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 45
  • 46. Notifiers, Adapters, and Notification public interface Notifier public interface Adapter { { EList<Adapter> eAdapters(); void notifyChanged(Notification notification); void eNotify(Notification notification); // ... boolean eDeliver(); } void eSetDeliver(boolean deliver); } int SET = 1; public interface Notification int UNSET = 2; { int ADD = 3; Object getNotifier(); int REMOVE = 4; int getEventType(); int ADD_MANY = 5; Object getFeature(); int REMOVE_MANY = 6; Object getOldValue(); int MOVE = 7; Object getNewValue(); int REMOVING_ADAPTER = 8; int getPosition(); notifier.eAdapters().add int RESOLVE = 9; // ... (new AdapterImpl() int EVENT_TYPE_COUNT = 10; } { @Override public void notifyChanged(Notification notification) { // Process notifications produced by the notifier. } }); Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 46
  • 47. EObject Reflection • EObject is EMF’s equivalent to java.lang.Object – Just as java.lang.Object has getClass() to determine the object’s runtime java.lang.Class, EObject has eClass() to determine the object’s runtime EClass – An EObject knows the EObject that contains it as well as the specific containment EReference by which it is referenced – An EObject knows all its contained children • An EObject is a notifier – Changes to its features fire notifications public interface EObject extends Notifier { EClass eClass(); EObject eContainer(); EReference eContainmentFeature(); EList<EObject> eContents(); // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 47
  • 48. EObject Notification • Generated set (and unset) method as well as EMF’s specialized list implementations all produce notifications – The logic is optimized to produce them if and only if there are listeners public void setLabel(String newLabel) { String oldLabel = label; label = newLabel; if (eNotificationRequired()) eNotify (new ENotificationImpl (this, Notification.SET, TreePackage.NODE__LABEL, oldLabel, label)); } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 48
  • 49. References and Referential Integrity • Ecore models associations as a pair of references related as opposites – Such references are referred to as bidirectional – EMF enforces the referential integrity of such references via the handshaking protocol provided by InternalEObject’s eInverseAdd and eInverseRemove • A containment reference induces a tree structure – It is implicitly bidirectional even if there is no explicitly defined opposite – EObject’s eContainer() is the implicit opposite of a containment reference • A container reference is the explicit opposite of a containment reference – It is effectively derived from EObject.eContainer() • Any other type of reference is referred to as a cross reference – It specifies cross links between the objects in the tree structure induced by containment and container references • When an object is added to a containment reference it is removed from its current containment reference – Referential integrity is enforced, i.e., there can only be one eContainer() Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 49
  • 50. Updating a Tree Instance Model Node b.getChildren().set(0, x); label Root children A, AB Notifier Feature Type Old New parent SET b children y x SET y parent b Node Node SET x parent a b label A label B REMOVE a children x children X children X Y parent Root parent Root Node Node label X label Y children children parent B A parent B Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 50
  • 51. Exercise 1 Code Generation Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 51
  • 52. RESTful Persistence • The principles of representation state transfer underlie EMF’s persistence architecture – Models are stored in one or more resources – Each resource is addressed via a Uniform Resource Identifier, i.e., a URI – A resource supports save, load, unload, and delete – Specialized resources support arbitrary content types – Transfer of state is uniformly handled by a stateless URI converter that supports • Any scheme accessible as a URL • Any scheme registered with Eclipse File System (EFS) Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 52
  • 53. Uniform Resource Identifiers • A URI is effectively a string with a well-defined structure – Supported by org.eclipse.emf.common.util.URI • It predates java.net.URI • They are immutable • They are created by static factory methods public final class URI { public static URI createURI(String uri); public static URI createFileURI(String pathName); public static URI createPlatformResourceURI(String pathName, boolean encode); public static URI createPlatformPluginURI(String pathName, boolean encode); // … } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 53
  • 54. Hierarchical URIs • A URI typically consists of /-separated components – [scheme:][//authority][/path][?query][#fragment] – E.g., • http://www.eclipse.org/modeling/emf/?project=emf#related • file://c:/workspace/project/file.extension#id • platform:/resource/project/file.extension#id public final class URI { public boolean isHierarchical(); public String scheme(); public String authority(); public String[] segments(); public String path(); public String query(); public String fragment(); // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 54
  • 55. Absolute and Relative URIs • An absolute URI starts with a scheme – Always uses absolute URIs to identify resources! – Relative URIs are useful within resources for referring to other resources within the same authority • This supports moving groups of related resources – Examples of relative URIs • #id • ../directory/file.extension • file.extension public final class URI { public boolean isRelative(); // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 55
  • 56. Resolving and De-resolving URIs • De-resolving an absolute URI against a base absolute URI yields the URI relative to that base – e.g., de-resolving platform:/resource/a/foo.html against platform:/resource/b/bar.html yields ../a/foo.html • Resolving a relative URI against a base absolute URI yields the absolute URI relative to that base – e.g., resolving ../a/foo.html against platform:/resource/b/bar.html yields platform:/resource/a/foo.html public final class URI { public URI resolve(URI base); public URI deresolve(URI base); // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 56
  • 57. URIs to Access the File System • A file system path is OS-specific! – It is not a URI and is not a separator in a URI – Use createFileURI to convert a file system path to a URI • The path c:afoo.html becomes file:/c:/a/foo.html – Use toFileString to convert back to a file system path – Ensure your file system path is also absolute • URI.createFileURI(new java.io.File(<path>).getAbsolutePath()); public final class URI { public static URI createFileURI(String pathName) public boolean isFile(); public String toFileString(); // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 57
  • 58. URIs to Access the Eclipse Workspace • Use platform resource URIs to access the workspace – platform:/resource/project[/relative-path] – Be sure to encode the path • URI.createPlatformResourceURI(iFile.getPath().toString(), true) – Use workspaceRoot.getFile(new Path(uri.toPlatformResourceString(true))) to convert back to an IFile public final class URI { public static URI createPlatformResourceURI(String pathName, boolean encode); public boolean isPlatformResource(); public String toPlatformString(boolean decode); // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 58
  • 59. URIs to Access the Eclipse Installation • Use platform plug-in URIs to access the installation – platform:/plugin/plugin-id[/relative-path] – Be sure to encode the path • URI.createPlatformPluginURI(<plugin-path>, true); public final class URI { public static URI createPlatformPluginURI(String pathName, boolean encode); public boolean isPlatformPlugin(); public String toPlatformString(boolean decode); // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 59
  • 60. URIs to Access an Archive • Use archive URIs to access zipped or jarred content – archive:absolute-uri{!/relative-path}+ – E.g., archive:file:/c:/my.zip!/a/foo.zip!/b/bar.html public final class URI { public boolean isArchive(); // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 60
  • 61. URI Converter • All access to the state associated with a URI is directed to a URI converter – It supports URI normalization • Relative URIs are made absolute • URI mappings are applied – There is a global URI converter instance • Implementations should extend ExtensibleURIConverterImpl public interface URIConverter { URI normalize(URI uri); URIConverter INSTANCE = new ExtensibleURIConverterImpl(); // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 61
  • 62. URI Converter Remapping • A URI map provides support for redirection – Instance mappings, e.g., • http://www.example.org/foo.html -> platform:/plugin/org.example/foo.html – Folder mappings (URIs ending with /), e.g., • http://www.example.org/ -> platform:/plugin/org.example/ – There’s a global instance that can be populated by the org.eclipse.emf.ecore.uri_mapping extension point public interface URIConverter { Map<URI, URI> getURIMap(); Map<URI, URI> URI_MAP = /**/; // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 62
  • 63. URI Converter Input and Output • The URI converter acts as a factory for creating input and output streams – Arbitrary client-defined options can be passed along – An OPTION_RESPONSE can be used to pass in a map to be populated with additional information • The RESPONSE_TIME_STAMP_PROPERTY will be updated with the time stamp of the resource at the time the stream was created public interface URIConverter { String OPTION_RESPONSE = quot;RESPONSEquot;; String RESPONSE_TIME_STAMP_PROPERTY = quot;TIME_STAMPquot;; InputStream createInputStream(URI uri, Map<?, ?> options) throws IOException; OutputStream createOutputStream(URI uri, Map<?, ?> options) throws IOException; //... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 63
  • 64. URI Converter Deletion and Existence • The URI converter can test whether there is any state associated with a URI – This is generally more efficient than fetching an input stream, which could fail due to insufficient permission • The state associated with a URI can be deleted – This was added in 2.4 to support the full create, read, update, delete (CRUD) life cycle public interface URIConverter { boolean exists(URI uri, Map<?, ?> options); void delete(URI uri, Map<?, ?> options) throws IOException; // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 64
  • 65. URI Converter • Attributes associated with the state of a URI can be fetched and stored – An OPTION_REQUESTED_ATTRIBUTES map specifies the attributes to be fetched public interface URIConverter { String ATTRIBUTE_TIME_STAMP = quot;timeStampquot;; long NULL_TIME_STAMP = -1; String ATTRIBUTE_LENGTH = quot;lengthquot;; String ATTRIBUTE_READ_ONLY = quot;readOnlyquot;; String ATTRIBUTE_EXECUTABLE = quot;executablequot;; String ATTRIBUTE_ARCHIVE = quot;archivequot;; String ATTRIBUTE_HIDDEN = quot;hiddenquot;; String ATTRIBUTE_DIRECTORY = quot;directoryquot;; String OPTION_REQUESTED_ATTRIBUTES = quot;requestedAttributesquot;; Map<String, ?> getAttributes(URI uri, Map<?, ?> options); void setAttributes(URI uri, Map<String, ?> attributes, Map<?, ?> options) throws IOException; // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 65
  • 66. URI Converter Content Description • A URI converter can be asked to provide a content description of the state associated with a URI – The result is a map of properties describing the content • The content description is typically determined by analyzing the input stream the URI – This analysis is done by content handlers – There is a configurable list of these handlers public interface URIConverter { Map<String, ?> contentDescription(URI uri, Map<?, ?> options) throws IOException; EList<ContentHandler> getContentHandlers(); // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 66
  • 67. URI Converter Delegation To URI Handlers • All the work of the URI converter is delegated to a URI handler – URIs are normalized before the handler is determined – The getURIHandler method determines the appropriate handler for the given URI – There is a configurable list of URI handlers • Initially populated with URIHandler.DEFAULTS public interface URIConverter { EList<URIHandler> getURIHandlers(); URIHandler getURIHandler(URI uri); // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 67
  • 68. URI Handler • The full complement of URI converter methods are supported for delegation • The canHandle method indicates whether the handler is applicable for the given URI • Facilitates composition of specialized URI converter behavior public interface URIHandler { boolean canHandle(URI uri); InputStream createInputStream(URI uri, Map<?, ?> options) throws IOException; OutputStream createOutputStream(URI uri, Map<?, ?> options) throws IOException; void delete(URI uri, Map<?, ?> options) throws IOException; Map<String, ?> contentDescription(URI uri, Map<?, ?> options) throws IOException; boolean exists(URI uri, Map<?, ?> options); Map<String, ?> getAttributes(URI uri, Map<?, ?> options); void setAttributes(URI uri, Map<String, ?> attributes, Map<?, ?> options) throws IOException; // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 68
  • 69. URI Handler • Default URI handlers support the Eclipse workspace, the file system, the Eclipse File System, nested archives, and arbitrary URLs public interface URIHandler { List<URIHandler> DEFAULT_HANDLERS = Collections.unmodifiableList (Arrays.asList (new URIHandler [] { new PlatformResourceURIHandlerImpl(), new FileURIHandlerImpl(), new EFSURIHandlerImpl(), new ArchiveURIHandlerImpl(), new URIHandlerImpl() })); // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 69
  • 70. Content Handler • The URI converter creates an input stream along with an empty context and delegates to each content handler for which canHandle returns true – The context cashes state to reduce duplicate computation costs • Other than validity and content type, only the requested properties in the map supplied in the options are computed public interface ContentHandler { boolean canHandle(URI uri); String OPTION_REQUESTED_PROPERTIES = quot;REQUESTED_PROPERTIESquot;; Map<String, ?> contentDescription (URI uri, InputStream inputStream, Map<?, ?> options, Map<Object, Object> context) throws IOException; // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 70
  • 71. Content Handler Validity Determination • Content validity is a three state result – The URI converter returns the description of the first handler that yields a valid description – Failing that, it returns the first indeterminate description – Only when invalid is the content type not included in the description public interface ContentHandler { String VALIDITY_PROPERTY = quot;org.eclipse.emf.ecore:validityquot;; enum Validity { INVALID, INDETERMINATE, VALID } String CONTENT_TYPE_PROPERTY = quot;org.eclipse.emf.ecore:contentTypequot;; String UNSPECIFIED_CONTENT_TYPE = quot;quot;; Map<String, Object> INVALID_CONTENT_DESCRIPTION = /**/; } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 71
  • 72. Content Handler Encodings • Two standard description properties are supported – The character set used to encode the content – The byte order marker at the start of the stream public interface ContentHandler { String CHARSET_PROPERTY = quot;org.eclipse.core.runtime:charsetquot;; String BYTE_ORDER_MARK_PROPERTY = quot;org.eclipse.core.runtime:bomquot;; enum ByteOrderMark { UTF_8, UTF_16BE, UTF_16LE; public byte [] bytes(); public static ByteOrderMark read(InputStream inputStream) throws IOException; } // .. } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 72
  • 73. Content Handler Registration • There is a registry of content handlers populated by the org.eclipse.emf.ecore.content_handler extension point – Handlers are sorted and applied based on priority – A flattened list view based on priority is provided – A single default handler that delegates to the platform is registered by EMF so that org.eclipse.core.contenttype.contentTypes registrations are exploited public interface ContentHandler { interface Registry extends SortedMap<Integer, List<ContentHandler>> { int VERY_HIGH_PRIORITY = -10000; int HIGH_PRIORITY = -1000; int NORMAL_PRIORITY = 0; int LOW_PRIORITY = 1000; int VERY_LOW_PRIORITY = 10000; void put(int priority, ContentHandler contentHandler); List<ContentHandler> contentHandlers(); Registry INSTANCE = new ContentHandlerRegistryImpl(); } } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 73
  • 74. Resource Set • A resource set acts as a container for resources – The relationship from resource set to resource is effectively bidirectional containment • A resource set is a notifier – Changes to the resources list fire notifications for the RESOURCE_SET__RESOURCES feature public interface ResourceSet extends Notifier { int RESOURCE_SET__RESOURCES = 0; EList<Resource> getResources(); // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 74
  • 75. Resource • A resource acts as a container for EObjects – The relationship from resource to EObject is effectively bidirectional containment • A resource knows its containing resource set • A resource is a notifier – Changes to its features fire notifications public interface EObject public interface Resource extends Notifier //... { { Resource eResource(); int RESOURCE__RESOURCE_SET = 0; // ... ResourceSet getResourceSet(); } int RESOURCE__URI = 1; URI getURI(); void setURI(URI uri); int RESOURCE__CONTENTS = 2; EList<EObject> getContents(); // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 75
  • 76. Tree Iterators over the Containment Tree • Resource set’s resources, a resource’s contents, and an EObject’s eContents() collectively induce a tree structure that can be walked by a tree iterator, which is simply an iterator that supports branch pruning public interface ResourceSet // ... { TreeIterator<Notifier> getAllContents(); // ... } public interface Resource public interface TreeIterator<E> // ... { extends Iterator<E> TreeIterator<EObject> getAllContents(); { // ... void prune(); } } public interface EObject //... { TreeIterator<EObject> eAllContents(); // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 76
  • 77. Resource Set • A resource set provides a complete context – A URI converter for accessing the state of the resources – A resource factory registry for determining the appropriate factory when creating new resources – A package registry for determining the appropriate package to associate with a namespace URI public interface ResourceSet extends Notifier { URIConverter getURIConverter(); Resource.Factory.Registry getResourceFactoryRegistry(); EPackage.Registry getPackageRegistry(); // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 77
  • 78. Resource Factory • A resource factory creates a resource given a URI – It is responsible for creating and configuring new resources • Resource factories are maintained in resource factory registries public interface Resource // ... { interface Factory { Resource createResource(URI uri); // ... } } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 78
  • 79. Resource Factory Registry • A resource factory registry determines the appropriate factory given a URI and a content type – For null content type, no lookup based on content type is performed – For URIHandler.UNSPECIFIED_CONTENT_TYPE, the content type is computed lazily when first required – A resource set’s local resource factory registry delegates to the global instance when local lookup yields no match public interface Resource // ... { interface Factory { interface Registry { Factory getFactory(URI uri, String contentType); Registry INSTANCE = new ResourceFactoryRegistryImpl(); // ... } } } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 79
  • 80. Protocol Resource Factory Registration • Registration based on URI scheme is supported – The org.eclipse.emf.ecore.protocol_parser extension point is used to register such a factory with the global factory registry instance – This mechanism is rarely used and is not very RESTful public interface Resource // ... public final class URI { { interface Factory public String scheme(); { // ... interface Registry } { Map<String, Object> getProtocolToFactoryMap(); // ... } } } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 80
  • 81. File Extension Resource Factory Registration • Registration based on URI file extension is supported – The org.eclipse.emf.ecore.extension_parser extension point is used to register such a factory with the global factory registry instance – A registration against the default extension matches any extension – This mechanism is commonly used, efficient, but not very RESTful public interface Resource // ... public final class URI { { interface Factory public String fileExtension(); { // ... interface Registry } { String DEFAULT_EXTENSION = quot;*quot;; Map<String, Object> getExtensionToFactoryMap(); // ... } } } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 81
  • 82. Content Type Resource Factory Registration • Registration based on content type is supported – The org.eclipse.emf.ecore.content_parser extension point is used to register such a factory with the global factory registry instance – A registration against the default content type matches any content type – This is new to 2.4 and is more RESTful public interface Resource // ... { interface Factory { interface Registry { String DEFAULT_CONTENT_TYPE_IDENTIFIER = quot;*quot;; Map<String, Object> getContentTypeToFactoryMap(); } } // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 82
  • 83. Package Registry • A package registry determines the appropriate EPackage or EFactory given a namespace URI – The org.eclipse.emf.ecore.generated_package/dynamic_package extension points are used to register generated/dynamic packages with the global registry – The org.eclipse.emf.ecore.factory_override extension point is used to register a factory that overrides the generated default – A resource set’s local package registry delegates to the global instance when local lookup yields no match • The org.eclipse.emf.ecore.package_registry_implementation can be used once to override the default implementation of the global instance public interface EPackage // ... { interface Registry { EPackage getEPackage(String nsURI); EFactory getEFactory(String nsURI); Registry INSTANCE = EPackageRegistryImpl.createGlobalRegistry(); // ... } } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 83
  • 84. Creating a New Resource • A resource set acts as a factory for creating resources – Specifying no content type is equivalent to specifying null – The resource set’s resource factory registry is consulted to determine the appropriate factory – That factory is used to create the resource – That resource is added to the list of resources public interface ResourceSet // ... { Resource createResource(URI uri); Resource createResource(URI uri, String contentType); // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 84
  • 85. Populating a New Resource • A newly created resource is initially considered not loaded – Adding an object to the contents list will change the state to indicate that it is considered loaded public interface Resource // ... { int RESOURCE__IS_LOADED = 4; boolean isLoaded(); // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 85
  • 86. Saving a Resource • Resource has two save methods – The save method without an output stream argument uses the URI converter of the containing resource set to create an output stream from the resource’s URI and then calls the second save method, after which it closes the stream – The second save method writes a representation of the contained objects into the output stream public interface Resource // ... { void save(Map<?, ?> options) throws IOException; void save(OutputStream outputStream, Map<?, ?> options) throws IOException; // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 86
  • 87. Saving a Tree Model Instance ResourceSet resourceSet = ResourceSet new ResourceSetImpl(); resources Resource resource = resourceSet.createResource Resource (URI.createFileURI resourceSet <?xml version=quot;1.0quot; encoding=quot;ASCIIquot;?> (quot;c:/Root.treequot;)); uri file:/c:/Root.tree <tree:Node xmi:version=quot;2.0quot; TreeFactory tree = contents TreeFactory.eINSTANCE; xmlns:xmi=quot;http://www.omg.org/XMIquot; xmlns:tree=quot;http://www.example.org/treequot; Node root = tree.createNode(); Node label=quot;Rootquot;> eContainer root.setLabel(quot;Rootquot;); <children label=quot;Aquot;/> eResource </tree:Node> resource.getContents().add(root); label Root children A Node a = tree.createNode(); parent a.setLabel(quot;Aquot;); root.getChildren().add(a); Node eContainer resource.save(null); eResource label A children parent Root Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 87
  • 88. Explicitly Loading a Resource • Resource has two load methods – The load method without an input stream argument uses the URI converter of the containing resource set to create an input stream from the resource’s URI and then calls the second load method, after which it closes the stream – The second load method reads the representation and adds the resulting objects to the contents – Resources are usually not loaded explicitly public interface Resource // ... { void load(Map<?, ?> options) throws IOException; void load(InputStream inputStream, Map<?, ?> options) throws IOException; // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 88
  • 89. Demand Loading a Resource • Resources are typically demand loaded into a resource set rather than being explicitly loaded – The existing list of resources is first considered for a match – If there isn’t one, a new resource is created as before – If the matched resource isn’t already loaded or a new resource is created, that resource is loaded • The default load options are passed to the load method public interface ResourceSet // ... { Map<Object, Object> getLoadOptions(); Resource getResource(URI uri, boolean loadOnDemand); // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 89
  • 90. Loading a Tree Model Instance ResourceSet resourceSet = ResourceSet new ResourceSetImpl(); resources Resource resource = resourceSet.getResource Resource (URI.createFileURI(quot;c:/Root.treequot;), resourceSet <?xml version=quot;1.0quot; encoding=quot;ASCIIquot;?> true); uri file:/c:/Root.tree <tree:Node xmi:version=quot;2.0quot; Node root = contents xmlns:xmi=quot;http://www.omg.org/XMIquot; (Node)resource.getContents().get(0); xmlns:tree=quot;http://www.example.org/treequot; root.setLabel(root.getLabel() + quot;'quot;); Node label=quot;Root'quot;> eContainer Node a = root.getChildren().get(0); <children label=quot;A'quot;/> eResource </tree:Node> a.setLabel(a.getLabel() + quot;'quot;); label Root’ Root children A’ A resource.save(System.out, null); parent Node eContainer eResource label A’ A children parent Root’ Root Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 90
  • 91. Resource Time Stamps • Both loading and saving update a resource’s time stamp – When loading, it’s the time stamp of the resource when the input stream is opened – When saving, it’s the time stamp of the resource after the output stream is closed – When populating a new resource, it’s the time stamp of the clock when the first object is added • This can be used to implement optimistic concurrency or to detect external changes public interface Resource // ... { int RESOURCE__TIME_STAMP = 8; long getTimeStamp(); void setTimeStamp(long timeStamp); // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 91
  • 92. Resource Modification Tracking • A resource can track modification of its contents – It’s implemented using adapters on the tree of content – It’s quite expensive and hence is optional and not enabled by default – Typically the state of the command stack is used to track changes • This provides better support for undo reversing a modification public interface Resource // ... { int RESOURCE__IS_TRACKING_MODIFICATION = 5; boolean isTrackingModification(); void setTrackingModification(boolean isTrackingModification); int RESOURCE__IS_MODIFIED = 3; boolean isModified(); void setModified(boolean isModified); // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 92
  • 93. Resource Diagnostics • Problems encountered when loading a resource are recorded as diagnostics describing the problem public interface Resource // ... { int RESOURCE__ERRORS = 6; EList<Diagnostic> getErrors(); int RESOURCE__WARNINGS = 7; EList<Diagnostic> getWarnings(); interface Diagnostic { String getMessage(); String getLocation(); int getLine(); int getColumn(); } // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 93
  • 94. Resource Unloading • A resource can be unloaded to discard any changes – It returns to the state it was in when first created – All the contained objects are converted to proxies so that references to them will try to resolve again – The resource can subsequently be loaded again public interface Resource // ... { void unload(); // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 94
  • 95. Resource Deletion • A resource can be deleted – The resource set’s URI converter is used to delete the state associated with the resource’s URI – Then the resource is unloaded, hence converting all its contents to proxies – Finally the resource is removed from the resource set public interface Resource // ... { void delete(Map<?, ?> options) throws IOException; // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 95
  • 96. Containment References Revisited • In order to persist an object, it must be contained by a resource, i.e., – It must either be directly a member of a resource’s contents list – Or it must be possible to reach such a direct member object by walking up the eContainer() chain – Typically eResource() and eContainer() are mutually exclusive • That means adding an object to a resource’s contents removes it from its current container Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 96
  • 97. Moving a Tree Model Instance ResourceSet Resource child = resources resourceSet.createResource (URI.createFileURI (quot;c:/Child.treequot;)); Resource Resource child.getContents().add(a); resourceSet resourceSet uri file:/c:/Root.tree uri file:/c:/Child.tree contents contents Node eContainer eResource label Root children A parent Node eContainer eResource label A children parent Root Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 97
  • 98. Cross References Revisited • A reference that is neither a containment nor the opposite of a containment, i.e., a container, is a cross reference – Cross references can span not only objects within a containment tree but also objects across different resources – Cross references require specialized serialization support – An EObject knows all its cross references public interface EObject // ... { EList<EObject> eCrossReferences(); // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 98
  • 99. URI Access EObjects • A full URI that includes a fragment denotes an EObject – The URI that is left when the fragment is trimmed denotes a resource – The fragment itself locates the object within that resource – The resource is responsible for producing a fragment that it can subsequently use to locate the object • Given a Resource r and an EObject x the following is always true r.getEObject(r.getURIFragment(x)) == x public final class URI public interface Resource // ... { { public String fragment(); EObject getEObject(String uriFragment); public URI trimFragment(); String getURIFragment(EObject eObject); public URI appendFragment(String fragment); // ... // ... } } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 99
  • 100. Locating or Demand Loading an EObject • An EObject can be located or demand loaded in a resource set – The URI fragment is trimmed and used to locate or demand load the resource it denotes – If one is found, the fragment is used to locate the object within that resource public interface ResourceSet // ... { EObject getEObject(URI uri, boolean loadOnDemand); // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 100
  • 101. URI Fragments • URI fragment can take one of several different forms – Fragment paths • The fragment is a path that consists of /-separated segments that are used to navigate to the object starting from the root of the resource – Keys • A combination of attributes that uniquely identify the object within a given reference – Intrinsic IDs • A unique string stored as data on the object itself – Extrinsic IDs • Unique strings associated with the objects but maintained by the resource Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 101
  • 102. URI Fragment Paths • The fragment starts with a root segment determined by the resource – By default a numeric indexing scheme is used, i.e., the zero-based index of the root object in the resource’s contents • /0 denotes the first root object and the 0 is optional – The remaining segments are computed by the objects themselves using the InternalEObject API • The modeled objects may specialize their segment syntax • The default implementation uses @feature-name[.index] public interface InternalEObject // ... { String eURIFragmentSegment(EStructuralFeature eFeature, EObject eObject); EObject eObjectForURIFragmentSegment(String uriFragmentSegment); // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 102
  • 103. URI Fragment Paths with Keys • The index-based default segment syntax within a multi- valued reference is fragile with respect to list reordering • Keys can be used to make this more robust – An EReference can designate one or more of the EAttributes of its referenced EClass as uniquely identifying each object in that reference – This yields a syntax in the following form, where the square brackets are part of the actual segment rather than denoting optionality @feature-name[key='value1',key2='value2'] public interface EReference // ... { EList<EAttribute> getEKeys(); // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 103
  • 104. URI Fragment Intrinsic IDs • Any path-based mechanism will be fragile with respect to restructuring of the tree • IDs can be used to make this more robust – An EAttribute can be designed as the ID of its containing EClass – The string value of this attribute will be used directly as the fragment – This string value must be unique with respect to all other objects (of all types) within the same resource – This uniqueness requirement makes them a bit difficult and expensive to maintain public interface EAttribute// ... { boolean isID(); // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 104
  • 105. URI Fragment Extrinsic IDs • Because not all models are able to maintain IDs as data within the instances themselves, a resource implementation can manage a two way object-to-ID mapping within the resource – XMLResource supports that approach • A specific attribute can be set as corresponding to the ID in the serialization, e.g., xmi:id • By specializing useUUIDs to return true, universally unique IDs are generated automatically as needed • UUIDs and ID maps take up a lot of space! ~175 bytes per object public class EcoreUtil { public static String generateUUID(); // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 105
  • 106. Saving Cross Document References ResourceSet ResourceSet resourceSet = resources new ResourceSetImpl(); Resource resource = Resource Resource resourceSet.getResource resourceSet resourceSet (URI.createFileURI(quot;c:/Root.treequot;), <?xml version=quot;1.0quot; encoding=quot;ASCIIquot;?> uri file:/c:/Root.tree uri file:/c:/Map.tree true); <tree:Node xmi:version=quot;2.0quot; contents contents Resource map = xmlns:xmi=quot;http://www.omg.org/XMIquot; resourceSet.createResource xmlns:tree=quot;http://www.example.org/treequot; Node Node (URI.createFileURI(quot;c:/Map.treequot;)); label=quot;Rootquot;> eContainer eContainer EcoreUtil.Copier copier = <children label=quot;Aquot;> new EcoreUtil.Copier(); eResource eResource <data href=quot;Root.tree#//@children.0quot;/> label label Root Root map.getContents().addAll </children> children A children A (copier.copyAll (resource.getContents())); href=quot;Root.tree#/quot;/> <data parent parent data data for (Iterator<EObject> </tree:Node> i= resource.getAllContents(); Node Node i.hasNext(); ) { eContainer eContainer EObject eObject = i.next(); eResource eResource ((Node)copier.get(eObject)). label A label A setData(eObject); children children } parent Root parent Root resource.save(null); data data Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 106
  • 107. Proxies • EMF supports the concept of a proxy – A proxy is just a regular instance that acts as a proxy – Internally it stores the proxy URI, i.e., the URI of the EObject to which the proxy should resolve – The proxy URI can be set by the de-serializer and is set for each object when a resource is unloaded public interface EObject public interface InternalEObject // ... { extends EObject boolean eIsProxy(); { // ... URI eProxyURI(); } void eSetProxyURI(URI uri); // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 107
  • 108. Proxy Resolution • Generated get methods as well as EMF’s specialized list implementations all resolve proxies on demand – Resolution produces notifications – Resolution demand loads the proxy URI into the resource set public EObject getData() { if (data != null && data.eIsProxy()) { InternalEObject oldData = (InternalEObject)data; data = eResolveProxy(oldData); if (data != oldData) { if (eNotificationRequired()) eNotify (new ENotificationImpl (this, Notification.RESOLVE, TreePackage.NODE__DATA, oldData, data)); } } return data; } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 108
  • 109. Loading Cross Document References ResourceSet ResourceSet resourceSet = resources new ResourceSetImpl(); Resource resource = Resource Resource resourceSet.getResource resourceSet resourceSet (URI.createFileURI(quot;c:/Map.treequot;), uri file:/c:/Map.tree uri file:/c:/Root.tree true); contents contents Node node = (Node)resource.getContents().get(0); Node Node assert !node.getData().eIsProxy(); eContainer eContainer eResource eResource Node child = label Root label Root node.getChildren().get(0); children A children A assert child.getData().eIsProxy(); parent parent data data Node eProxyURI file:/c:/Root.tree#/ Node Node eContainer eContainer eResource eResource Node label A label A eProxyURI file:/c:/Root.tree#//@children.0 children children parent Root parent Root data data Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 109
  • 110. Cross Resource Containment • There is optional support for cross resource containment that applies only for proxy resolving containment references; in that case – An object added to that reference will not be removed from its directly containing resource – An object added to a resource’s contents will not be remove from such a containment Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 110
  • 111. A Cross Contained Tree Model Instance ResourceSet Resource child = resources resourceSet.createResource (URI.createFileURI (quot;c:/Child.treequot;)); Resource Resource resourceSet resourceSet child.getContents().add(a); <?xml version=quot;1.0quot; encoding=quot;ASCIIquot;?> uri uri file:/c:/Root.tree file:/c:/Child.tree <tree:Node xmi:version=quot;2.0quot; contents contents resource.save(System.out, null); xmlns:xmi=quot;http://www.omg.org/XMIquot; child.save(System.out, null); xmlns:tree=quot;http://www.example.org/treequot; Node label=quot;Aquot;> label=quot;Rootquot;> eContainer <parent href=quot;Root.tree#/quot;/> <children href=quot;Child.tree#/quot;/> eResource </tree:Node> label Root children A parent Node eContainer eResource label A children parent Root Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 111
  • 112. Specialized Resource Implementations • Implementing a specialized resource involves overriding the doSave and doLoad methods of ResourceImpl • EMF provides a number of specialized implementations that support – XML serialization – XMLResourceImpl – XMI serialization – XMIResourceImpl – Fast compact binary serialization – BinaryResourceImpl – Database persistence (Teneo) – Distributed shared access (CDO) – Repository (JCRM) Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 112
  • 113. Options to Configure Resource Load and Save • The resource factory is the place to configure load and save options to be used by all clients public class TreeResourceFactoryImpl extends ResourceFactoryImpl { @Override public Resource createResource(URI uri) { XMLResource result = new TreeResourceImpl(uri); result.getDefaultSaveOptions().put(XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE); result.getDefaultLoadOptions().put(XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE); result.getDefaultSaveOptions().put(XMLResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE); result.getDefaultLoadOptions().put(XMLResource.OPTION_USE_ENCODED_ATTRIBUTE_STYLE, Boolean.TRUE); result.getDefaultSaveOptions().put(XMLResource.OPTION_USE_ENCODED_ATTRIBUTE_STYLE, Boolean.TRUE); result.getDefaultLoadOptions().put(XMLResource.OPTION_USE_LEXICAL_HANDLER, Boolean.TRUE); return result; } // … } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 113
  • 114. General Resource Options • Saving only if the result differs from the current content – Resource.OPTION_SAVE_ONLY_IF_CHANGED • Resource.OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER • Resource.OPTION_SAVE_ONLY_IF_CHANGED_FILE_BUFFER • Encrypting and decrypting the bytes – Resource.OPTION_CIPHER • A URIConverter.Cipher instance – AESCipherImpl – DESCipherImpl • Compressing and decompressing the bytes – Resource.OPTION_ZIP • A Boolean.TRUE or Boolean.FALSE Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 114
  • 115. Loading from a String or a Reader • The resource APIs work with InputStreams but you may need to process a String or a Reader and can avoid needless char -> byte -> char conversion – A stream that implements URIConverter.Readable will be unwrapped and used directly if the underlying resource supports that – An implementation is provided, URIConverter.ReadableInputStream • It converts to bytes using the encoding if necessary interface Readable { Reader asReader(); String getEncoding(); } class ReadableInputStream extends InputStream implements Readable { public ReadableInputStream(Reader reader, String encoding) public ReadableInputStream(Reader xmlReader) public ReadableInputStream(String string, String encoding) public ReadableInputStream(String xmlString) } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 115
  • 116. Saving to a String or a Writer • The resource APIs work with OutputStreams but you may need to process a String or a Writer and can avoid needless char -> byte -> char conversion – A stream that implements URIConverter.Writeable will be unwrapped and used directly if the underlying resource supports that – An implementation is provided, URIConverter.WriteableInputStream • It converts to bytes using the encoding if necessary interface Writeable { Writer asWriter(); String getEncoding(); } static class WriteableOutputStream extends OutputStream implements Writeable { public WriteableOutputStream(Writer writer, String encoding); } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 116
  • 117. Exercise 2 Programming with Resources Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 117
  • 118. EMF Resource Best Practices • There are a number of ways in which you can tweak the nature of the serializations that EMF gives you based on its built-in support for XML (and XMI) resources • In general, these tweaks take place in one of three places – the Ecore model, the generator model, or the code • We'll consider each of these in turn and look at the impact various choices have on serialized data, using our sample model Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 118
  • 119. Sample Model Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 119
  • 120. The Ecore Model (The Good?) • An Ecore model is the specification of metadata for your domain (i.e., your data) • Settings you specify in the Ecore model have a direct impact on the – namespace and prefix that are using in your serializations – names of the elements and attributes that are serialized (and in fact when an attribute is used vs. when and attribute is) – way references between elements are serialized (including whether a containment hierarchy can be spread over more than one resource) Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 120
  • 121. Namespace URIs • The namespace URI defines a unique namespace for data based on your metamodel • This URI will correspond to the (second portion of the) xmlns declaration that appears at the beginning of an XML/XMI serialization <tree:Node xmi:version=quot;2.1quot; xmlns:xmi=quot;http://schema.omg.org/spec/XMI/2.1quot; xmlns:tree=quot;http://www.eclipsecon2009.org/emf/1.0/Treequot; id=‚rootquot; label=quot;Rootquot; kind=quot;Rootquot;/> Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 121
  • 122. Namespace URIs • An Ecore package has an 'Ns URI' property that must be set to the desired string Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 122
  • 123. Namespace URIs • Not only is it important that this URI be unique (as with all URIs), but it must ideally contain information about the version of the metamodel's schema (yes, a metamodel definition effectively defines a schema for its instance documents) • Every change to this schema must be accompanied by a change to this version information • One convention commonly used in the industry is to include the year in a URI as the version indicator – This may be OK for schemas that don't change very frequently (e.g., those maintained by standards or specifications bodies like the OMG) – In practice, it's common for more than one version of a schema to be defined in the same calendar year, so a better convention is to use the version number of the component in which the metamodel is defined • For an organization, it's also typically important for namespace URIs to be of a consistent form Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 123
  • 124. Best Practice #1 The namespace URI defined for a resource serialization should be of the form 'http://<organization domain>/<project name>/<project version>/<schema name>' Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 124
  • 125. Namespace Prefixes • The namespace prefix defines short name that's used to qualify serialized elements representing data based on your metamodel • The namespace prefix will correspond to the (the first portion of the) xmlns declaration that appears at the beginning of an XML/XMI serialization <tree:Node xmi:version=quot;2.1quot; xmlns:xmi=quot;http://schema.omg.org/spec/XMI/2.1quot; xmlns:tree=quot;http://www.eclipsecon2009.org/emf/1.0/Treequot; id=quot;rootquot; label=quot;Rootquot; kind=quot;Rootquot;/> Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 125
  • 126. Namespace Prefixes • The namespace prefix also appears as a qualifier in xmi:type declarations referencing types from the namespace throughout the document <child xmi:type=quot;tree:Nodequot; id=quot;childquot; label=quot;Childquot;/> Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 126
  • 127. Namespace Prefixes • An Ecore package has an 'Ns Prefix' property that must be set to the desired string Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 127
  • 128. Namespace Prefixes • The prefix is actually arbitrary, but must be unique within a given XML/XMI document • Typically this string corresponds to the last segment of the namespace URI, but in lower case Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 128
  • 129. Best Practice #2 The namespace prefix defined for a resource serialization should be of the form '<lowercase schema name>' (relative to the recommended namespace URI form) Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 129
  • 130. Extended Metadata Annotations • EMF uses annotations as a way of attaching additional information to an Ecore (or generator) model which isn't considered part of the semantics but is used for other (downstream) processing, for example code generation or serialization • It's analogous to the way UML uses stereotypes (for those familiar with UML) • Every annotation used by EMF has a quot;sourcequot;, which is typically a URI that uniquely identifies a class of annotations Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 130
  • 131. Extended Metadata Annotations • Common annotation sources used in EMF include 'http://www.eclipse.org/emf/2002/GenModel' (for code generation) and 'http:///org/eclipse/emf/ecore/util/ExtendedMetaData' (for extended metadata™) Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 131
  • 132. Extended Metadata Annotations • An EMF annotation also has a details map in which simple key-value pairs (both strings) can be stored • These details are analogous to tagged values in UML • Extended metadata annotation details can be used to affect the way data elements are mapped to and from XML/XMI during serialization and deserialization Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 132
  • 133. Extended Metadata Annotations • Two such details keys for extended metadata are 'name', which determines the XML name for the annotated element, and 'kind', which determines the kind of XML element (i.e., attribute or element) Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 133
  • 134. Extended Metadata Annotations • One common use for extended metadata is to specify an alternative name for a feature when it is serialized to XML/XMI, in particular when the name of the feature is plural • In the sample model, a 'name' detail key has been added to the 'iD' and 'children' features with a values of 'id' and 'child' • When serializing without this extended metadata (which, even if defined in an annotation, must be explicitly enabled), the corresponding XML names would be based directly on the feature names <children xmi:type=quot;tree:Nodequot; iD=quot;child1quot; label=quot;Child 1quot;/> <children xmi:type=quot;tree:Nodequot; iD=quot;child2quot; label=quot;Child 2quot;/> Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 134
  • 135. Extended Metadata Annotations • Serializing based on the extended metadata, however, results in the more desirable names (e.g., every occurrence of the element defines a single child, and hence its XML name should be singular, but the accessor method in Java should probably be based on the plural feature name) <child xmi:type=quot;tree:Nodequot; id=quot;child1quot; label=quot;Child 1quot;/> <child xmi:type=quot;tree:Nodequot; id=quot;child2quot; label=quot;Child 2quot;/> Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 135
  • 136. Extended Metadata Annotations • Generally speaking, the 'kind' details entry must also be specified any time a 'name' entry is specified • By default, every Ecore attribute maps to an XML attribute and every reference maps to an XML attribute iff it references an element in the same document (i.e., via an idref), otherwise an XML element (i.e., either a sub- element or an href) Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 136
  • 137. Best Practice #3 Extended metadata should be used in resource serializations to achieve more desirable XML names Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 137
  • 138. ID Attributes • EMF supports the identification of an Ecore attribute as an identifier • The significance of marking an attribute as an identifier is that it value can be used as the means of linking elements in XML/XMI serializations • The value of an identifier attribute must be unique within a given context, and for the purposes of (de)serialization, that context is a resource (XML/XMI document) Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 138
  • 139. ID Attributes • An Ecore attribute has an 'ID' property that must be set to 'true' for identifier attributes Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 139
  • 140. ID Attributes • One problem with identifier attributes is that, if their values are allowed to be modified via the API, clients can inadvertently introduce broken references • To alleviate this concern, visibility of the setter for that attribute can be suppressed using a generator model annotation Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 140
  • 141. Proxy Resolution • EMF uses proxies to resolve references between objects (potentially in different resources) on demand • Support for this mechanism is provided by the EMF framework and invoked by generated code by default • Of course, this proxy resolution behavior comes at a cost, so one must carefully consider where is in fact needed – there are cases, for example when you know that a referencing element will always be in the same resource (XML/XMI document) as a referenced element, when it isn't Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 141
  • 142. Proxy Resolution • An Ecore reference has a 'Resolve Proxies' property that must be set to 'true' or 'false', depending on whether EMF's proxy resolution mechanism is required Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 142
  • 143. Proxy Resolution • Generally speaking, a container (parent) element will always be in the same resource as its contained (child) elements (as is the case above, for an object root and its object identifier), so proxy resolution isn't needed, by default, for containment references • However, if you intend to support containment proxies for your resources (i.e., separate elements within a given containment hierarchy over multiple resources), proxy resolution must be enabled Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 143
  • 144. The Generator Model (The Bad?) • The generator model is a decorator for an Ecore model that specifies additional information used during code generation • The generator model offers an ever-growing number of options that allow you to customize the code that EMF generates • Among these options are ones that affect – the file extension and content type that will be defined (by default) for your resources – what kind of resource serialization will be used (basically XML or XMI) – whether cross-resource containment proxies will be supported Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 144
  • 145. File Extensions • File extensions are gradually becoming a thing of the past; what should really matter is the type of content contained in a document • Support for content type definition wasn't introduced until EMF 2.4, so for a while longer at least, file extensions are still important • EMF provides a registry that associates resource factories (and hence the resources they create) with file extensions Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 145
  • 146. File Extensions • Registration of a resource factory against a file extension can be done via a plug-in extension point (for applications based on Eclipse) <extension point=quot;org.eclipse.emf.ecore.extension_parserquot;> <parser type=quot;treequot; class=‚org.eclipsecon2009.emf.tree.util.TreeResourceFactoryImplquot;/> </extension> Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 146
  • 147. File Extensions • What this plug-in extension does is register the tree resource factory implementation (from our sample model) against resources (files) with a '.tree' file extension • This means is that applications using a resource set to create an EMF resource for a given URI will obtain the corresponding resource implementation (from the registry) by default; unless, that is, this default (global) registration is overridden locally in the resource set (every resource set has a local registry which delegates to the global one) • Note that once this plug-in extension is generated (as part of the plug-in's manifest file, plugin.xml), EMF won't overwrite it, so if you decide to change the file extension later, you'll need to update it manually Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 147
  • 148. File Extensions • Another plug-in extension that depends on file extension is in the manifest for the generated editor plug-in <editor id=‚org.eclipsecon2009.emf.tree.presentation.TreeEditorIDquot; name=quot;%_UI_TreeEditor_labelquot; icon=quot;icons/full/obj16/TreeModelFile.gifquot; extensions=quot;treequot; class=‚org.eclipsecon2009.emf.tree.presentation.TreeEditor‚ contributorClass=‚org.ecipsecon2009.emf.tree.presentation.TreeActionBarContributorquot;> </editor> Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 148
  • 149. File Extensions • This plug-in extension registers the generated editor against the file extension so that, by default, resources with that extension will be opened with the specified editor • As with the resource factory registration, be sure to update this value manually if you change the extension (assuming you're generating and using the sample editor) Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 149
  • 150. File Extensions • Another place where the file extension appears is in the plugin.properties file of the generated editor plug-in _UI_TreeEditorFilenameExtensions = tree Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 150
  • 151. File Extensions • This string is used by the generated wizard when creating new instance documents based on your model • While EMF does update properties files when new classes or features are introduced into a model, it doesn't automatically remove them and won't overwrite their values, so again, if you change your file extension, don't forget to change this value Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 151
  • 152. File Extensions • So, where does the value for this file extension actually come from? • It's based on the value specified via the 'File Extensions' property of a package in the EMF generator model Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 152
  • 153. Content Types • EMF provides a registry that associates resource factories (and hence the resources they create) with content types • Registration of a resource factory against a content type can be done via a plug-in extension point (for applications based on Eclipse) <extension point=quot;org.eclipse.emf.ecore.content_parserquot;> <parser contentTypeIdentifier=“org.eclipsecon2009.emf.treequot; class=‚org.eclipsecon2009.emf.tree.util.TreeResourceFactoryImplquot;/> </extension> Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 153
  • 154. Content Types • What this plug-in extension does is register the tree resource factory implementation (from our sample model) against resources with the ‘org.eclipsecon2009.emf.tree' content type • This means is that applications using a resource set to create an EMF resource for URI with a particular content type will obtain the corresponding resource implementation (from the registry) by default (unless it is overridden locally in the resource set) • Note that once this plug-in extension is generated EMF won't overwrite it, so if you decide to change the content type later, you'll need to update it manually Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 154
  • 155. Content Types • EMF will also generate a plug-in extension to register the content type, and an associated content describer, with the Eclipse platform <content-type base-type=quot;org.eclipse.emf.ecore.xmiquot; file-extensions=quot;treequot; id=“org.eclipsecon2009.emf.treequot; name=quot;%_UI_Tree_content_typequot; priority=quot;normalquot;> <describer class=quot;org.eclipse.emf.ecore.xmi.impl.RootXMLContentHandlerImpl$Describerquot;> <parameter name=quot;namespacequot; value=quot;http://www.eclipsecon2009.org/emf/1.0/Treequot; /> <parameter name=quot;kindquot; value=quot;xmiquot; /> </describer> </content-type> Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 155
  • 156. Content Types • Since the default content describer is specific to the namespace URI of your metamodel, which in turn is version-specific, it’s generally better to change this declaration to match by namespace pattern <content-type base-type=quot;org.eclipse.emf.ecore.xmiquot; file-extensions=quot;treequot; id=‚org.eclipsecon2009.emf.treequot; name=quot;%_UI_Tree_content_typequot; priority=quot;normalquot;> <describer class=quot;org.eclipse.emf.ecore.xmi.impl.RootXMLContentHandlerImpl$Describerquot;> <parameter name=quot;namespacePatternquot; value=quot;http://www.eclipsecon2009.org/emf/(1.0|1.1)/Treequot; /> <parameter name=quot;kindquot; value=quot;xmiquot; /> </describer> </content-type> Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 156
  • 157. Content Types • A new version-specific content type declaration can then be defined, as a child of the base declaration, each time your metamodel changes <content-type base-type=“org.eclipsecon2009.emf.treequot; file-extensions=quot;treequot; id=‚org.eclipsecon2009.emf.tree_1_0quot; name=quot;%_UI_Tree_1_0_content_typequot; priority=quot;normalquot;> <describer class=quot;org.eclipse.emf.ecore.xmi.impl.RootXMLContentHandlerImpl$Describerquot;> <parameter name=quot;namespacequot; value=quot;http://www.eclipsecon2009.org/emf/1.0/Treequot; /> <parameter name=quot;kindquot; value=quot;xmiquot; /> </describer> </content-type> Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 157
  • 158. Content Types • Another extension that depends on content type is in the manifest for the generated editor plug-in <editor id=‚org.eclipsecon2009.emf.tree.presentation.TreeEditorIDquot; name=quot;%_UI_TreeEditor_labelquot; icon=quot;icons/full/obj16/TreeModelFile.gifquot; class=‚org.eclipsecon2009.emf.tree.presentation.TreeEditor‚ contributorClass=‚org.eclipsecon2009.emf.tree.presentation.TreeActionBarContributorquot;> <contentTypeBinding contentTypeId=“org.eclipsecon2009.emf.treequot;/> </editor> Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 158
  • 159. Content Types • This plug-in extension registers the generated editor against the content type so that, by default, resources with that content type will be opened with the specified editor • As with the resource factory registration, be sure to update this value manually if you change the content type identifier (assuming you're generating and using the sample editor) Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 159
  • 160. Content Types • So, where does the value for this content type identifier actually come from? • It's based on the value specified via the ‘Content Type Identifier' property of a package in the EMF generator model Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 160
  • 161. Best Practice #4 A new content type (and describer) should be registered each time your metamodel changes Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 161
  • 162. Resource Types • As previously mentioned, EMF provides support for serializing resources in XML or XMI format • The choice between the two depends on what you're looking to do, but XMI resources are generally more flexible (e.g., they support cross-resource containment and the use of XMI identifiers), so XMI is probably the better choice Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 162
  • 163. Resource Types • The value of the 'Resource Type' property of a package in the EMF generator model can be set (to 'None', 'Basic', 'XML', or 'XMI') to specify the desired resource type Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 163
  • 164. Best Practice #5 The resource type for resource serializations should be XMI (unless the source model is an XML schema) Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 164
  • 165. Containment Proxies • EMF supports the partitioning of an object hierarchy (containment tree) across multiple resources • To do so, the framework makes a distinction between containment proxies (references from parent objects to child objects in different resources) and non-containment (or cross-reference) proxies (references from objects to objects in other resources) • Since support for proxy resolution requires a certain amount of overhead (via a specialized list implementation), the choice to enable cross-resource containment via containment proxies has to be made explicitly based on the needs of your resource implementation Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 165
  • 166. Containment Proxies • Why would one want to enable containment proxies? • One reason is that they go a long way toward supporting a scalable architecture where objects within a (potentially large) containment tree can be loaded and unloaded dynamically as part of separate resources, thereby reducing the concurrent memory footprint Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 166
  • 167. Containment Proxies • The value of the 'Containment Proxies' property of the model (root node) in an EMF generator model can be set to 'true' to enable cross-resource containment • Of course, in order for a given containment reference to support containment proxies, the 'Resolve Proxies' property must be set to 'true' in the Ecore model Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 167
  • 168. Best Practice #6 Containment proxies should be enabled for all resource serializations Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 168
  • 169. The Code (The Ugly?) • The code is, well, the code • Here, though, we’re referring specifically to the code that gets generated for you by EMF and some of the framework customizations that EMF makes available • The main things to consider here are – what character encoding will be used – which version of XMI will be used – what form of identifiers will be used (i.e., in references via idref or href attributes) – what the default load and save options will be for documents based on your resource implementation Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 169
  • 170. Encoding • EMF supports a number of different encoding choices for resources – ASCII, UTF-8, UTF-16, UTF-16BE, UTF-16LE, ISO-8859-1 • The most versatile and/or commonly used of these is UTF-8 • The encoding for a given serialization will appear on the first line of the XML/XMI document <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 170
  • 171. Encoding • The encoding of an EMF resource can be set programmatically using the XMLResource#setEncoding(String) method • Generally speaking, however, its a good idea to hard-code the default encoding for a resource into its (generated) resource implementation class by marking the constructor as @generated NOT and adding the method call /** * Creates an instance of the resource. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @param uri the URI of the new resource. * @generated NOT */ public TreeResourceImpl(URI uri) { super(uri); setEncoding(quot;UTF-8quot;); // ... } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 171
  • 172. Best Practice #7 The default encoding of all resource serializations should be quot;UTF-8quot; Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 172
  • 173. XMI Versions • Technically speaking, the (de)serialization support provided for XML and XMI by EMF supports only a subset of the full syntax dictated by the corresponding specifications for these schemas • An XML or XMI serialization produced using EMF should be well-formed and valid (assuming the right options are used) • But well-formed, valid document produced with other tools that use a larger subset of constructs may not necessarily be handled very well by EMF Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 173
  • 174. XMI Versions • The support EMF provides for specific versions of XMI (2.0 or 2.1), then, is really only a statement of intent (e.g., quot;we'll say we support it until someone complains that we don'tquot;) • Nevertheless, most modern tools that produce XMI serializations do so using XMI version 2.1 • The version of XMI used in a given serialization appears in the first element of the document Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 174
  • 175. XMI Versions • Here we see, based on the xmi:version and xmlns:xmi attributes, a document that's been serialized using XMI version 2.1 • A document based on XMI 2.0 (the only other real alternative) would have an xmi:version of quot;2.0quot; and an xmlns:xmi of quot;http://www.omg.org/XMIquot; <tree:Node xmi:version=quot;2.1quot; xmlns:xmi=quot;http://schema.omg.org/spec/XMI/2.1quot; xmlns:tree=quot;http://www.eclipsecon2009.org/emf/1.0/Treequot; xmi:id=quot;rootquot; label=quot;Rootquot; kind=quot;Rootquot;/> Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 175
  • 176. XMI Versions • The XMI version an EMF resource can be set programmatically using the XMIResource#setVersion(String) method • Generally speaking, however, its a good idea to hard-code the default XMI version for a resource into its (generated) resource implementation class by marking the constructor as @generated NOT and adding the method call /** * Creates an instance of the resource. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @param uri the URI of the new resource. * @generated NOT */ public TreeResourceImpl(URI uri) { super(uri); // ... setXMIVersion(quot;2.1quot;); } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 176
  • 177. Best Practice #8 The default XMI version of a resource serialization should be quot;2.1quot; Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 177
  • 178. Identifiers • As mentioned previously in the context of ID attributes, EMF provides support for the use of identifiers in serializing references between elements in XML/XMI • Generally speaking, in order for an element in an XMI serialization to be referenceable, it must either have a value for the xmi:id attribute (the more common case) or for an attribute that has been designated as its ID attribute, and all references to the element (via idrefs and hrefs) must be based on that value Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 178
  • 179. Identifiers • If your metamodel has ID attributes, whose values you want used for references serialized to XMI, there are a couple of things you should do • First, you'll want to enable the use of the intrinsic identifier cache to improve the performance of object look-ups /** * Creates an instance of the resource. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @param uri the URI of the new resource. * @generated NOT */ public TreeResourceImpl(URI uri) { super(uri); // ... setIntrinsicIDToEObjectMap(new HashMap<String, EObject>()); } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 179
  • 180. Identifiers • The second thing you'll need to do (assuming the cache has been enabled) is ensure that any time the value of an ID attribute changes in the model, the resource's mapping of intrinsic identifiers to objects is updated • In our sample model, we need to update the mapping (e.g. clear the cache) if the ‘iD’ attribute changes Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 180
  • 181. Identifiers public void setIDGen(String newID) { String oldID = iD; iD = newID; if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, TreePackage.NODE__ID, oldID, iD)); } public void setID(String newID) { Resource eResource = eResource(); if (eResource instanceof TreeResourceImpl) { ((TreeResourceImpl) eResource).getIntrinsicIDToEObjectMap().clear(); } setIDGen(newID); } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 181
  • 182. Identifiers • Here we see use of the other code customization pattern – marking the original method with a 'Gen' suffix and introducing a new method with the original signature which delegates to it • This pattern is useful in cases where you want to preserve the original behavior, but do some additional processing before and/or after it is executed Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 182
  • 183. Identifiers • If your metamodel does not make use of ID attributes, a dead simple alternative for ensuring that XMI identifiers are serialized is to use UUIDs – Universally Unique Identifiers • EMF provides built-in support for automatic generation and (de)serialization of UUIDs as XMI identifiers @Override protected boolean useUUIDs() { return true; } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 183
  • 184. Identifiers • When using UUIDs, a unique identifier is assigned to an object as soon as is attached to a resource, and it is preserved even of the object is later detached from on resource and attached to another • The format of the UUIDs generated by EMF are based on a standard 128 bit UUID (see ftp://ietf.org/internet- drafts/draft-mealling-uuid-urn-02.txt) but encoded into a padded base 64 string <child xmi:type=quot;tree:Nodequot; xmi:id=quot;_cKLewOvxEdyeZZzrmWnnqgquot; label=quot;Childquot;/> Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 184
  • 185. Best Practice #9 All references in XMI resource serializations should be based on the value for an ID attribute or xmi:id Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 185
  • 186. Save Options • EMF provides many save options which can be used to tweak the way resources are serialized to XML/XMI • We'll cover a few of the important ones here, but encourage you to explore all the various options available • To set or enable these options by default, the createResource(URI) method of the resource factory implementation class must be customized Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 186
  • 187. Save Options /** * Creates an instance of the resource. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated NOT */ @Override public Resource createResource(URI uri) { XMIResource result = new TreeResourceImpl(uri); // ... Map<Object, Object> defaultSaveOptions = result.getDefaultSaveOptions(); // ... return result; } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 187
  • 188. Save Options • The XMLResource.OPTION_EXTENDED_META_DATA option, as alluded to earlier, must be enabled in order to respect extended metadata annotations that have been attached to your Ecore model • To enable this option, add an entry to the options map with XMLResource.OPTION_EXTENDED_META_DATA as the key and Boolean.TRUE as the value defaultSaveOptions.put(XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE); Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 188
  • 189. Save Options • The XMIResource.OPTION_USE_XMI_TYPE option will ensure that xmi:type attributes are used instead of xsi:type attributes (as seen earlier); the former are obviously more desirable in XMI serializations • To enable this option, add an entry to the options map with XMLResource.OPTION_USE_XMI_TYPE as the key and Boolean.TRUE as the value defaultSaveOptions.put(XMIResource.OPTION_USE_XMI_TYPE, Boolean.TRUE); Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 189
  • 190. Save Options • The XMLResource.OPTION_SAVE_TYPE_INFORMATION tells EMF when to save type information in xmi:type attributes • Strictly speaking EMF doesn't always need to save type information because it can obtain it from the metamodel (e.g., if the type of the object is the same as the type of the feature) • However, there are cases, particularly in migration scenarios (where the type of a feature may have changed in newer versions of the schema), where it is useful to serialize type information more often than EMF does by default Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 190
  • 191. Save Options • The extreme option is to always save type information; this can be achieved by adding an entry to the options map with XMLResource.OPTION_SAVE_TYPE_INFORMATION as the key and Boolean.TRUE as the value • A more reasonable compromise is to pass an anonymous subclass of XMLTypeInfo that specifies exactly when the type information needs to be saved Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 191
  • 192. Save Options defaultSaveOptions.put(XMLResource.OPTION_SAVE_TYPE_INFORMATION, new XMLTypeInfo() { public boolean shouldSaveType(EClass objectType, EClassifier featureType, EStructuralFeature feature) { return objectType != featureType && objectType != XMLTypePackage.Literals.ANY_TYPE; } public boolean shouldSaveType(EClass objectType, EClass featureType, EStructuralFeature feature) { return objectType != featureType; } } ); Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 192
  • 193. Load Options • EMF also provides many load options which can be used to tweak the way resources are de-serialized from XML/XMI • We'll cover a few of the important ones here, but encourage you to explore all the various options available • To set or enable these options by default, the createResource(URI) method of the resource factory implementation class must be customized Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 193
  • 194. Load Options /** * Creates an instance of the resource. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated NOT */ @Override public Resource createResource(URI uri) { XMIResource result = new TreeResourceImpl(uri); // ... Map<Object, Object> defaultLoadOptions = result.getDefaultLoadOptions(); // ... return result; } Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 194
  • 195. Load Options • The XMLResource.OPTION_EXTENDED_META_DATA option can also be used during de-serialization, and must be enabled in order to recognize data that has been serialized based on extended metadata annotations • To enable this option, add an entry to the options map with XMLResource.OPTION_EXTENDED_META_DATA as the key and Boolean.TRUE as the value defaultLoadOptions.put(XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE); Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 195
  • 196. Load Options • The XMLResource.OPTION_DEFER_IDREF_RESOLUTION option instructs EMF to defer resolution of same document references until the end of the document is reached • Depending on the nature and order of cross-references in your data this option may be required in order to successfully de-serialize XML/XMI documents based on them; even if it isn't required, this option improves load performance, so it should generally be used Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 196
  • 197. Load Options • To enable this option, add an entry to the options map with XMLResource.OPTION_DEFER_IDREF_RESOLUTION as the key and Boolean.TRUE as the value defaultLoadOptions.put(XMLResource.OPTION_DEFER_IDREF_RESOLUTION, Boolean.TRUE); Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 197
  • 198. Load Options • The XMLResource.OPTION_RECORD_UNKNOWN_FEATURE option tells EMF to preserve unrecognized data (i.e. XML elements and attributes) during de-serialization • Such data are added to a map, accessible via the XMLResource#getEObjectToExtensionMap() method, which can be introspected and processed after a resource has been loaded • The data in this map are then serialized back out the next time the resource is saved Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 198
  • 199. Load Options • This is incredibly useful when dealing with mixed content from unknown sources and/or in migration scenarios where features that existed on an older version of a schema are no longer valid • To enable this option, add an entry to the options map with XMLResource.OPTION_RECORD_UNKNOWN_FEATURE as the key and Boolean.TRUE as the value defaultLoadOptions.put(XMLResource.OPTION_RECORD_UNKNOWN_FEATURE, Boolean.TRUE); Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 199
  • 200. Best Practice #10 Default save and load options (as described here) should be initialized for resource serializations Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 200
  • 201. Exercise 3 Resource Best Practices Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 201
  • 202. Summary • EMF the de facto standard reference implementation • EMF is a low cost modeling solution for Java – SD Times ranks it “top shelf” even relative to pricey commercial software • http://www.sdtimes.com/content/article.aspx?ArticleID=32287 • It exploits the models already underlying the application • It supports iterative development that facilitates both model-based changes and hand-written changes equally well • It boosts productivity by automating routine and mundane development tasks • It’s the foundation for data integration by providing a uniform way to access all models Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 202
  • 203. What’s in EMF 2.5 (Galileo release) • Low memory footprint implementation • Several bug fixes and small features (+120) • Performance improvements Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 203
  • 204. Low Memory Footprint Implementation • Starting with EMF 2.5, it is possible to configure an EMF generator model to produce a model implementation that is optimally tuned for memory efficiency • Several techniques were applied to produce “lean” instances, including – “Flag” fields to store certain information – Shared data storage buffers – “Smart” list implementations • Enabled by changing the ‘Root Extends Class’ property of the generator model (under the ‘Model Class Defaults’ category) to ‚org.eclipse.emf.ecore.impl.MinimalEObject$Container‛. Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 204
  • 205. Conclusion • We have covered – REST and the architectural principles on which it is based – How EMF supports development of RESTful applications in Java via its resource persistence framework – Best practices for working with EMF resources Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 205
  • 206. Resources • Online help – http://help.eclipse.org/ganymede/index.jsp?nav=/14 • Website – http://www.eclipse.org/emf • Downloads • Wiki • FAQ • Newsgroup • Documentation • Book – Eclipse Modeling Framework • Second Edition – http://safari.awprofessional.com/9780321331885 Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 206
  • 207. Legal Notices • OMG and Object Management Group are trademarks of the Object Management Group • UML and XMI are registered trademarks of the Object Management Group • Hypertext Transfer Protocol, HTTP, Metadata, and XML are trademarks of the World Wide Web Consortium; marks of W3C are registered and held by its host institutions MIT, ERCIM, and Keio • Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both • Other company, product, or service names may be trademarks or service marks of others Friday, March 20, 2009 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0 207

×