SlideShare una empresa de Scribd logo
1 de 207
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
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
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
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
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
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
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
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
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
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
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
Ecore Overview




Friday, March 20, 2009   © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0   12
Ecore Data Types




Friday, March 20, 2009   © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0   13
Ecore Annotations and EObject




Friday, March 20, 2009   © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0   14
Ecore Generics




Friday, March 20, 2009   © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0   15
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
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
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
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
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
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
EMF Application Architecture




Friday, March 20, 2009   © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0   22
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
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
A Richer Tree Ecore Model




Friday, March 20, 2009   © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0   25
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
Exercise 1
                                                                                      Code Generation


Friday, March 20, 2009   © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0    51
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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

Más contenido relacionado

La actualidad más candente

Chapitre N°4 Diagramme de séquence.pdf
Chapitre N°4  Diagramme de séquence.pdfChapitre N°4  Diagramme de séquence.pdf
Chapitre N°4 Diagramme de séquence.pdf
SaadiaAjbbar
 
Hibernate Presentation
Hibernate  PresentationHibernate  Presentation
Hibernate Presentation
guest11106b
 

La actualidad más candente (20)

Java entreprise edition et industrialisation du génie logiciel par m.youssfi
Java entreprise edition et industrialisation du génie logiciel par m.youssfiJava entreprise edition et industrialisation du génie logiciel par m.youssfi
Java entreprise edition et industrialisation du génie logiciel par m.youssfi
 
Jdbc in servlets
Jdbc in servletsJdbc in servlets
Jdbc in servlets
 
JavaScript Tutorial
JavaScript  TutorialJavaScript  Tutorial
JavaScript Tutorial
 
Entreprise Java Beans (EJB)
Entreprise Java Beans (EJB)Entreprise Java Beans (EJB)
Entreprise Java Beans (EJB)
 
Introduction àJava
Introduction àJavaIntroduction àJava
Introduction àJava
 
Spring Framework - AOP
Spring Framework - AOPSpring Framework - AOP
Spring Framework - AOP
 
ES2015 / ES6: Basics of modern Javascript
ES2015 / ES6: Basics of modern JavascriptES2015 / ES6: Basics of modern Javascript
ES2015 / ES6: Basics of modern Javascript
 
Les nouveautés de Java 21 - Devoxx MA 2023.pdf
Les nouveautés de Java 21 - Devoxx MA 2023.pdfLes nouveautés de Java 21 - Devoxx MA 2023.pdf
Les nouveautés de Java 21 - Devoxx MA 2023.pdf
 
Ajax presentation
Ajax presentationAjax presentation
Ajax presentation
 
Automated testing APEX Applications
Automated testing APEX ApplicationsAutomated testing APEX Applications
Automated testing APEX Applications
 
JNDI
JNDIJNDI
JNDI
 
Support Java Avancé Troisième Partie
Support Java Avancé Troisième PartieSupport Java Avancé Troisième Partie
Support Java Avancé Troisième Partie
 
02 - [ASP.NET Core] ASP.NET Core MVC
02 - [ASP.NET Core] ASP.NET Core MVC 02 - [ASP.NET Core] ASP.NET Core MVC
02 - [ASP.NET Core] ASP.NET Core MVC
 
Chapitre N°4 Diagramme de séquence.pdf
Chapitre N°4  Diagramme de séquence.pdfChapitre N°4  Diagramme de séquence.pdf
Chapitre N°4 Diagramme de séquence.pdf
 
Java Spring framework, Dependency Injection, DI, IoC, Inversion of Control
Java Spring framework, Dependency Injection, DI, IoC, Inversion of ControlJava Spring framework, Dependency Injection, DI, IoC, Inversion of Control
Java Spring framework, Dependency Injection, DI, IoC, Inversion of Control
 
UML Part1-Introduction Mansouri
UML Part1-Introduction MansouriUML Part1-Introduction Mansouri
UML Part1-Introduction Mansouri
 
Hibernate Presentation
Hibernate  PresentationHibernate  Presentation
Hibernate Presentation
 
Spring Framework - Core
Spring Framework - CoreSpring Framework - Core
Spring Framework - Core
 
Modificateurs d'accès en java
Modificateurs d'accès en javaModificateurs d'accès en java
Modificateurs d'accès en java
 
ADO.NET
ADO.NETADO.NET
ADO.NET
 

Destacado

