Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

ConstructRuntime instance structures

EClassifier

Abstract superclass of EClass and EDataType

 

EClass

The class construct, has a name and can be abstract (cannot be instantiated) and also marked as interface (no state, just methods). A container of so-called structural features (attributes and associations). May have a list of superclasses (EClass).

Example:

PlantUML Macro
class OrgUnit
class Person

Non-abstract classes can be instantiated. Instances will have attributes values and links to other objects corresponding to contained and inherited features.

 

PlantUML Macro
object "~#o1 : OrgUnit" as o1
object "~#p1 : Person" as p1

EDataType

A non-modelled or "foreign" type, provided by the host language and runtime environment, like int, double, String, Date etc. Many such types are pre-defined by Ecore, e.g. EInt, EIntegerObject, EDouble, EDoubleObject, EBoolean, EBooleanObject, EString, EDate corresponding to Java's int, Integer, double, Double, boolean, Boolean, String and Date types. You can define your own, to be able to use other Java types in your model.

Instances of the corresponding (non-abstract) Java classes can be created from Strings.

EStructualFeature

Abstract superclass of EAttribute and EReference. The distinction between these two is the kind of type they have, EDataType and EClass, respectively, so when adding a "property" to a class you decide which of EAttribute and EReference to use based on whether the type is an EDataType or EClass.

An EStructuralFeature has a name, type (an EDataType) and multiplicity (lower and upper bounds).

 

EAttribute

An EStructuralFeature where the type is an EDataType.

 

PlantUML Macro
class OrgUnit {
	String name
}
class Person {
	String name
}
or using inheritance
PlantUML Macro
abstract class Named {
	String name
}

class OrgUnit extends Named
class Person extends Named

Both OrgUnit and Person instances have a name attribute.

 

PlantUML Macro
object "~#o1: OrgUnit" as o1 {
	name = "IDI"
}
object "~#p1: Person" as p1 {
	name = "Hallvard"
}

EReference

An EStructuralFeature where the type is an EClass. Corresponds to the target role of an association from the owning EClass to a target EClass. The association itself is not explicitly modelled.

PlantUML Macro
class OrgUnit {
}
class Person {
}
OrgUnit <- Person: works-inworksIn

PlantUML Macro
object "~#o1: OrgUnit" as o1 {
	name = "IDI"
}
object "~#p1: Person" as p1 {
	name = "Hallvard"
}
o1 <- p1: works-inworksIn

Two EReferences may be each other's opposite, meaning they correspond to roles of the logically same association. This implies the consistency requirement that if one instance refers to another, the other must refer back, and vice versa.

 

PlantUML Macro
class OrgUnit {
}
class Person {
}
OrgUnit "works-inworksIn" -- "workers *" Person

Consistency requirement: Since o1 has workers links to p1 and p2, p1 and p2 must both have a works-in link to o1.

PlantUML Macro
object "~#o1: OrgUnit" as o1 {
	name = "IDI"
}
object "~#p1: Person" as p1 {
	name = "Hallvard"
}
object "~#p2: Person" as p2 {
	name = "Letizia"
}
o1 <-- p1: works-inworksIn
o1 --> p1: workers
o1 <-- p2: works-inworksIn
o1 --> p2: workers

EReferences can be marked as containment or container, to support creating strict hierarchies. A containment reference points down the hierarchy and a container reference points up. Often you have containment and container references in pairs that are each others opposites. An object can only be directly contained in one container, and this is enforced. If we model the workers EReference as containment, meaning a Person belongs to only one OrgUnit, the opposite works-in worksIn EReference is automatically marked as container.

 

PlantUML Macro
class OrgUnit {
}
class Person {
}
OrgUnit "works-inworksIn" *-- "workers *" Person
 

In general you want objects structures to be hierarchies with one root, hence containment and container markings are important. Usually you want to ensure that every class has a container EReference, unless you consider it a root object in the hierarchy.

PlantUML Macro
object "~#o1: OrgUnit" as o1 {
	name = "IDI"
}
object "~#p1: Person" as p1 {
	name = "Hallvard"
}
object "~#p2: Person" as p2 {
	name = "Letizia"
}
o1 "works-inworksIn" *--> "workers *" p1
o1 "works-inworksIn" *--> "workers *" p2

EOperation

Corresponds to methods. Includes return type (EClassifier), typed (EClassifier) parameters and a list of types it may throw (EDataType).


PlantUML Macro
class OrgUnit {
   void fire(Person)
}
class Person {
}

 

...

Ecore includes a mechanism for attaching extra data to all the above modelling elements, in the form of String key-value pairs. The extra data is typically used by tools, e.g. annotations are used for naming constraints (that will need to be implemented by hand in the generated code, see Validation Constraints and validation) and providing method bodies for the code generator. You may also add your own custom annotations that are utilised by your own tools.

...

Class diagramObject diagram of meta-objects

PlantUML Macro
abstract class Named {
	String name
}
class OrgUnit extends Named {
   void fire(Person person)
}
class Person extends Named {
}
OrgUnit "works-inworksIn" -- "workers *" Person

PlantUML Macro
object "~#c1 : EClass" as Named {
	name = "Named"
	abstract = true
}
object "~#c1 : EAttribute" as nameAttr {
	name = "name"
	lowerlowerBound = 0
	upperupperBound = 1
}
object "~#dt1 : EDataType" as EString {
	name = "EString"
	instanceClassName = "java.lang.String"
}
nameAttr --> "eType" EString
Named *--> "eStructuralFeatures" nameAttr
 
object "~#c2 : EClass" as OrgUnit {
	name = "OrgUnit"
}
OrgUnit --> "eSuperTypes" Named
object "~#c3 : EClass" as Person {
	name = "Person"
}
Person --> "eSuperTypes" Named
object "~#m1 : EOperation" as fire {
	name = "fire"
}
object "~#p1 : EParameter" as personParam {
	name = "person"
}
personParam --> "eType" Person
fire *--> "eParameters" personParam
OrgUnit *--> "eOperations" fire
 
object "~#r1 : EReference" as worksInRef {
	name = "works-inworksIn"
	lowerlowerBound = 0
	upperupperBound = 1
}
worksInRef --> "eType" OrgUnit
Person *--> "eStructuralFeatures" worksInRef
 
object "~#r2 : EReference" as workersRef {
	name = "workers"
 	lowerlowerBound = 0
	upperupperBound = -1 // unbounded
}
workersRef --> "eType" Person
OrgUnit *--> "eStructuralFeatures" workersRef
 
workersRef "eOpposite" <--> "eOpposite" worksInRef

...