building restful java applications with emf

207
Marcelo Paternostro, IBM Kenn Hussey, Embarcadero Technologies Building RESTful Java™ Applications with EMF 12/25/21 1 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Upload: kenn-hussey

Post on 13-Jun-2015

6.350 views

Category:

Technology


7 download

DESCRIPTION

Representational State Transfer (REST) is a style of software architecture for distributed hypermedia systems such as the World Wide Web. However, it is possible to design any enterprise software system in accordance with the REST architectural style without using the HTTP protocol and without interacting with the World Wide Web. Systems that follow the principles of REST often referred to as RESTful. Proponents of REST argue that the Web enjoyed the scalability and growth that it has had as a direct result of a few key design principles. Among these principles are the notions that application state and functionality are divided into resources and that every resource is uniquely addressable using a universal syntax for use in hypermedia links. Another key principle of REST is that all resources share a uniform interface for the transfer of state between client and resource, consisting of a constrained set of content types and a constrained set of well-defined operations.The Eclipse Modeling Framework (EMF) provides a Java runtime framework and tools for generative application development and fine-grained data integration based on simple models. Models can be specified directly using EMF's metamodel, Ecore, or imported from other forms, including UML and XML Schema. Given a model specification, EMF can generate a corresponding set of Java interfaces and implementation classes that can easily be mixed with hand-written code for maximum flexibility. When deployed, applications developed with EMF benefit from a powerful and extensible runtime, which, among other features, includes a persistence mechanism which has always supported the principles of REST – perhaps even before the term "REST" became popular. This tutorial will provide an introduction to EMF, including alternatives for specifying a model, EMF's code generation tools, and key runtime framework concepts. As a practical usage of this knowledge, the presenters will show how EMF can be used to build RESTful applications, exploring some best practices for working with resources and other features of the framework.

TRANSCRIPT

Page 1: Building RESTful Java Applications with EMF

Marcelo Paternostro, IBMKenn Hussey, Embarcadero Technologies

Building RESTful Java™ Applications with EMF

Thursday, April 13, 2023 1© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 2: Building RESTful Java Applications with EMF

• 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

Model Driven Software Development

Thursday, April 13, 2023 2© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 3: Building RESTful Java Applications with EMF

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

Thursday, April 13, 2023 3© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 4: Building RESTful Java Applications with EMF

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

Thursday, April 13, 2023 4© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 5: Building RESTful Java Applications with EMF

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

Thursday, April 13, 2023 5© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 6: Building RESTful Java Applications with EMF

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

Thursday, April 13, 2023 6© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 7: Building RESTful Java Applications with EMF

• 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

Eclipse Modeling Framework

Thursday, April 13, 2023 7© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 8: Building RESTful Java Applications with 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

A Brief History of EMF

Thursday, April 13, 2023 8© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 9: Building RESTful Java Applications with EMF

• 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

Ecore: The Model of Models

Thursday, April 13, 2023 9© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 10: Building RESTful Java Applications with EMF

Relationship of Ecore to Other Models

Thursday, April 13, 2023 10© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

UML®

XML Schema

Java

Ecore

Page 11: Building RESTful Java Applications with EMF

A Model is a Model is a Model

Thursday, April 13, 2023 11© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

<xsd:complexType name="Node"> <xsd:sequence> <xsd:element name="children" type="tree:Node" minOccurs="0" maxOccurs="unbounded" ecore:opposite="parent"/> </xsd:sequence> <xsd:attribute name="label" type="xsd:string"/></xsd:complexType>

public interface Node { String getLabel(); void setLabel(String value); List<Node> getChildren(); Node getParent(); void setParent(Node value);} // Node

UML XML Schema

Java

Ecore

Page 12: Building RESTful Java Applications with EMF

Ecore Overview

Thursday, April 13, 2023 12© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 13: Building RESTful Java Applications with EMF

Ecore Data Types

Thursday, April 13, 2023 13© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 14: Building RESTful Java Applications with EMF

Ecore Annotations and EObject

Thursday, April 13, 2023 14© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 15: Building RESTful Java Applications with EMF

Ecore Generics

Thursday, April 13, 2023 15© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 16: Building RESTful Java Applications with EMF

The Tree Ecore Model

Thursday, April 13, 2023 16© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

name tree

nsURI http://www.example.org/tree

eClassifiers

Node

name Node

eStructuralFeatures

label, children, parent

name label

eType EString

lowerBound

0

upperBound

0

name children

eType Node

lowerBound

0

upperBound

-1

containment

true

eOpposite parent

name parent

eType Node

lowerBound

0

upperBound

1

containment

false

eOpposite children

EPackage

EClass

EAttribute EReference EReference

Page 17: Building RESTful Java Applications with EMF

The Tree Ecore Model Serialized as XMI

Thursday, April 13, 2023 17© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

<?xml version="1.0" encoding="UTF-8"?><ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="tree" nsURI="http://www.example.org/tree" nsPrefix="tree"> <eClassifiers xsi:type="ecore:EClass" name="Node"> <eStructuralFeatures xsi:type="ecore:EAttribute" name="label" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> <eStructuralFeatures xsi:type="ecore:EReference" name="children" upperBound="-1" eType="#//Node" containment="true" eOpposite="#//Node/parent"/> <eStructuralFeatures xsi:type="ecore:EReference" name="parent" eType="#//Node" eOpposite="#//Node/children"/> </eClassifiers></ecore:EPackage>

Page 18: Building RESTful Java Applications with EMF

The Tree Ecore Model Serialized as EMOF

Thursday, April 13, 2023 18© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

<?xml version="1.0" encoding="UTF-8"?><emof:Package xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:emof="http://schema.omg.org/spec/MOF/2.0/emof.xml" xmi:id="tree" name="tree" uri="http://www.example.org/tree"> <ownedType xmi:type="emof:Class" xmi:id="tree.Node" name="Node"> <ownedAttribute xmi:id="tree.Node.label" name="label" isOrdered="true" lower="0"> <type xmi:type="emof:PrimitiveType" href="http://schema.omg.org/spec/MOF/2.0/emof.xml#String"/> </ownedAttribute> <ownedAttribute xmi:id="tree.Node.children" name="children" isOrdered="true" lower="0" upper="*" type="tree.Node" isComposite="true" opposite="tree.Node.parent"/> <ownedAttribute xmi:id="tree.Node.parent" name="parent" isOrdered="true" lower="0" type="tree.Node" opposite="tree.Node.children"/> </ownedType> <xmi:Extension extender="http://www.eclipse.org/emf/2002/Ecore"> <nsPrefix>tree</nsPrefix> </xmi:Extension></emof:Package>

Page 19: Building RESTful Java Applications with EMF

A Tree Instance Model

Thursday, April 13, 2023 19© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

label Root

children

A, B

parent

Node

label A

children

X

parent Root

Node

label B

children

Y

parent Root

Node

label X

children

parent A

Node

label Y

children

parent B

Node

Page 20: Building RESTful Java Applications with EMF

A Tree Instance Model Serialized as XMI

Thursday, April 13, 2023 20© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

<tree:Node xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:tree="http://www.example.org/tree" label="root"> <children label="A"> <children label="X"/> </children> <children label="B"> <children label="Y"/> </children></tree:Node>

Page 21: Building RESTful Java Applications with EMF

• The GenModel is a decorator for tailoring the generated code

The EMF Generator Model

Thursday, April 13, 2023 21© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 22: Building RESTful Java Applications with EMF

EMF Application Architecture

Thursday, April 13, 2023 22© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Eclipse Runtime

Ecore

Edit

Edit UI

Common

Common UI

XMI Change

Ecore Editor

Ecore Edit

Eclipse UI

Page 23: Building RESTful Java Applications with EMF

• 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

EMF in Action

Thursday, April 13, 2023 23© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 24: Building RESTful Java Applications with EMF

• 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

Completing the Picture

Thursday, April 13, 2023 24© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 25: Building RESTful Java Applications with EMF

A Richer Tree Ecore Model

Thursday, April 13, 2023 25© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 26: Building RESTful Java Applications with EMF

Generated EPackage

Thursday, April 13, 2023 26© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

package org.example.tree;// ...