From Lab to Market. Lessons learned from Breaking Bad
From Lab to Market. Lessons learned from Breaking BadFrom Lab to Market. Lessons learned from Breaking Bad
From Lab to Market. Lessons learned from Breaking Bad
Pedro Moneo
 
Tech Review's Top Ten Emerging Technologies 2012
Tech Review's Top Ten Emerging Technologies 2012Tech Review's Top Ten Emerging Technologies 2012
Tech Review's Top Ten Emerging Technologies 2012
Pedro Moneo
 
I Terremoti Cartosio Zanoli
I Terremoti Cartosio ZanoliI Terremoti Cartosio Zanoli
I Terremoti Cartosio Zanoli
andrea.multari
 

Destacado (20)

EMF-REST: Generation of RESTful APIs from Models
EMF-REST: Generation of RESTful APIs from ModelsEMF-REST: Generation of RESTful APIs from Models
EMF-REST: Generation of RESTful APIs from Models
 
Sandeep Sharma_CV
Sandeep Sharma_CVSandeep Sharma_CV
Sandeep Sharma_CV
 
NEDA Broadband Survey
NEDA Broadband SurveyNEDA Broadband Survey
NEDA Broadband Survey
 
01. http basics v27
01. http basics v2701. http basics v27
01. http basics v27
 
JavaDayIV - Leoncini Writing Restful Applications With Resteasy
JavaDayIV - Leoncini Writing Restful Applications With ResteasyJavaDayIV - Leoncini Writing Restful Applications With Resteasy
JavaDayIV - Leoncini Writing Restful Applications With Resteasy
 
Introduction to API Design: REST and Java
Introduction to API Design: REST and JavaIntroduction to API Design: REST and Java
Introduction to API Design: REST and Java
 
Effat 1234
Effat 1234Effat 1234
Effat 1234
 
Soc meded nhwehl-4-9-2010
Soc meded nhwehl-4-9-2010Soc meded nhwehl-4-9-2010
Soc meded nhwehl-4-9-2010
 
Social Media - CONFR - Workshop Lebanon NH
Social Media - CONFR - Workshop Lebanon NHSocial Media - CONFR - Workshop Lebanon NH
Social Media - CONFR - Workshop Lebanon NH
 
From Lab to Market. Lessons learned from Breaking Bad
From Lab to Market. Lessons learned from Breaking BadFrom Lab to Market. Lessons learned from Breaking Bad
From Lab to Market. Lessons learned from Breaking Bad
 
NFCB
NFCBNFCB
NFCB
 
CAA 2014 - To Boldly or Bravely Go? Experiences of using Semantic Technologie...
CAA 2014 - To Boldly or Bravely Go? Experiences of using Semantic Technologie...CAA 2014 - To Boldly or Bravely Go? Experiences of using Semantic Technologie...
CAA 2014 - To Boldly or Bravely Go? Experiences of using Semantic Technologie...
 
EAA2014 Istanbul - Barriers and Opportunities for Linked Open Data use in Arc...
EAA2014 Istanbul - Barriers and Opportunities for Linked Open Data use in Arc...EAA2014 Istanbul - Barriers and Opportunities for Linked Open Data use in Arc...
EAA2014 Istanbul - Barriers and Opportunities for Linked Open Data use in Arc...
 
Graphicast Sales
Graphicast SalesGraphicast Sales
Graphicast Sales
 
CAA 2016 The Matrix: Connecting Time and Space with archaeological research q...
CAA 2016 The Matrix: Connecting Time and Space with archaeological research q...CAA 2016 The Matrix: Connecting Time and Space with archaeological research q...
CAA 2016 The Matrix: Connecting Time and Space with archaeological research q...
 
Tech Review's Top Ten Emerging Technologies 2012
Tech Review's Top Ten Emerging Technologies 2012Tech Review's Top Ten Emerging Technologies 2012
Tech Review's Top Ten Emerging Technologies 2012
 
Social Media for the Social Sector
Social Media for the Social SectorSocial Media for the Social Sector
Social Media for the Social Sector
 
Voor Op Blogger
Voor Op BloggerVoor Op Blogger
Voor Op Blogger
 
Architettura Di Reti Sicure
Architettura Di Reti SicureArchitettura Di Reti Sicure
Architettura Di Reti Sicure
 
I Terremoti Cartosio Zanoli
I Terremoti Cartosio ZanoliI Terremoti Cartosio Zanoli
I Terremoti Cartosio Zanoli
 

