Skip to content
Nuno Macedo edited this page May 28, 2018 · 5 revisions

Supported languages

Ecore metamodels

Additional constraints in the metamodel can be defined by embedding OCL (OMG's constraint language) formulas in annotations. This is the same mechanism prescribed by EMF's OCLinEcore. In order to be processed as such, the source of the annotation must be set to http://www.eclipse.org/emf/2002/Ecore/OCL. For instance, the following example from the object/relational mapping states that the class hierarchy must be acyclic and that names are unique:

OCL constraints

Annotations are also used to control the shape of newly generated models. In this case, the constraints are set with the source Echo/Gen, denoting that they will only be processed by model generation procedures. For instance, in the previous figure, the generation constraint is that the created attributes must have the same name as the owning class.

The definition of operations, required to use an operation-based distance follows the same procedure. The following example presents the definition in OCL formulas of the setName operation of a class. OCL constraints The apparent verbosity of the definition is due to the frame conditions of the operation (the unchanged parts), which must also be specified.

OCL constraints

The complete subset of the OCL language supported can be consulted in this paper. It includes the transitive closure operator, recently introduced by the OCL standard.

QVT Relations

Echo supports most constructs specified by the QVT standard. QVT-R transformations relate a set of models (although currently only binary transformations are supporter). Their main components are relations, which relate elements from the models through domain patterns. For instance, consider the following relations from the expand/collapse example:

top relation S2S { 
	n: String; 
	domain hm s1:State { 
		opposite(StateMachine::states) = sm:StateMachine{},
  		name=n} 
  		{s1.container->isEmpty() 
  	};
	domain nm s2:State { 
  		opposite(StateMachine::states) = tm:StateMachine{},
  		name=n 
  	};
  	when { M2M(sm,tm); }	
}

top relation T2T { 
	n: String; s,t: HSM::State; 
	domain hm t1:Transition { 
  		target = trg1:State{}, 
  		source = src1:State{}
  	};
	domain nm t2:Transition { 
  		target = trg2:State{}, 
  		source = src2:State{}
  	};
	where { 
	    s.container->isEmpty() and 
		(s = src1 or src1->closure(container)->includes(s)) and 
		S2S(s,src2) and
		t.container->isEmpty() and 
		(t = trg1 or trg1->closure(container)->includes(t)) and 
		S2S(t,trg2); 
	}
}

In these case, relation S2S relates states with no container from the HSM model with states from the NHSM model with the same name. If relations must hold for all elements, they are marked as top. Otherwise they must hold only when called by other rules. Furthermore, S2S has a pre-condition, defined by the when clause, that only states whose owning state machines are related should be matched (the relation M2M is omitted). The opposite keyword can be used to navigate features in the opposite direction.

Note that arbitrary OCL constraints can be used both in when and where (post-conditions) clauses, and in the domain patterns to further restrict the candidate elements (as in s1.owner->isEmpty()). This includes the closure operator (as in the where clause of T2T). Recursive relation calls in the where and when constraints are also supported, as long as recursion is well-founded.

Clone this wiki locally