public interface TreePackage extends EPackage{ String eNAME = "tree"; String eNS_URI = "http://www.example.org/tree"; String eNS_PREFIX = "tree"; TreePackage eINSTANCE = TreePackageImpl.init(); // ...

interface Literals { // ... }} package org.example.tree.impl;// ...

public class TreePackageImpl extends EPackageImpl implements TreePackage{ // ...}

Page 27: Building RESTful Java Applications with EMF

Generated EFactory

Thursday, April 13, 2023 27© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

package org.example.tree.impl;// ...public class TreeFactoryImpl extends EFactoryImpl implements TreeFactory{ // ...}

package org.example.tree;// ...public interface TreeFactory extends EFactory{ TreeFactory eINSTANCE = TreeFactoryImpl.init(); // ...}

Page 28: Building RESTful Java Applications with EMF

Generated EPackage Utility Classes

Thursday, April 13, 2023 28© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

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{ // ...}

Page 29: Building RESTful Java Applications with EMF

Generated EClass

Thursday, April 13, 2023 29© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

package org.example.tree;// ...public interface Node extends EObject{ // ...}

package org.example.tree.impl;// ...public class NodeImpl extends EObjectImpl implements Node{ // ...}

Page 30: Building RESTful Java Applications with EMF

Generated EClass Impact

Thursday, April 13, 2023 30© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface TreePackage //...{

int NODE = 0; EClass getNode(); // ...

interface Literals {

EClass NODE = eINSTANCE.getNode(); // ... }}public interface TreeFactory //...{

Node createNode(); // ...}

public class TreeAdapterFactory //...{

public Adapter createNodeAdapter(); // ...}

public class TreeSwitch<T>{

public T caseNode(Node object); // ...}

Page 31: Building RESTful Java Applications with EMF

Generated EStructuralFeature

Thursday, April 13, 2023 31© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

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; // ...

}

// ...}

Page 32: Building RESTful Java Applications with EMF

Generated EStructuralFeature Impact

Thursday, April 13, 2023 32© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface TreePackage //...{ int NODE__LABEL = 0; EAttribute getNode_Label(); // ...

interface Literals { EAttribute NODE__LABEL = eINSTANCE.getNode_Label(); // ... }}

Page 33: Building RESTful Java Applications with EMF

Generated EOperation

Thursday, April 13, 2023 33© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

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(); } // ...}

Page 34: Building RESTful Java Applications with EMF

Generated EDataType Impact

Thursday, April 13, 2023 34© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

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); } // ...}

Page 35: Building RESTful Java Applications with EMF

Generated EEnum

Thursday, April 13, 2023 35© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

package org.example.tree;// ...public enum NodeKind implements Enumerator{ // ...}

Page 36: Building RESTful Java Applications with EMF

Generated EEnum Impact

Thursday, April 13, 2023 36© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface TreePackage //...{

int NODE_KIND = 1; EEnum getNodeKind(); // ...

interface Literals {

EEnum NODE_KIND = eINSTANCE.getNodeKind(); // ... }}

Page 37: Building RESTful Java Applications with EMF

Generated EEnumLiteral

Thursday, April 13, 2023 37© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public enum NodeKind // ...{ SINGLETON(0, "Singleton", "Singleton"), // ...}

Page 38: Building RESTful Java Applications with EMF

• 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

Generated Project-level Artifacts

Thursday, April 13, 2023 38© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 39: Building RESTful Java Applications with EMF

• The generated MANIFEST.MF is not regenerated once the corresponding plugin.xml exists so you can tailor it as needed

Generated Manifest

Thursday, April 13, 2023 39© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Manifest-Version: 1.0Bundle-ManifestVersion: 2Bundle-Name: %pluginNameBundle-SymbolicName: org.example.tree;singleton:=trueBundle-Version: 1.0.0Bundle-ClassPath: .Bundle-Vendor: %providerNameBundle-Localization: pluginBundle-RequiredExecutionEnvironment: J2SE-1.5Export-Package: org.example.tree, org.example.tree.impl, org.example.tree.utilRequire-Bundle: org.eclipse.core.runtime, org.eclipse.emf.ecore;visibility:=reexport, org.eclipse.emf.ecore.xmi;visibility:=reexportBundle-ActivationPolicy: lazy

Page 40: Building RESTful Java Applications with EMF

• 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

Generated Plug-in XML

Thursday, April 13, 2023 40© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

<plugin>

<extension point="org.eclipse.emf.ecore.generated_package"> <package uri="http://www.example.org/tree" class="org.example.tree.TreePackage" genModel="model/Tree.genmodel"/> </extension>

<extension point="org.eclipse.emf.ecore.extension_parser"> <parser type="tree" class="org.example.tree.util.TreeResourceFactoryImpl"/> </extension>

</plugin>

Page 41: Building RESTful Java Applications with EMF

• The generated plugin.properties supports merging– Any property not already defined is added– Any property already defined retains it’s value

• The generated build.properties will not be modified once it exists it can be tailored as desired

Generated Build and Plug-in Properties

Thursday, April 13, 2023 41© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

pluginName = Tree ModelproviderName = www.example.org

bin.includes = .,\ model/,\ META-INF/,\ plugin.xml,\ plugin.propertiesjars.compile.order = .source.. = src/output.. = bin/

Page 42: Building RESTful Java Applications with EMF

• 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

Modifying Generated Code

Thursday, April 13, 2023 42© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

/** * <!-- 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;}

Page 43: Building RESTful Java Applications with EMF

• 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

Modifying Generated Javadoc

Thursday, April 13, 2023 43© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

/** * 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="org.example.tree.Label“ * @generated */String getLabel();

Page 44: Building RESTful Java Applications with EMF

• A generated method can be renamed by adding a “Gen” suffix and then the original signature can be used to provide additional behavior

Augmenting Generated Methods

Thursday, April 13, 2023 44© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

/** * <!-- 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());}

Page 45: Building RESTful Java Applications with EMF

label

children

parent

label Y

children

parent

label

children

parent

label B

children

parent

label B

children

parent Root

label

children

parent

label X

children

parent

label

children

parent

label A

children

parent

label A

children

parent Root

label

children

parent

label Root

children

parent

label Root

children

A

parent

label Root

children

A, B

parent

Node

Creating a Tree Instance Model

Thursday, April 13, 2023 45© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

label A

children

X

parent Root

Node

label B

children

Y

parent Root

Node

label X

children

parent A

Node

label Y

children

parent B

Node

TreeFactory tree = TreeFactory.eINSTANCE;

Node root = tree.createNode();

root.setLabel("Root");

Node a = tree.createNode();

root.getChildren().add(a);

a.setLabel("A");

Node x = tree.createNode();

x.setLabel("X");

a.getChildren().add(x);

Node b = tree.createNode();

b.setLabel("B");

root.getChildren().add(b);

Node y = tree.createNode();

y.setLabel("Y");

b.getChildren().add(y);

Page 46: Building RESTful Java Applications with EMF

Notifiers, Adapters, and Notification

Thursday, April 13, 2023 46© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface Notifier{ EList<Adapter> eAdapters(); void eNotify(Notification notification); boolean eDeliver(); void eSetDeliver(boolean deliver);}

public interface Adapter{ void notifyChanged(Notification notification); // ...}

int SET = 1;int UNSET = 2;int ADD = 3;int REMOVE = 4;int ADD_MANY = 5;int REMOVE_MANY = 6;int MOVE = 7; int REMOVING_ADAPTER = 8; int RESOLVE = 9;int EVENT_TYPE_COUNT = 10;

notifier.eAdapters().add (new AdapterImpl() { @Override public void notifyChanged(Notification notification) { // Process notifications produced by the notifier. } });

public interface Notification{ Object getNotifier(); int getEventType(); Object getFeature(); Object getOldValue(); Object getNewValue(); int getPosition(); // ...}

Page 47: Building RESTful Java Applications with EMF

• 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

EObject Reflection

Thursday, April 13, 2023 47© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface EObject extends Notifier{ EClass eClass(); EObject eContainer(); EReference eContainmentFeature(); EList<EObject> eContents(); // ...}

Page 48: Building RESTful Java Applications with EMF

• 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

EObject Notification

Thursday, April 13, 2023 48© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public void setLabel(String newLabel){ String oldLabel = label; label = newLabel; if (eNotificationRequired()) eNotify (new ENotificationImpl (this, Notification.SET, TreePackage.NODE__LABEL, oldLabel, label));}

Page 49: Building RESTful Java Applications with EMF

• 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()

References and Referential Integrity

Thursday, April 13, 2023 49© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 50: Building RESTful Java Applications with EMF

Notifier

Feature

Type Old

New

label

children

parent

label Y

children

parent

label

children

parent

label B

children

parent

label B

children

parent Root

label

children

parent

label X

children

parent

label

children

parent

label A

children

parent

label A

children

parent Root

label

children

parent

label Root

children

parent

label Root

children

A

parent

label Root

children

A, B

parent

Node

Updating a Tree Instance Model

50Thursday, April 13, 2023

© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

label A

children

X

parent Root

Node

label B

children

Y

parent Root

label X

children

parent A

label Y

children

parent B

Node

b.getChildren().set(0, x);

label B

children

X

parent Root

Node

Notifier

Feature

Type Old

New

b children

SET y

Notifier

Feature

Type Old

New

b children

SET y x

Notifier

Feature

Type Old

New

b children

SET y x

y parent SET b

Notifier

Feature

Type Old

New

b children

SET y x

y parent SET b

x parent SET a

Notifier

Feature

Type Old

New

b children

SET y x

y parent SET b

x parent SET a b

label X

children

parent B

Node

Notifier

Feature

Type Old

New

b children

SET y x

y parent SET b

x parent SET a b

a children

REMOVE

x

Page 51: Building RESTful Java Applications with EMF

Code Generation

Exercise 1

Thursday, April 13, 2023 51© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 52: Building RESTful Java Applications with EMF

• 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)

RESTful Persistence

Thursday, April 13, 2023 52© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 53: Building RESTful Java Applications with EMF

• 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

Uniform Resource Identifiers

Thursday, April 13, 2023 53© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

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); // …}

Page 54: Building RESTful Java Applications with EMF

• 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

Hierarchical URIs

Thursday, April 13, 2023 54© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

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(); // ...}

Page 55: Building RESTful Java Applications with EMF

• 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

Absolute and Relative URIs

Thursday, April 13, 2023 55© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public final class URI{ public boolean isRelative(); // ...}

Page 56: Building RESTful Java Applications with EMF

• 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

Resolving and De-resolving URIs

Thursday, April 13, 2023 56© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public final class URI{ public URI resolve(URI base); public URI deresolve(URI base); // ...}

Page 57: Building RESTful Java Applications with EMF

• 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:\a\foo.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());

URIs to Access the File System

Thursday, April 13, 2023 57© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public final class URI{ public static URI createFileURI(String pathName) public boolean isFile(); public String toFileString(); // ...}

Page 58: Building RESTful Java Applications with EMF

• 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

URIs to Access the Eclipse Workspace

Thursday, April 13, 2023 58© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public final class URI{ public static URI createPlatformResourceURI(String pathName, boolean encode); public boolean isPlatformResource(); public String toPlatformString(boolean decode); // ...}

Page 59: Building RESTful Java Applications with EMF

• 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);

URIs to Access the Eclipse Installation

Thursday, April 13, 2023 59© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public final class URI{ public static URI createPlatformPluginURI(String pathName, boolean encode); public boolean isPlatformPlugin(); public String toPlatformString(boolean decode); // ...}

Page 60: Building RESTful Java Applications with EMF

• 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

URIs to Access an Archive

Thursday, April 13, 2023 60© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public final class URI{ public boolean isArchive(); // ...}

Page 61: Building RESTful Java Applications with EMF

• 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

URI Converter

Thursday, April 13, 2023 61© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface URIConverter{ URI normalize(URI uri); URIConverter INSTANCE = new ExtensibleURIConverterImpl(); // ...}

Page 62: Building RESTful Java Applications with EMF

• 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

URI Converter Remapping

Thursday, April 13, 2023 62© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface URIConverter{ Map<URI, URI> getURIMap(); Map<URI, URI> URI_MAP = /**/; // ...}

Page 63: Building RESTful Java Applications with EMF

• 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

URI Converter Input and Output

Thursday, April 13, 2023 63© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface URIConverter{ String OPTION_RESPONSE = "RESPONSE"; String RESPONSE_TIME_STAMP_PROPERTY = "TIME_STAMP"; InputStream createInputStream(URI uri, Map<?, ?> options) throws IOException; OutputStream createOutputStream(URI uri, Map<?, ?> options) throws IOException; //...}

Page 64: Building RESTful Java Applications with EMF

• 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

URI Converter Deletion and Existence

Thursday, April 13, 2023 64© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface URIConverter{ boolean exists(URI uri, Map<?, ?> options); void delete(URI uri, Map<?, ?> options) throws IOException; // ... }

Page 65: Building RESTful Java Applications with EMF

• Attributes associated with the state of a URI can be fetched and stored– An OPTION_REQUESTED_ATTRIBUTES map specifies

the attributes to be fetched

URI Converter

Thursday, April 13, 2023 65© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface URIConverter{ String ATTRIBUTE_TIME_STAMP = "timeStamp"; long NULL_TIME_STAMP = -1; String ATTRIBUTE_LENGTH = "length"; String ATTRIBUTE_READ_ONLY = "readOnly"; String ATTRIBUTE_EXECUTABLE = "executable"; String ATTRIBUTE_ARCHIVE = "archive"; String ATTRIBUTE_HIDDEN = "hidden"; String ATTRIBUTE_DIRECTORY = "directory"; String OPTION_REQUESTED_ATTRIBUTES = "requestedAttributes"; Map<String, ?> getAttributes(URI uri, Map<?, ?> options); void setAttributes(URI uri, Map<String, ?> attributes, Map<?, ?> options) throws IOException; // ...}

Page 66: Building RESTful Java Applications with EMF

• 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

URI Converter Content Description

Thursday, April 13, 2023 66© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface URIConverter{ Map<String, ?> contentDescription(URI uri, Map<?, ?> options) throws IOException; EList<ContentHandler> getContentHandlers(); // ...}

Page 67: Building RESTful Java Applications with EMF

• 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

URI Converter Delegation To URI Handlers

Thursday, April 13, 2023 67© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface URIConverter{ EList<URIHandler> getURIHandlers(); URIHandler getURIHandler(URI uri); // ...}

Page 68: Building RESTful Java Applications with EMF

• 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

URI Handler

Thursday, April 13, 2023 68© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

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; // ...}

Page 69: Building RESTful Java Applications with EMF

• Default URI handlers support the Eclipse workspace, the file system, the Eclipse File System, nested archives, and arbitrary URLs

URI Handler

Thursday, April 13, 2023 69© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface URIHandler{ List<URIHandler> DEFAULT_HANDLERS = Collections.unmodifiableList (Arrays.asList (new URIHandler [] { new PlatformResourceURIHandlerImpl(), new FileURIHandlerImpl(), new EFSURIHandlerImpl(), new ArchiveURIHandlerImpl(), new URIHandlerImpl() })); // ...}

Page 70: Building RESTful Java Applications with EMF

• 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

Content Handler

Thursday, April 13, 2023 70© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface ContentHandler{ boolean canHandle(URI uri); String OPTION_REQUESTED_PROPERTIES = "REQUESTED_PROPERTIES"; Map<String, ?> contentDescription (URI uri, InputStream inputStream, Map<?, ?> options, Map<Object, Object> context) throws IOException; // ...}

Page 71: Building RESTful Java Applications with EMF

• 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

Content Handler Validity Determination

Thursday, April 13, 2023 71© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface ContentHandler{ String VALIDITY_PROPERTY = "org.eclipse.emf.ecore:validity"; enum Validity { INVALID, INDETERMINATE, VALID } String CONTENT_TYPE_PROPERTY = "org.eclipse.emf.ecore:contentType"; String UNSPECIFIED_CONTENT_TYPE = ""; Map<String, Object> INVALID_CONTENT_DESCRIPTION = /**/;}

Page 72: Building RESTful Java Applications with EMF

• Two standard description properties are supported– The character set used to encode the content– The byte order marker at the start of the

stream

Content Handler Encodings

Thursday, April 13, 2023 72© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface ContentHandler{ String CHARSET_PROPERTY = "org.eclipse.core.runtime:charset"; String BYTE_ORDER_MARK_PROPERTY = "org.eclipse.core.runtime:bom"; enum ByteOrderMark { UTF_8, UTF_16BE, UTF_16LE; public byte [] bytes(); public static ByteOrderMark read(InputStream inputStream) throws IOException; } // ..}

Page 73: Building RESTful Java Applications with EMF

• 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

Content Handler Registration

Thursday, April 13, 2023 73© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

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(); }}

Page 74: Building RESTful Java Applications with EMF

• 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

Resource Set

Thursday, April 13, 2023 74© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface ResourceSet extends Notifier{ int RESOURCE_SET__RESOURCES = 0; EList<Resource> getResources(); // ...}

Page 75: Building RESTful Java Applications with EMF

• 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

Resource

Thursday, April 13, 2023 75© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface Resource extends Notifier{

int RESOURCE__RESOURCE_SET = 0; ResourceSet getResourceSet(); int RESOURCE__URI = 1; URI getURI(); void setURI(URI uri); int RESOURCE__CONTENTS = 2; EList<EObject> getContents(); // ...}

public interface EObject //...{

Resource eResource(); // ...}

Page 76: Building RESTful Java Applications with EMF

• 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

Tree Iterators over the Containment Tree

Thursday, April 13, 2023 76© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface Resource // ...{

TreeIterator<EObject> getAllContents(); // ...}

public interface EObject //...{

TreeIterator<EObject> eAllContents(); // ...}

public interface ResourceSet // ...{

TreeIterator<Notifier> getAllContents(); // ...}

public interface TreeIterator<E> extends Iterator<E>{

void prune();}

Page 77: Building RESTful Java Applications with EMF

• 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

Resource Set

Thursday, April 13, 2023 77© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface ResourceSet extends Notifier{ URIConverter getURIConverter(); Resource.Factory.Registry getResourceFactoryRegistry(); EPackage.Registry getPackageRegistry(); // ...}

Page 78: Building RESTful Java Applications with EMF

• 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

Resource Factory

Thursday, April 13, 2023 78© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface Resource // ...{

interface Factory {

Resource createResource(URI uri); // ... } }

Page 79: Building RESTful Java Applications with EMF

• 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

Resource Factory Registry

Thursday, April 13, 2023 79© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface Resource // ...{ interface Factory {

interface Registry {

Factory getFactory(URI uri, String contentType); Registry INSTANCE = new ResourceFactoryRegistryImpl(); // ... } }}

Page 80: Building RESTful Java Applications with EMF

• 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

Protocol Resource Factory Registration

Thursday, April 13, 2023 80© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface Resource // ...{ interface Factory {

interface Registry {

Map<String, Object> getProtocolToFactoryMap(); // ... } }}

public final class URI{ public String scheme(); // ...}

Page 81: Building RESTful Java Applications with EMF

• 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

File Extension Resource Factory Registration

Thursday, April 13, 2023 81© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface Resource // ...{ interface Factory {

interface Registry {

String DEFAULT_EXTENSION = "*"; Map<String, Object> getExtensionToFactoryMap(); // ... } }}

public final class URI{ public String fileExtension(); // ...}

Page 82: Building RESTful Java Applications with EMF

• 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

Content Type Resource Factory Registration

Thursday, April 13, 2023 82© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface Resource // ...{ interface Factory {

interface Registry {

String DEFAULT_CONTENT_TYPE_IDENTIFIER = "*"; Map<String, Object> getContentTypeToFactoryMap(); } } // ...}

Page 83: Building RESTful Java Applications with EMF

• 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

Package Registry

Thursday, April 13, 2023 83© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface EPackage // ...{

interface Registry { EPackage getEPackage(String nsURI); EFactory getEFactory(String nsURI); Registry INSTANCE = EPackageRegistryImpl.createGlobalRegistry(); // ... }}

Page 84: Building RESTful Java Applications with EMF

• 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

Creating a New Resource

Thursday, April 13, 2023 84© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface ResourceSet // ...{ Resource createResource(URI uri); Resource createResource(URI uri, String contentType); // ...}

Page 85: Building RESTful Java Applications with EMF

• 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

Populating a New Resource

Thursday, April 13, 2023 85© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface Resource // ...{

int RESOURCE__IS_LOADED = 4; boolean isLoaded(); // ...}

Page 86: Building RESTful Java Applications with EMF

• 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

Saving a Resource

Thursday, April 13, 2023 86© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface Resource // ...{

void save(Map<?, ?> options) throws IOException; void save(OutputStream outputStream, Map<?, ?> options) throws IOException; // ...}

Page 87: Building RESTful Java Applications with EMF

Saving a Tree Model Instance

Thursday, April 13, 2023 87© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

eContainereResourcelabelchildrenparent

eContainereResourcelabel Rootchildrenparent

eContainereResourcelabel Rootchildren Aparent

Node

resources

ResourceSet

eContainereResourcelabelchildrenparent

eContainereResourcelabel Achildrenparent

eContainereResourcelabel Achildrenparent Root

Noderesource.save(null);

root.getChildren().add(a);

a.setLabel("A");

Node a = tree.createNode();

resource.getContents().add(root);

root.setLabel("Root");

Node root = tree.createNode();

TreeFactory tree = TreeFactory.eINSTANCE;

Resource resource = resourceSet.createResource (URI.createFileURI ("c:/Root.tree"));

ResourceSet resourceSet = new ResourceSetImpl();

resourceSeturicontents

resourceSeturi file:/c:/

Root.treecontents

Resource

<?xml version="1.0" encoding="ASCII"?><tree:Node xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:tree="http://www.example.org/tree" label="Root"> <children label="A"/></tree:Node>

Page 88: Building RESTful Java Applications with EMF

• 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

Explicitly Loading a Resource

Thursday, April 13, 2023 88© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface Resource // ...{

void load(Map<?, ?> options) throws IOException; void load(InputStream inputStream, Map<?, ?> options) throws IOException; // ...}

Page 89: Building RESTful Java Applications with EMF

• 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

Demand Loading a Resource

Thursday, April 13, 2023 89© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface ResourceSet // ...{ Map<Object, Object> getLoadOptions(); Resource getResource(URI uri, boolean loadOnDemand); // ...}

Page 90: Building RESTful Java Applications with EMF

Loading a Tree Model Instance

Thursday, April 13, 2023 90© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

eContainereResourcelabelchildrenparent

eContainereResourcelabel Rootchildrenparent

eContainereResourcelabel Rootchildren Aparent

eContainereResourcelabel Root’children Aparent

eContainereResourcelabel Root’children A’parent

Node

resources

ResourceSet

eContainereResourcelabelchildrenparent

eContainereResourcelabel Achildrenparent

eContainereResourcelabel Achildrenparent Root

eContainereResourcelabel Achildrenparent Root’

eContainereResourcelabel A’childrenparent Root’

Node

resource.save(System.out, null);

a.setLabel(a.getLabel() + "'");

Node a = root.getChildren().get(0);

root.setLabel(root.getLabel() + "'");

Node root = (Node)resource.getContents().get(0);

Resource resource = resourceSet.getResource (URI.createFileURI("c:/Root.tree"), true);

ResourceSet resourceSet = new ResourceSetImpl();

resourceSeturicontents

resourceSeturi file:/c:/

Root.treecontents

Resource

<?xml version="1.0" encoding="ASCII"?><tree:Node xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:tree="http://www.example.org/tree" label="Root'"> <children label="A'"/></tree:Node>

Page 91: Building RESTful Java Applications with EMF

• 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

Resource Time Stamps

Thursday, April 13, 2023 91© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface Resource // ...{

int RESOURCE__TIME_STAMP = 8; long getTimeStamp(); void setTimeStamp(long timeStamp); // ...}

Page 92: Building RESTful Java Applications with EMF

• 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

Resource Modification Tracking

Thursday, April 13, 2023 92© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

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); // ...}

Page 93: Building RESTful Java Applications with EMF

• Problems encountered when loading a resource are recorded as diagnostics describing the problem

Resource Diagnostics

Thursday, April 13, 2023 93© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

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(); } // ...}

Page 94: Building RESTful Java Applications with EMF

• 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

Resource Unloading

Thursday, April 13, 2023 94© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface Resource // ...{

void unload(); // ...}

Page 95: Building RESTful Java Applications with EMF

• 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

Resource Deletion

Thursday, April 13, 2023 95© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface Resource // ...{

void delete(Map<?, ?> options) throws IOException; // ...}

Page 96: Building RESTful Java Applications with EMF

• 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

Containment References Revisited

Thursday, April 13, 2023 96© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 97: Building RESTful Java Applications with EMF

Moving a Tree Model Instance

Thursday, April 13, 2023 97© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

eContainereResourcelabel Rootchildren Aparent

eContainereResourcelabel Rootchildrenparent

Node

resources

ResourceSet

eContainereResourcelabel Achildrenparent Root

eContainereResourcelabel Achildrenparent

Node

child.getContents().add(a);

Resource child = resourceSet.createResource (URI.createFileURI ("c:/Child.tree"));

resourceSeturi file:/c:/

Root.treecontents

ResourceresourceSeturicontents

resourceSeturi file:/c:/

Child.treecontents

Resource

Page 98: Building RESTful Java Applications with EMF

• 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

Cross References Revisited

Thursday, April 13, 2023 98© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface EObject // ...{ EList<EObject> eCrossReferences(); // ...}

Page 99: Building RESTful Java Applications with EMF

• 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

URI Access EObjects

Thursday, April 13, 2023 99© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface Resource // ...{ EObject getEObject(String uriFragment); String getURIFragment(EObject eObject); // ...}

public final class URI{ public String fragment(); public URI trimFragment(); public URI appendFragment(String fragment);

// ...}

Page 100: Building RESTful Java Applications with EMF

• 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

Locating or Demand Loading an EObject

Thursday, April 13, 2023 100© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface ResourceSet // ...{ EObject getEObject(URI uri, boolean loadOnDemand); // ...}

Page 101: Building RESTful Java Applications with EMF

• 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

URI Fragments

Thursday, April 13, 2023 101© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 102: Building RESTful Java Applications with EMF

• 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]

URI Fragment Paths

Thursday, April 13, 2023 102© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface InternalEObject // ...{ String eURIFragmentSegment(EStructuralFeature eFeature, EObject eObject); EObject eObjectForURIFragmentSegment(String uriFragmentSegment); // ...}

Page 103: Building RESTful Java Applications with EMF

• 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']

URI Fragment Paths with Keys

Thursday, April 13, 2023 103© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface EReference // ...{ EList<EAttribute> getEKeys(); // ...}

Page 104: Building RESTful Java Applications with EMF

• 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

URI Fragment Intrinsic IDs

Thursday, April 13, 2023 104© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface EAttribute// ...{ boolean isID(); // ...}

Page 105: Building RESTful Java Applications with EMF

• 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

URI Fragment Extrinsic IDs

Thursday, April 13, 2023 105© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public class EcoreUtil{ public static String generateUUID(); // ...}

Page 106: Building RESTful Java Applications with EMF

Saving Cross Document References

Thursday, April 13, 2023 106© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

eContainereResourcelabelchildrenparentdata

eContainereResourcelabel Rootchildrenparentdata

eContainereResourcelabel Rootchildren Aparentdata

Node

resources

ResourceSet

eContainereResourcelabelchildrenparentdata

eContainereResourcelabel Achildrenparentdata

eContainereResourcelabel Achildrenparent Rootdata

Node

resource.save(null);

map.getContents().addAll (copier.copyAll (resource.getContents()));

EcoreUtil.Copier copier = new EcoreUtil.Copier();

Resource map = resourceSet.createResource (URI.createFileURI("c:/Map.tree"));

Resource resource = resourceSet.getResource (URI.createFileURI("c:/Root.tree"), true);

ResourceSet resourceSet = new ResourceSetImpl();

resourceSeturicontents

resourceSeturi file:/c:/

Root.treecontents

Resource

for (Iterator<EObject> i = resource.getAllContents(); i.hasNext(); ){

EObject eObject = i.next(); ((Node)copier.get(eObject)). setData(eObject);}

eContainereResourcelabelchildrenparentdata

eContainereResourcelabel Rootchildrenparentdata

eContainereResourcelabel Rootchildren Aparentdata

Node

eContainereResourcelabelchildrenparentdata

eContainereResourcelabel Achildrenparentdata

eContainereResourcelabel Achildrenparent Rootdata

Node

resourceSeturicontents

resourceSeturi file:/c:/

Map.treecontents

Resource

<?xml version="1.0" encoding="ASCII"?><tree:Node xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:tree="http://www.example.org/tree" label="Root"> <children label="A"> <data href="Root.tree#//@children.0"/> </children> <data href="Root.tree#/"/></tree:Node>

Page 107: Building RESTful Java Applications with EMF

• 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

Proxies

Thursday, April 13, 2023 107© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public interface EObject // ...

{ boolean eIsProxy(); // ...}

public interface InternalEObject extends EObject{ URI eProxyURI(); void eSetProxyURI(URI uri); // ...}

Page 108: Building RESTful Java Applications with EMF

• 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

Proxy Resolution

Thursday, April 13, 2023 108© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

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;}

Page 109: Building RESTful Java Applications with EMF

Loading Cross Document References

Thursday, April 13, 2023 109© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

eContainereResourcelabelchildrenparentdata

eContainereResourcelabel Rootchildrenparentdata

eContainereResourcelabel Rootchildren Aparentdata

Node

resources

ResourceSet

eContainereResourcelabelchildrenparentdata

eContainereResourcelabel Achildrenparentdata

eContainereResourcelabel Achildrenparent Rootdata

Node

Node child = node.getChildren().get(0);

assert !node.getData().eIsProxy();

Node node = (Node)resource.getContents().get(0);

Resource resource = resourceSet.getResource (URI.createFileURI("c:/Map.tree"), true);

ResourceSet resourceSet = new ResourceSetImpl();

resourceSeturicontents

resourceSeturi file:/c:/

Map.treecontents

Resource

assert child.getData().eIsProxy();

eContainereResourcelabelchildrenparentdata

eContainereResourcelabel Rootchildrenparentdata

eContainereResourcelabel Rootchildren Aparentdata

Node

eContainereResourcelabelchildrenparentdata

eContainereResourcelabel Achildrenparentdata

eContainereResourcelabel Achildrenparent Rootdata

Node

resourceSeturicontents

resourceSeturi file:/c:/

Root.treecontents

Resource

eProxyURI

file:/c:/Root.tree#/Node

eProxyURI

file:/c:/Root.tree#//@children.0

Node

Page 110: Building RESTful Java Applications with EMF

• There is optional support for cross resource containment that applies only for proxy resolving containment references; in that case– An object added to that reference will not be removed

from its directly containing resource– An object added to a resource’s contents will not be

remove from such a containment

Cross Resource Containment

Thursday, April 13, 2023 110© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 111: Building RESTful Java Applications with EMF

A Cross Contained Tree Model Instance

Thursday, April 13, 2023 111© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

eContainereResourcelabel Rootchildren Aparent

eContainereResourcelabel Rootchildrenparent

Node

resources

ResourceSet

eContainereResourcelabel Achildrenparent Root

eContainereResourcelabel Achildrenparent

Node

child.getContents().add(a);

Resource child = resourceSet.createResource (URI.createFileURI ("c:/Child.tree"));

resourceSeturi file:/c:/

Root.treecontents

ResourceresourceSeturicontents

resourceSeturi file:/c:/

Child.treecontents

Resource

resource.save(System.out, null);child.save(System.out, null);

<?xml version="1.0" encoding="ASCII"?><tree:Node xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:tree="http://www.example.org/tree" label="Root"> <children href="Child.tree#/"/></tree:Node>

<?xml version="1.0" encoding="ASCII"?><tree:Node xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:tree="http://www.example.org/tree" label="A"> <parent href="Root.tree#/"/></tree:Node>

Page 112: Building RESTful Java Applications with EMF

• Implementing a specialized resource involves overriding the doSave and doLoad methods of ResourceImpl

• EMF provides a number of specialized implementations that support– XML serialization – XMLResourceImpl– XMI serialization – XMIResourceImpl– Fast compact binary serialization – BinaryResourceImpl

– Database persistence (Teneo)– Distributed shared access (CDO)– Repository (JCRM)

Specialized Resource Implementations

Thursday, April 13, 2023 112© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 113: Building RESTful Java Applications with EMF

• The resource factory is the place to configure load and save options to be used by all clients

Options to Configure Resource Load and Save

Thursday, April 13, 2023 113© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

public class TreeResourceFactoryImpl extends ResourceFactoryImpl{ @Override public Resource createResource(URI uri) { XMLResource result = new TreeResourceImpl(uri); result.getDefaultSaveOptions().put(XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE); result.getDefaultLoadOptions().put(XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE);

result.getDefaultSaveOptions().put(XMLResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE);

result.getDefaultLoadOptions().put(XMLResource.OPTION_USE_ENCODED_ATTRIBUTE_STYLE, Boolean.TRUE); result.getDefaultSaveOptions().put(XMLResource.OPTION_USE_ENCODED_ATTRIBUTE_STYLE, Boolean.TRUE);

result.getDefaultLoadOptions().put(XMLResource.OPTION_USE_LEXICAL_HANDLER, Boolean.TRUE); return result; } // …}

Page 114: Building RESTful Java Applications with EMF

• Saving only if the result differs from the current content– Resource.OPTION_SAVE_ONLY_IF_CHANGED

• Resource.OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER• Resource.OPTION_SAVE_ONLY_IF_CHANGED_FILE_BUFFER

• Encrypting and decrypting the bytes– Resource.OPTION_CIPHER

• A URIConverter.Cipher instance– AESCipherImpl– DESCipherImpl

• Compressing and decompressing the bytes– Resource.OPTION_ZIP

• A Boolean.TRUE or Boolean.FALSE

General Resource Options

Thursday, April 13, 2023 114© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 115: Building RESTful Java Applications with EMF

• The resource APIs work with InputStreams but you may need to process a String or a Reader and can avoid needless char -> byte -> char conversion– A stream that implements URIConverter.Readable will be

unwrapped and used directly if the underlying resource supports that

– An implementation is provided, URIConverter.ReadableInputStream• It converts to bytes using the encoding if necessary

Loading from a String or a Reader

Thursday, April 13, 2023 115© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

interface Readable{ Reader asReader(); String getEncoding();}

class ReadableInputStream extends InputStream implements Readable{ public ReadableInputStream(Reader reader, String encoding) public ReadableInputStream(Reader xmlReader) public ReadableInputStream(String string, String encoding) public ReadableInputStream(String xmlString)}

Page 116: Building RESTful Java Applications with EMF

• The resource APIs work with OutputStreams but you may need to process a String or a Writer and can avoid needless char -> byte -> char conversion– A stream that implements URIConverter.Writeable will be

unwrapped and used directly if the underlying resource supports that

– An implementation is provided, URIConverter.WriteableInputStream• It converts to bytes using the encoding if necessary

Saving to a String or a Writer

Thursday, April 13, 2023 116© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

interface Writeable{ Writer asWriter(); String getEncoding();}

static class WriteableOutputStream extends OutputStream implements Writeable{ public WriteableOutputStream(Writer writer, String encoding);}

Page 117: Building RESTful Java Applications with EMF

Programming with Resources

Exercise 2

Thursday, April 13, 2023 117© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 118: Building RESTful Java Applications with EMF

EMF Resource Best Practices• There are a number of ways in which you can

tweak the nature of the serializations that EMF gives you based on its built-in support for XML (and XMI) resources

• In general, these tweaks take place in one of three places – the Ecore model, the generator model, or the code

• We'll consider each of these in turn and look at the impact various choices have on serialized data, using our sample model

Thursday, April 13, 2023 118© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 119: Building RESTful Java Applications with EMF

Sample Model

Thursday, April 13, 2023 119© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 120: Building RESTful Java Applications with EMF

The Ecore Model (The Good?)• An Ecore model is the specification of metadata

for your domain (i.e., your data)• Settings you specify in the Ecore model have a

direct impact on the– namespace and prefix that are using in your

serializations– names of the elements and attributes that are serialized

(and in fact when an attribute is used vs. when and attribute is)

– way references between elements are serialized (including whether a containment hierarchy can be spread over more than one resource)

Thursday, April 13, 2023 120© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 121: Building RESTful Java Applications with EMF

Namespace URIs• The namespace URI defines a unique namespace

for data based on your metamodel• This URI will correspond to the (second portion of

the) xmlns declaration that appears at the beginning of an XML/XMI serialization

<tree:Node xmi:version="2.1" xmlns:xmi="http://schema.omg.org/spec/XMI/2.1" xmlns:tree="http://www.eclipsecon2009.org/emf/1.0/Tree" id=“root" label="Root" kind="Root"/>

Thursday, April 13, 2023 121© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 122: Building RESTful Java Applications with EMF

Namespace URIs• An Ecore package has an 'Ns URI'

property that must be set to the desired string

Thursday, April 13, 2023 122© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 123: Building RESTful Java Applications with EMF

Namespace URIs• Not only is it important that this URI be unique (as with all

URIs), but it must ideally contain information about the version of the metamodel's schema (yes, a metamodel definition effectively defines a schema for its instance documents)

• Every change to this schema must be accompanied by a change to this version information

• One convention commonly used in the industry is to include the year in a URI as the version indicator– This may be OK for schemas that don't change very frequently

(e.g., those maintained by standards or specifications bodies like the OMG)

– In practice, it's common for more than one version of a schema to be defined in the same calendar year, so a better convention is to use the version number of the component in which the metamodel is defined

• For an organization, it's also typically important for namespace URIs to be of a consistent form

Thursday, April 13, 2023 123© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 124: Building RESTful Java Applications with EMF

Best Practice #1The namespace URI defined for a resource

serialization should be of the form 'http://<organization domain>/<project name>/<project version>/<schema name>'

Thursday, April 13, 2023 124© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 125: Building RESTful Java Applications with EMF

Namespace Prefixes• The namespace prefix defines short name that's

used to qualify serialized elements representing data based on your metamodel

• The namespace prefix will correspond to the (the first portion of the) xmlns declaration that appears at the beginning of an XML/XMI serialization

<tree:Node xmi:version="2.1" xmlns:xmi="http://schema.omg.org/spec/XMI/2.1" xmlns:tree="http://www.eclipsecon2009.org/emf/1.0/Tree" id="root" label="Root" kind="Root"/>

Thursday, April 13, 2023 125© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 126: Building RESTful Java Applications with EMF

Namespace Prefixes• The namespace prefix also appears as a

qualifier in xmi:type declarations referencing types from the namespace throughout the document

<child xmi:type="tree:Node" id="child" label="Child"/>

Thursday, April 13, 2023 126© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 127: Building RESTful Java Applications with EMF

Namespace Prefixes• An Ecore package has an 'Ns Prefix'

property that must be set to the desired string

Thursday, April 13, 2023 127© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 128: Building RESTful Java Applications with EMF

Namespace Prefixes• The prefix is actually arbitrary, but must

be unique within a given XML/XMI document

• Typically this string corresponds to the last segment of the namespace URI, but in lower case

Thursday, April 13, 2023 128© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 129: Building RESTful Java Applications with EMF

Best Practice #2The namespace prefix defined for a resource

serialization should be of the form '<lowercase schema name>' (relative to the recommended namespace URI form)

Thursday, April 13, 2023 129© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 130: Building RESTful Java Applications with EMF

Extended Metadata Annotations• EMF uses annotations as a way of attaching

additional information to an Ecore (or generator) model which isn't considered part of the semantics but is used for other (downstream) processing, for example code generation or serialization

• It's analogous to the way UML uses stereotypes (for those familiar with UML)

• Every annotation used by EMF has a "source", which is typically a URI that uniquely identifies a class of annotations

Thursday, April 13, 2023 130© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 131: Building RESTful Java Applications with EMF

Extended Metadata Annotations• Common annotation sources used in EMF include

'http://www.eclipse.org/emf/2002/GenModel' (for code generation) and 'http:///org/eclipse/emf/ecore/util/ExtendedMetaData' (for extended metadata™)

Thursday, April 13, 2023 131© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 132: Building RESTful Java Applications with EMF

Extended Metadata Annotations• An EMF annotation also has a details map in

which simple key-value pairs (both strings) can be stored

• These details are analogous to tagged values in UML

• Extended metadata annotation details can be used to affect the way data elements are mapped to and from XML/XMI during serialization and deserialization

Thursday, April 13, 2023 132© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 133: Building RESTful Java Applications with EMF

Extended Metadata Annotations• Two such details keys for extended metadata are 'name', which determines the XML name for the annotated element, and 'kind', which determines the kind of XML element (i.e., attribute or element)

Thursday, April 13, 2023 133© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 134: Building RESTful Java Applications with EMF

Extended Metadata Annotations• One common use for extended metadata is to specify an

alternative name for a feature when it is serialized to XML/XMI, in particular when the name of the feature is plural

• In the sample model, a 'name' detail key has been added to the 'iD' and 'children' features with a values of 'id' and 'child'

• When serializing without this extended metadata (which, even if defined in an annotation, must be explicitly enabled), the corresponding XML names would be based directly on the feature names

<children xmi:type="tree:Node" iD="child1" label="Child 1"/><children xmi:type="tree:Node" iD="child2" label="Child 2"/>

Thursday, April 13, 2023 134© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 135: Building RESTful Java Applications with EMF

Extended Metadata Annotations• Serializing based on the extended metadata,

however, results in the more desirable names (e.g., every occurrence of the element defines a single child, and hence its XML name should be singular, but the accessor method in Java should probably be based on the plural feature name)

<child xmi:type="tree:Node" id="child1" label="Child 1"/><child xmi:type="tree:Node" id="child2" label="Child 2"/>

Thursday, April 13, 2023 135© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 136: Building RESTful Java Applications with EMF

Extended Metadata Annotations• Generally speaking, the 'kind' details entry

must also be specified any time a 'name' entry is specified

• By default, every Ecore attribute maps to an XML attribute and every reference maps to an XML attribute iff it references an element in the same document (i.e., via an idref), otherwise an XML element (i.e., either a sub-element or an href)

Thursday, April 13, 2023 136© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 137: Building RESTful Java Applications with EMF

Best Practice #3Extended metadata should be used in

resource serializations to achieve more desirable XML names

Thursday, April 13, 2023 137© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 138: Building RESTful Java Applications with EMF

ID Attributes• EMF supports the identification of an Ecore

attribute as an identifier• The significance of marking an attribute as an

identifier is that it value can be used as the means of linking elements in XML/XMI serializations

• The value of an identifier attribute must be unique within a given context, and for the purposes of (de)serialization, that context is a resource (XML/XMI document)

Thursday, April 13, 2023 138© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 139: Building RESTful Java Applications with EMF

ID Attributes• An Ecore attribute has an 'ID' property that

must be set to 'true' for identifier attributes

Thursday, April 13, 2023 139© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 140: Building RESTful Java Applications with EMF

ID Attributes• One problem with identifier attributes is that, if their values

are allowed to be modified via the API, clients can inadvertently introduce broken references

• To alleviate this concern, visibility of the setter for that attribute can be suppressed using a generator model annotation

Thursday, April 13, 2023 140© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 141: Building RESTful Java Applications with EMF

Proxy Resolution• EMF uses proxies to resolve references between

objects (potentially in different resources) on demand

• Support for this mechanism is provided by the EMF framework and invoked by generated code by default

• Of course, this proxy resolution behavior comes at a cost, so one must carefully consider where is in fact needed – there are cases, for example when you know that a referencing element will always be in the same resource (XML/XMI document) as a referenced element, when it isn't

Thursday, April 13, 2023 141© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 142: Building RESTful Java Applications with EMF

Proxy Resolution• An Ecore reference has a 'Resolve Proxies'

property that must be set to 'true' or 'false', depending on whether EMF's proxy resolution mechanism is required

Thursday, April 13, 2023 142© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 143: Building RESTful Java Applications with EMF

Proxy Resolution• Generally speaking, a container (parent) element

will always be in the same resource as its contained (child) elements (as is the case above, for an object root and its object identifier), so proxy resolution isn't needed, by default, for containment references

• However, if you intend to support containment proxies for your resources (i.e., separate elements within a given containment hierarchy over multiple resources), proxy resolution must be enabled

Thursday, April 13, 2023 143© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 144: Building RESTful Java Applications with EMF

The Generator Model (The Bad?)• The generator model is a decorator for an Ecore model that

specifies additional information used during code generation

• The generator model offers an ever-growing number of options that allow you to customize the code that EMF generates

• Among these options are ones that affect– the file extension and content type that will be defined (by

default) for your resources– what kind of resource serialization will be used (basically XML

or XMI)– whether cross-resource containment proxies will be supported

Thursday, April 13, 2023 144© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 145: Building RESTful Java Applications with EMF

File Extensions• File extensions are gradually becoming a thing of

the past; what should really matter is the type of content contained in a document

• Support for content type definition wasn't introduced until EMF 2.4, so for a while longer at least, file extensions are still important

• EMF provides a registry that associates resource factories (and hence the resources they create) with file extensions

Thursday, April 13, 2023 145© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 146: Building RESTful Java Applications with EMF

File Extensions• Registration of a resource factory against a file

extension can be done via a plug-in extension point (for applications based on Eclipse)

<extension point="org.eclipse.emf.ecore.extension_parser"> <parser type="tree" class=“org.eclipsecon2009.emf.tree.util.TreeResourceFactoryImpl"/></extension>

Thursday, April 13, 2023 146© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 147: Building RESTful Java Applications with EMF

File Extensions• What this plug-in extension does is register the tree

resource factory implementation (from our sample model) against resources (files) with a '.tree' file extension

• This means is that applications using a resource set to create an EMF resource for a given URI will obtain the corresponding resource implementation (from the registry) by default; unless, that is, this default (global) registration is overridden locally in the resource set (every resource set has a local registry which delegates to the global one)

• Note that once this plug-in extension is generated (as part of the plug-in's manifest file, plugin.xml), EMF won't overwrite it, so if you decide to change the file extension later, you'll need to update it manually

Thursday, April 13, 2023 147© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 148: Building RESTful Java Applications with EMF

File Extensions• Another plug-in extension that depends on

file extension is in the manifest for the generated editor plug-in

<editor id=“org.eclipsecon2009.emf.tree.presentation.TreeEditorID" name="%_UI_TreeEditor_label" icon="icons/full/obj16/TreeModelFile.gif" extensions="tree" class=“org.eclipsecon2009.emf.tree.presentation.TreeEditor“ contributorClass=“org.ecipsecon2009.emf.tree.presentation.TreeActionBarContributor"></editor>

Thursday, April 13, 2023 148© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 149: Building RESTful Java Applications with EMF

File Extensions• This plug-in extension registers the generated

editor against the file extension so that, by default, resources with that extension will be opened with the specified editor

• As with the resource factory registration, be sure to update this value manually if you change the extension (assuming you're generating and using the sample editor)

Thursday, April 13, 2023 149© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 150: Building RESTful Java Applications with EMF

File Extensions• Another place where the file extension

appears is in the plugin.properties file of the generated editor plug-in

_UI_TreeEditorFilenameExtensions = tree

Thursday, April 13, 2023 150© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 151: Building RESTful Java Applications with EMF

File Extensions• This string is used by the generated wizard when

creating new instance documents based on your model

• While EMF does update properties files when new classes or features are introduced into a model, it doesn't automatically remove them and won't overwrite their values, so again, if you change your file extension, don't forget to change this value

Thursday, April 13, 2023 151© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 152: Building RESTful Java Applications with EMF

File Extensions• So, where does the value for this file extension

actually come from?• It's based on the value specified via the 'File Extensions' property of a package in the EMF generator model

Thursday, April 13, 2023 152© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 153: Building RESTful Java Applications with EMF

Content Types• EMF provides a registry that associates resource

factories (and hence the resources they create) with content types

• Registration of a resource factory against a content type can be done via a plug-in extension point (for applications based on Eclipse)

<extension point="org.eclipse.emf.ecore.content_parser"> <parser contentTypeIdentifier=“org.eclipsecon2009.emf.tree" class=“org.eclipsecon2009.emf.tree.util.TreeResourceFactoryImpl"/></extension>

Thursday, April 13, 2023 153© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 154: Building RESTful Java Applications with EMF

Content Types• What this plug-in extension does is register the

tree resource factory implementation (from our sample model) against resources with the ‘org.eclipsecon2009.emf.tree' content type

• This means is that applications using a resource set to create an EMF resource for URI with a particular content type will obtain the corresponding resource implementation (from the registry) by default (unless it is overridden locally in the resource set)

• Note that once this plug-in extension is generated EMF won't overwrite it, so if you decide to change the content type later, you'll need to update it manuallyThursday, April 13, 2023 154© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM

Corp. | EPL v1.0

Page 155: Building RESTful Java Applications with EMF

Content Types• EMF will also generate a plug-in extension to

register the content type, and an associated content describer, with the Eclipse platform

<content-type base-type="org.eclipse.emf.ecore.xmi" file-extensions="tree" id=“org.eclipsecon2009.emf.tree" name="%_UI_Tree_content_type" priority="normal"> <describer class="org.eclipse.emf.ecore.xmi.impl.RootXMLContentHandlerImpl$Describer"> <parameter name="namespace" value="http://www.eclipsecon2009.org/emf/1.0/Tree" /> <parameter name="kind" value="xmi" /> </describer></content-type>

Thursday, April 13, 2023 155© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 156: Building RESTful Java Applications with EMF

Content Types• Since the default content describer is specific to the

namespace URI of your metamodel, which in turn is version-specific, it’s generally better to change this declaration to match by namespace pattern

<content-type base-type="org.eclipse.emf.ecore.xmi" file-extensions="tree" id=“org.eclipsecon2009.emf.tree" name="%_UI_Tree_content_type" priority="normal"> <describer class="org.eclipse.emf.ecore.xmi.impl.RootXMLContentHandlerImpl$Describer"> <parameter name="namespacePattern" value="http://www\.eclipsecon2009\.org/emf/(1\.0|1\.1)/Tree" /> <parameter name="kind" value="xmi" /> </describer></content-type>

Thursday, April 13, 2023 156© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 157: Building RESTful Java Applications with EMF

Content Types• A new version-specific content type declaration can then be

defined, as a child of the base declaration, each time your metamodel changes

<content-type base-type=“org.eclipsecon2009.emf.tree" file-extensions="tree" id=“org.eclipsecon2009.emf.tree_1_0" name="%_UI_Tree_1_0_content_type" priority="normal"> <describer class="org.eclipse.emf.ecore.xmi.impl.RootXMLContentHandlerImpl$Describer"> <parameter name="namespace" value="http://www.eclipsecon2009.org/emf/1.0/Tree" /> <parameter name="kind" value="xmi" /> </describer></content-type>

Thursday, April 13, 2023 157© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 158: Building RESTful Java Applications with EMF

Content Types• Another extension that depends on

content type is in the manifest for the generated editor plug-in

<editor id=“org.eclipsecon2009.emf.tree.presentation.TreeEditorID" name="%_UI_TreeEditor_label" icon="icons/full/obj16/TreeModelFile.gif" class=“org.eclipsecon2009.emf.tree.presentation.TreeEditor“ contributorClass=“org.eclipsecon2009.emf.tree.presentation.TreeActionBarContributor"> <contentTypeBinding contentTypeId=“org.eclipsecon2009.emf.tree"/></editor>

Thursday, April 13, 2023 158© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 159: Building RESTful Java Applications with EMF

Content Types• This plug-in extension registers the generated

editor against the content type so that, by default, resources with that content type will be opened with the specified editor

• As with the resource factory registration, be sure to update this value manually if you change the content type identifier (assuming you're generating and using the sample editor)

Thursday, April 13, 2023 159© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 160: Building RESTful Java Applications with EMF

Content Types• So, where does the value for this content type

identifier actually come from?• It's based on the value specified via the ‘Content Type Identifier' property of a package in the EMF generator model

Thursday, April 13, 2023 160© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 161: Building RESTful Java Applications with EMF

Best Practice #4A new content type (and describer) should

be registered each time your metamodel changes

Thursday, April 13, 2023 161© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 162: Building RESTful Java Applications with EMF

Resource Types• As previously mentioned, EMF provides

support for serializing resources in XML or XMI format

• The choice between the two depends on what you're looking to do, but XMI resources are generally more flexible (e.g., they support cross-resource containment and the use of XMI identifiers), so XMI is probably the better choice

Thursday, April 13, 2023 162© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 163: Building RESTful Java Applications with EMF

Resource Types• The value of the 'Resource Type' property of a

package in the EMF generator model can be set (to 'None', 'Basic', 'XML', or 'XMI') to specify the desired resource type

Thursday, April 13, 2023 163© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 164: Building RESTful Java Applications with EMF

Best Practice #5The resource type for resource serializations

should be XMI (unless the source model is an XML schema)

Thursday, April 13, 2023 164© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 165: Building RESTful Java Applications with EMF

Containment Proxies• EMF supports the partitioning of an object

hierarchy (containment tree) across multiple resources

• To do so, the framework makes a distinction between containment proxies (references from parent objects to child objects in different resources) and non-containment (or cross-reference) proxies (references from objects to objects in other resources)

• Since support for proxy resolution requires a certain amount of overhead (via a specialized list implementation), the choice to enable cross-resource containment via containment proxies has to be made explicitly based on the needs of your resource implementation

Thursday, April 13, 2023 165© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 166: Building RESTful Java Applications with EMF

Containment Proxies• Why would one want to enable

containment proxies?• One reason is that they go a long way

toward supporting a scalable architecture where objects within a (potentially large) containment tree can be loaded and unloaded dynamically as part of separate resources, thereby reducing the concurrent memory footprint

Thursday, April 13, 2023 166© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 167: Building RESTful Java Applications with EMF

Containment Proxies• The value of the 'Containment Proxies'

property of the model (root node) in an EMF generator model can be set to 'true' to enable cross-resource containment

• Of course, in order for a given containment reference to support containment proxies, the 'Resolve Proxies' property must be set to 'true' in the Ecore model

Thursday, April 13, 2023 167© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 168: Building RESTful Java Applications with EMF

Best Practice #6Containment proxies should be enabled for

all resource serializations

Thursday, April 13, 2023 168© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 169: Building RESTful Java Applications with EMF

The Code (The Ugly?)• The code is, well, the code• Here, though, we’re referring specifically to the

code that gets generated for you by EMF and some of the framework customizations that EMF makes available

• The main things to consider here are– what character encoding will be used– which version of XMI will be used– what form of identifiers will be used (i.e., in references

via idref or href attributes)– what the default load and save options will be for

documents based on your resource implementation

Thursday, April 13, 2023 169© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 170: Building RESTful Java Applications with EMF

Encoding• EMF supports a number of different encoding

choices for resources – ASCII, UTF-8, UTF-16, UTF-16BE, UTF-16LE, ISO-8859-1

• The most versatile and/or commonly used of these is UTF-8

• The encoding for a given serialization will appear on the first line of the XML/XMI document

<?xml version="1.0" encoding="UTF-8"?>

Thursday, April 13, 2023 170© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 171: Building RESTful Java Applications with EMF

Encoding• The encoding of an EMF resource can be set

programmatically using the XMLResource#setEncoding(String) method

• Generally speaking, however, its a good idea to hard-code the default encoding for a resource into its (generated) resource implementation class by marking the constructor as @generated NOT and adding the method call

/** * Creates an instance of the resource. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @param uri the URI of the new resource. * @generated NOT */ public TreeResourceImpl(URI uri) { super(uri); setEncoding("UTF-8"); // ...}

Thursday, April 13, 2023 171© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 172: Building RESTful Java Applications with EMF

Best Practice #7The default encoding of all resource

serializations should be "UTF-8"

Thursday, April 13, 2023 172© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 173: Building RESTful Java Applications with EMF

XMI Versions• Technically speaking, the (de)serialization support

provided for XML and XMI by EMF supports only a subset of the full syntax dictated by the corresponding specifications for these schemas

• An XML or XMI serialization produced using EMF should be well-formed and valid (assuming the right options are used)

• But well-formed, valid document produced with other tools that use a larger subset of constructs may not necessarily be handled very well by EMF

Thursday, April 13, 2023 173© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 174: Building RESTful Java Applications with EMF

XMI Versions• The support EMF provides for specific versions of

XMI (2.0 or 2.1), then, is really only a statement of intent (e.g., "we'll say we support it until someone complains that we don't")

• Nevertheless, most modern tools that produce XMI serializations do so using XMI version 2.1

• The version of XMI used in a given serialization appears in the first element of the document

Thursday, April 13, 2023 174© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 175: Building RESTful Java Applications with EMF

XMI Versions• Here we see, based on the xmi:version and xmlns:xmi attributes, a document that's been serialized using XMI version 2.1

• A document based on XMI 2.0 (the only other real alternative) would have an xmi:version of "2.0" and an xmlns:xmi of "http://www.omg.org/XMI"

<tree:Node xmi:version="2.1" xmlns:xmi="http://schema.omg.org/spec/XMI/2.1" xmlns:tree="http://www.eclipsecon2009.org/emf/1.0/Tree" xmi:id="root" label="Root" kind="Root"/>

Thursday, April 13, 2023 175© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 176: Building RESTful Java Applications with EMF

XMI Versions• The XMI version an EMF resource can be set

programmatically using the XMIResource#setVersion(String) method

• Generally speaking, however, its a good idea to hard-code the default XMI version for a resource into its (generated) resource implementation class by marking the constructor as @generated NOT and adding the method call

/** * Creates an instance of the resource. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @param uri the URI of the new resource. * @generated NOT */ public TreeResourceImpl(URI uri) { super(uri); // ... setXMIVersion("2.1");}

Thursday, April 13, 2023 176© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 177: Building RESTful Java Applications with EMF

Best Practice #8The default XMI version of a resource

serialization should be "2.1"

Thursday, April 13, 2023 177© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 178: Building RESTful Java Applications with EMF

Identifiers• As mentioned previously in the context of ID

attributes, EMF provides support for the use of identifiers in serializing references between elements in XML/XMI

• Generally speaking, in order for an element in an XMI serialization to be referenceable, it must either have a value for the xmi:id attribute (the more common case) or for an attribute that has been designated as its ID attribute, and all references to the element (via idrefs and hrefs) must be based on that value

Thursday, April 13, 2023 178© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 179: Building RESTful Java Applications with EMF

Identifiers• If your metamodel has ID attributes, whose

values you want used for references serialized to XMI, there are a couple of things you should do

• First, you'll want to enable the use of the intrinsic identifier cache to improve the performance of object look-ups

Thursday, April 13, 2023 179© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

/** * Creates an instance of the resource. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @param uri the URI of the new resource. * @generated NOT */ public TreeResourceImpl(URI uri) { super(uri); // ... setIntrinsicIDToEObjectMap(new HashMap<String, EObject>());}

Page 180: Building RESTful Java Applications with EMF

Identifiers• The second thing you'll need to do (assuming the

cache has been enabled) is ensure that any time the value of an ID attribute changes in the model, the resource's mapping of intrinsic identifiers to objects is updated

• In our sample model, we need to update the mapping (e.g. clear the cache) if the ‘iD’ attribute changes

Thursday, April 13, 2023 180© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 181: Building RESTful Java Applications with EMF

Identifierspublic void setIDGen(String newID) { String oldID = iD; iD = newID; if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, TreePackage.NODE__ID, oldID, iD));}

public void setID(String newID) { Resource eResource = eResource(); if (eResource instanceof TreeResourceImpl) { ((TreeResourceImpl) eResource).getIntrinsicIDToEObjectMap().clear(); } setIDGen(newID);}

Thursday, April 13, 2023 181© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 182: Building RESTful Java Applications with EMF

Identifiers• Here we see use of the other code customization

pattern – marking the original method with a 'Gen' suffix and introducing a new method with the original signature which delegates to it

• This pattern is useful in cases where you want to preserve the original behavior, but do some additional processing before and/or after it is executed

Thursday, April 13, 2023 182© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 183: Building RESTful Java Applications with EMF

Identifiers• If your metamodel does not make use of ID

attributes, a dead simple alternative for ensuring that XMI identifiers are serialized is to use UUIDs – Universally Unique Identifiers

• EMF provides built-in support for automatic generation and (de)serialization of UUIDs as XMI identifiers

@Overrideprotected boolean useUUIDs() { return true;}

Thursday, April 13, 2023 183© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 184: Building RESTful Java Applications with EMF

Identifiers• When using UUIDs, a unique identifier is assigned

to an object as soon as is attached to a resource, and it is preserved even of the object is later detached from on resource and attached to another

• The format of the UUIDs generated by EMF are based on a standard 128 bit UUID (see ftp://ietf.org/internet-drafts/draft-mealling-uuid-urn-02.txt) but encoded into a padded base 64 string

<child xmi:type="tree:Node" xmi:id="_cKLewOvxEdyeZZzrmWnnqg" label="Child"/>

Thursday, April 13, 2023 184© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 185: Building RESTful Java Applications with EMF

Best Practice #9All references in XMI resource serializations

should be based on the value for an ID attribute or xmi:id

Thursday, April 13, 2023 185© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 186: Building RESTful Java Applications with EMF

Save Options• EMF provides many save options which can be

used to tweak the way resources are serialized to XML/XMI

• We'll cover a few of the important ones here, but encourage you to explore all the various options available

• To set or enable these options by default, the createResource(URI) method of the resource factory implementation class must be customized

Thursday, April 13, 2023 186© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 187: Building RESTful Java Applications with EMF

Save Options/** * Creates an instance of the resource. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated NOT */@Overridepublic Resource createResource(URI uri) { XMIResource result = new TreeResourceImpl(uri);

// ...

Map<Object, Object> defaultSaveOptions = result.getDefaultSaveOptions();

// ...

return result;}

Thursday, April 13, 2023 187© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 188: Building RESTful Java Applications with EMF

Save Options• The XMLResource.OPTION_EXTENDED_META_DATA

option, as alluded to earlier, must be enabled in order to respect extended metadata annotations that have been attached to your Ecore model

• To enable this option, add an entry to the options map with XMLResource.OPTION_EXTENDED_META_DATA as the key and Boolean.TRUE as the value

defaultSaveOptions.put(XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE);

Thursday, April 13, 2023 188© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 189: Building RESTful Java Applications with EMF

Save Options• The XMIResource.OPTION_USE_XMI_TYPE option

will ensure that xmi:type attributes are used instead of xsi:type attributes (as seen earlier); the former are obviously more desirable in XMI serializations

• To enable this option, add an entry to the options map with XMLResource.OPTION_USE_XMI_TYPE as the key and Boolean.TRUE as the value

defaultSaveOptions.put(XMIResource.OPTION_USE_XMI_TYPE, Boolean.TRUE);

Thursday, April 13, 2023 189© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 190: Building RESTful Java Applications with EMF

Save Options• The XMLResource.OPTION_SAVE_TYPE_INFORMATION tells

EMF when to save type information in xmi:type attributes• Strictly speaking EMF doesn't always need to save type

information because it can obtain it from the metamodel (e.g., if the type of the object is the same as the type of the feature)

• However, there are cases, particularly in migration scenarios (where the type of a feature may have changed in newer versions of the schema), where it is useful to serialize type information more often than EMF does by default

Thursday, April 13, 2023 190© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 191: Building RESTful Java Applications with EMF

Save Options• The extreme option is to always save type

information; this can be achieved by adding an entry to the options map with XMLResource.OPTION_SAVE_TYPE_INFORMATION as the key and Boolean.TRUE as the value

• A more reasonable compromise is to pass an anonymous subclass of XMLTypeInfo that specifies exactly when the type information needs to be saved

Thursday, April 13, 2023 191© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 192: Building RESTful Java Applications with EMF

Save OptionsdefaultSaveOptions.put(XMLResource.OPTION_SAVE_TYPE_INFORMATION, new XMLTypeInfo() {

public boolean shouldSaveType(EClass objectType, EClassifier featureType, EStructuralFeature feature) {

return objectType != featureType && objectType != XMLTypePackage.Literals.ANY_TYPE;

}

public boolean shouldSaveType(EClass objectType, EClass featureType, EStructuralFeature feature) {

return objectType != featureType;

} });

Thursday, April 13, 2023 192© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 193: Building RESTful Java Applications with EMF

Load Options• EMF also provides many load options which can

be used to tweak the way resources are de-serialized from XML/XMI

• We'll cover a few of the important ones here, but encourage you to explore all the various options available

• To set or enable these options by default, the createResource(URI) method of the resource factory implementation class must be customized

Thursday, April 13, 2023 193© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 194: Building RESTful Java Applications with EMF

Load Options/** * Creates an instance of the resource. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated NOT */@Overridepublic Resource createResource(URI uri) { XMIResource result = new TreeResourceImpl(uri);

// ...

Map<Object, Object> defaultLoadOptions = result.getDefaultLoadOptions();

// ...

return result;}

Thursday, April 13, 2023 194© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 195: Building RESTful Java Applications with EMF

Load Options• The XMLResource.OPTION_EXTENDED_META_DATA

option can also be used during de-serialization, and must be enabled in order to recognize data that has been serialized based on extended metadata annotations

• To enable this option, add an entry to the options map with XMLResource.OPTION_EXTENDED_META_DATA as the key and Boolean.TRUE as the value

defaultLoadOptions.put(XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE);

Thursday, April 13, 2023 195© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 196: Building RESTful Java Applications with EMF

Load Options• The XMLResource.OPTION_DEFER_IDREF_RESOLUTION option instructs EMF to defer resolution of same document references until the end of the document is reached

• Depending on the nature and order of cross-references in your data this option may be required in order to successfully de-serialize XML/XMI documents based on them; even if it isn't required, this option improves load performance, so it should generally be used

Thursday, April 13, 2023 196© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 197: Building RESTful Java Applications with EMF

Load Options• To enable this option, add an entry to the options

map with XMLResource.OPTION_DEFER_IDREF_RESOLUTION as the key and Boolean.TRUE as the value

defaultLoadOptions.put(XMLResource.OPTION_DEFER_IDREF_RESOLUTION, Boolean.TRUE);

Thursday, April 13, 2023 197© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 198: Building RESTful Java Applications with EMF

Load Options• The XMLResource.OPTION_RECORD_UNKNOWN_FEATURE option tells EMF to preserve unrecognized data (i.e. XML elements and attributes) during de-serialization

• Such data are added to a map, accessible via the XMLResource#getEObjectToExtensionMap() method, which can be introspected and processed after a resource has been loaded

• The data in this map are then serialized back out the next time the resource is saved

Thursday, April 13, 2023 198© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 199: Building RESTful Java Applications with EMF

Load Options• This is incredibly useful when dealing with mixed

content from unknown sources and/or in migration scenarios where features that existed on an older version of a schema are no longer valid

• To enable this option, add an entry to the options map with XMLResource.OPTION_RECORD_UNKNOWN_FEATURE as the key and Boolean.TRUE as the value

defaultLoadOptions.put(XMLResource.OPTION_RECORD_UNKNOWN_FEATURE, Boolean.TRUE);

Thursday, April 13, 2023 199© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 200: Building RESTful Java Applications with EMF

Best Practice #10Default save and load options (as described

here) should be initialized for resource serializations

Thursday, April 13, 2023 200© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 201: Building RESTful Java Applications with EMF

Resource Best Practices

Exercise 3

Thursday, April 13, 2023 201© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 202: Building RESTful Java Applications with EMF

• EMF the de facto standard reference implementation• EMF is a low cost modeling solution for Java

– SD Times ranks it “top shelf” even relative to pricey commercial software

• http://www.sdtimes.com/content/article.aspx?ArticleID=32287

• It exploits the models already underlying the application

• It supports iterative development that facilitates both model-based changes and hand-written changes equally well

• It boosts productivity by automating routine and mundane development tasks

• It’s the foundation for data integration by providing a uniform way to access all models

Summary

Thursday, April 13, 2023 202© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 203: Building RESTful Java Applications with EMF

What’s in EMF 2.5 (Galileo release)• Low memory footprint implementation• Several bug fixes and small features

(+120)• Performance improvements

Thursday, April 13, 2023 203© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 204: Building RESTful Java Applications with EMF

Low Memory Footprint Implementation• Starting with EMF 2.5, it is possible to configure

an EMF generator model to produce a model implementation that is optimally tuned for memory efficiency

• Several techniques were applied to produce “lean” instances, including– “Flag” fields to store certain information– Shared data storage buffers– “Smart” list implementations

• Enabled by changing the ‘Root Extends Class’ property of the generator model (under the ‘Model Class Defaults’ category) to “org.eclipse.emf.ecore.impl.MinimalEObject$Container”.

Thursday, April 13, 2023 204© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 205: Building RESTful Java Applications with EMF

Conclusion• We have covered

– REST and the architectural principles on which it is based

– How EMF supports development of RESTful applications in Java via its resource persistence framework

– Best practices for working with EMF resources

Thursday, April 13, 2023 205© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 206: Building RESTful Java Applications with EMF

• Online help– http://help.eclipse.org/ganymede/index.jsp?nav=/1

4• Website

– http://www.eclipse.org/emf• Downloads• Wiki• FAQ• Newsgroup• Documentation

• Book– Eclipse Modeling Framework

• Second Edition– http://safari.awprofessional.com/9780321331885

Resources

Thursday, April 13, 2023 206© Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

Page 207: Building RESTful Java Applications with EMF

Legal Notices• OMG and Object Management Group are

trademarks of the Object Management Group• UML and XMI are registered trademarks of the

Object Management Group• Hypertext Transfer Protocol, HTTP,

Metadata, and XML are trademarks of the World Wide Web Consortium; marks of W3C are registered and held by its host institutions MIT, ERCIM, and Keio

• Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both

• Other company, product, or service names may be trademarks or service marks of others

Thursday, April 13, 2023 © Macro Modeling Ltd., Embarcadero Technologies Inc., IBM Corp. | EPL v1.0

207