Similar a Building RESTful Java Applications with EMF

Intro to BackboneJS + Intermediate Javascript
Intro to BackboneJS + Intermediate JavascriptIntro to BackboneJS + Intermediate Javascript
Intro to BackboneJS + Intermediate Javascript
Andrew Lovett-Barron
 
[Muir] Seam 2 in practice
[Muir] Seam 2 in practice[Muir] Seam 2 in practice
[Muir] Seam 2 in practice
javablend
 
IBM Solutions '99 XML and Java: Lessons Learned
IBM Solutions '99 XML and Java: Lessons LearnedIBM Solutions '99 XML and Java: Lessons Learned
IBM Solutions '99 XML and Java: Lessons Learned
Ted Leung
 

Similar a Building RESTful Java Applications with EMF (20)

Overcoming The Impedance Mismatch Between Source Code And Architecture
Overcoming The Impedance Mismatch Between Source Code And ArchitectureOvercoming The Impedance Mismatch Between Source Code And Architecture
Overcoming The Impedance Mismatch Between Source Code And Architecture
 
XML Schema Patterns for Databinding
XML Schema Patterns for DatabindingXML Schema Patterns for Databinding
XML Schema Patterns for Databinding
 
Ruby on Rails Presentation
Ruby on Rails PresentationRuby on Rails Presentation
Ruby on Rails Presentation
 
Implementing the Genetic Algorithm in XSLT: PoC
Implementing the Genetic Algorithm in XSLT: PoCImplementing the Genetic Algorithm in XSLT: PoC
Implementing the Genetic Algorithm in XSLT: PoC
 
When To Use Ruby On Rails
When To Use Ruby On RailsWhen To Use Ruby On Rails
When To Use Ruby On Rails
 
Services Oriented Infrastructure in a Web2.0 World
Services Oriented Infrastructure in a Web2.0 WorldServices Oriented Infrastructure in a Web2.0 World
Services Oriented Infrastructure in a Web2.0 World
 
Intro to BackboneJS + Intermediate Javascript
Intro to BackboneJS + Intermediate JavascriptIntro to BackboneJS + Intermediate Javascript
Intro to BackboneJS + Intermediate Javascript
 
Model Inheritance
Model InheritanceModel Inheritance
Model Inheritance
 
RubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - KeynoteRubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - Keynote
 
[Muir] Seam 2 in practice
[Muir] Seam 2 in practice[Muir] Seam 2 in practice
[Muir] Seam 2 in practice
 
BeJUG JavaFx In Practice
BeJUG JavaFx In PracticeBeJUG JavaFx In Practice
BeJUG JavaFx In Practice
 
Ruby on Rails 101 - Presentation Slides for a Five Day Introductory Course
Ruby on Rails 101 - Presentation Slides for a Five Day Introductory CourseRuby on Rails 101 - Presentation Slides for a Five Day Introductory Course
Ruby on Rails 101 - Presentation Slides for a Five Day Introductory Course
 
I Feel Pretty
I Feel PrettyI Feel Pretty
I Feel Pretty
 
Boston Computing Review - Java Server Pages
Boston Computing Review - Java Server PagesBoston Computing Review - Java Server Pages
Boston Computing Review - Java Server Pages
 
Entity Framework V1 and V2
Entity Framework V1 and V2Entity Framework V1 and V2
Entity Framework V1 and V2
 
IBM Solutions '99 XML and Java: Lessons Learned
IBM Solutions '99 XML and Java: Lessons LearnedIBM Solutions '99 XML and Java: Lessons Learned
IBM Solutions '99 XML and Java: Lessons Learned
 
Jvm Language Summit Rose 20081016
Jvm Language Summit Rose 20081016Jvm Language Summit Rose 20081016
Jvm Language Summit Rose 20081016
 
Adventurous Merb
Adventurous MerbAdventurous Merb
Adventurous Merb
 
Wt unit 2 ppts client sied technology
Wt unit 2 ppts client sied technologyWt unit 2 ppts client sied technology
Wt unit 2 ppts client sied technology
 
Wt unit 2 ppts client side technology
Wt unit 2 ppts client side technologyWt unit 2 ppts client side technology
Wt unit 2 ppts client side technology
 

Último

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 

Último (20)

Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 

Building RESTful Java Applications with EMF

  • 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