Skip to content

Commit

Permalink
#131 Create new operation ExtractClass; New APP meta-model; Create te…
Browse files Browse the repository at this point in the history
…st for app evolution of operation ExtractClass;
  • Loading branch information
Petr Tarant committed Apr 3, 2013
1 parent 62acbdf commit ed33f79
Show file tree
Hide file tree
Showing 44 changed files with 89 additions and 703 deletions.
30 changes: 12 additions & 18 deletions migdb.mm.app/models/mm-app.ecore
@@ -1,8 +1,6 @@
<?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="mm"
nsURI="http://www.collectionspro.eu/jam/mm" nsPrefix="mm">
<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="mm" nsURI="http://www.collectionspro.eu/jam/mm" nsPrefix="mm">
<eSubpackages name="app" nsURI="http://www.collectionspro.eu/jam/mm/app" nsPrefix="app">
<eClassifiers xsi:type="ecore:EClass" name="ModelRoot" abstract="true"/>
<eClassifiers xsi:type="ecore:EClass" name="Structure" eSuperTypes="#//app/ModelRoot">
Expand Down Expand Up @@ -244,30 +242,26 @@
<eStructuralFeatures xsi:type="ecore:EAttribute" name="className" lowerBound="1"
eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="MergeClasses" eSuperTypes="#//app/ops/DecomposableOperation">
<eStructuralFeatures xsi:type="ecore:EAttribute" name="class1" lowerBound="1"
eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="class2" lowerBound="1"
eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="mergedClassName" lowerBound="1"
eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="ExtractClass" eSuperTypes="#//app/ops/DecomposableOperation">
<eClassifiers xsi:type="ecore:EClass" name="ExtractClass" eSuperTypes="#//app/ops/AtomicOperation">
<eStructuralFeatures xsi:type="ecore:EAttribute" name="sourceClassName" lowerBound="1"
eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="extractPropertiesNames"
lowerBound="1" upperBound="-1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="extractClassName" lowerBound="1"
eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="ExtractSuperClass" eSuperTypes="#//app/ops/DecomposableOperation">
<eClassifiers xsi:type="ecore:EClass" name="ExtractSuperClass" eSuperTypes="#//app/ops/AtomicOperation">
<eStructuralFeatures xsi:type="ecore:EAttribute" name="sourceClassesName"
lowerBound="1" upperBound="-1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="extractPropertiesName"
lowerBound="1" upperBound="-1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="extractParentName"
lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="MergeClasses" eSuperTypes="#//app/ops/DecomposableOperation">
<eStructuralFeatures xsi:type="ecore:EAttribute" name="class1" lowerBound="1"
eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="class2" lowerBound="1"
eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="mergedClassName" lowerBound="1"
eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="ZipperHierarchy" eSuperTypes="#//app/ops/DecomposableOperation">
<eStructuralFeatures xsi:type="ecore:EAttribute" name="className" lowerBound="1"
eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
Expand Down
22 changes: 10 additions & 12 deletions migdb.mm.app/models/mm-app.emf
Expand Up @@ -209,23 +209,21 @@ package app {
attr String[1] className;
}

class MergeClasses extends DecomposableOperation {
attr String[1] class1;
attr String[1] class2;
attr String[1] mergedClassName;
}

class ExtractClass extends DecomposableOperation {
class ExtractClass extends AtomicOperation{
attr String[1] sourceClassName;
attr String[+] extractPropertiesNames;
attr String[1] extractClassName;
}
}

class ExtractSuperClass extends DecomposableOperation {
class ExtractSuperClass extends AtomicOperation {
attr String[+] sourceClassesName;
attr String[+] extractPropertiesName;
attr String[1] extractParentName;
}
}

class MergeClasses extends DecomposableOperation {
attr String[1] class1;
attr String[1] class2;
attr String[1] mergedClassName;
}

class ZipperHierarchy extends DecomposableOperation {
attr String[1] className;
Expand Down
26 changes: 13 additions & 13 deletions migdb.qvto/transforms/main/builder_app.qvto
Expand Up @@ -168,11 +168,9 @@ helper _moveProperty(_owningClassName : String, _name : String, _targetClassName
}
}

helper _extractClass(_sourceClassName : String, _extractPropertiesNames : OrderedSet(String),
_extractClassName : String) : APP::ops::ExtractClass {
helper _extractClass(_sourceClassName : String, _extractClassName : String) : APP::ops::ExtractClass {
return object APP::ops::ExtractClass {
sourceClassName := _sourceClassName;
extractPropertiesNames := _extractPropertiesNames;
extractClassName := _extractClassName;
}
}
Expand Down Expand Up @@ -325,8 +323,7 @@ helper _class(_name : String, _parent : StandardClass,
return cls;
}

helper _class(_name : String, _idProperty : PrimitiveProperty,
_properties : OrderedSet(MultipliableProperty)) : StandardClass{
helper _class(_name : String, _idProperty : PrimitiveProperty, _properties : OrderedSet(MultipliableProperty)) : StandardClass {
assert(_idProperty <> null);
var cls : StandardClass := object StandardClass {
name := _name;
Expand All @@ -336,25 +333,28 @@ helper _class(_name : String, _idProperty : PrimitiveProperty,
return cls;
}

helper _class(_name : String, _idProperty : PrimitiveProperty,
_properties : OrderedSet(MultipliableProperty), _inheritanceType : InheritanceType
) : StandardClass{
helper _class(_name : String, _idProperty : PrimitiveProperty, _properties : OrderedSet(MultipliableProperty), _inheritanceType : InheritanceType ) : StandardClass{
var cls : StandardClass := _class(_name, _idProperty, _properties);
cls.inheritanceType := _inheritanceType;
return cls;
}

helper _class(_name : String, _idProperty : PrimitiveProperty, _isAbstract : Boolean,
type : APP::InheritanceType) : StandardClass{
helper _class(_name : String, _idProperty : PrimitiveProperty, _isAbstract : Boolean, type : APP::InheritanceType) : StandardClass {
var cls : StandardClass := _class(_name, _idProperty, OrderedSet{});
cls.inheritanceType := type;
cls.isAbstract := _isAbstract;
return cls;
}

helper _class(_name : String, _idProperty : PrimitiveProperty,
_properties : OrderedSet(MultipliableProperty), _isAbstract : Boolean,
type : APP::InheritanceType) : StandardClass{
// create not abstract class with joined inheritance type
helper _class(_name : String, _idProperty : PrimitiveProperty ) : StandardClass {
var cls : StandardClass := _class(_name, _idProperty, OrderedSet{});
cls.inheritanceType := InheritanceType::joined;
cls.isAbstract := false;
return cls;
}

helper _class(_name : String, _idProperty : PrimitiveProperty, _properties : OrderedSet(MultipliableProperty), _isAbstract : Boolean, type : APP::InheritanceType) : StandardClass{
var cls : StandardClass := _class(_name, _idProperty, _properties);
cls.inheritanceType := type;
cls.isAbstract := _isAbstract;
Expand Down
94 changes: 26 additions & 68 deletions migdb.qvto/transforms/main/evolution_app.qvto
Expand Up @@ -51,31 +51,25 @@ abstract query APP::ops::DecomposableOperation::

/* ++++++++++ BASIC OPERATIONS ++++++++++++++++++++ */

query APP::ops::AddPrimitiveClass::isValid(structure : APP::Structure, inout errorLog : ErrorLog,
operationIndex : Integer) : Boolean {
return checkEntityNotExists(self.name, structure, errorLog, operationIndex,
getEvolutionAppTransformationId());
query APP::ops::AddPrimitiveClass::isValid(structure : APP::Structure, inout errorLog : ErrorLog, operationIndex : Integer) : Boolean {
return checkEntityNotExists(self.name, structure, errorLog, operationIndex, getEvolutionAppTransformationId());
}

helper APP::ops::AddPrimitiveClass::apply(inout structure : APP::Structure) {
structure.entities += _primitiveClass(self.name, self.primitiveType);
return;
}

query APP::ops::AddEmbeddedClass::isValid(structure : APP::Structure, inout errorLog : ErrorLog,
operationIndex : Integer) : Boolean {
return checkEntityNotExists(self.name, structure, errorLog, operationIndex,
getEvolutionAppTransformationId());
query APP::ops::AddEmbeddedClass::isValid(structure : APP::Structure, inout errorLog : ErrorLog, operationIndex : Integer) : Boolean {
return checkEntityNotExists(self.name, structure, errorLog, operationIndex, getEvolutionAppTransformationId());
}

helper APP::ops::AddEmbeddedClass::apply(inout structure : APP::Structure) {
structure.entities += _embeddedClass(self.name, _embeddedProperty("id",
structure.findDefaultIdType(), false));
structure.entities += _embeddedClass(self.name, _embeddedProperty("id", structure.findDefaultIdType(), false));
return;
}

query APP::ops::AddStandardClass::isValid(structure : APP::Structure, inout errorLog : ErrorLog,
operationIndex : Integer) : Boolean {
query APP::ops::AddStandardClass::isValid(structure : APP::Structure, inout errorLog : ErrorLog, operationIndex : Integer) : Boolean {
var notExistEntity : Boolean := checkEntityNotExists(self.name, structure, errorLog,
operationIndex, getEvolutionAppTransformationId());
var primitiveExists : Boolean := checkPrimitiveClassExists(getAppDefaultIdTypeName(), structure,
Expand All @@ -84,8 +78,7 @@ query APP::ops::AddStandardClass::isValid(structure : APP::Structure, inout erro
}

helper APP::ops::AddStandardClass::apply(inout structure : APP::Structure) {
structure.entities += _class(self.name, _idProperty(getIdName(self.name),
structure.findDefaultIdType()), self.isAbstract, self.inheritanceType);
structure.entities += _class(self.name, _idProperty(getIdName(self.name), structure.findDefaultIdType()), self.isAbstract, self.inheritanceType);
return;
}

Expand Down Expand Up @@ -367,60 +360,29 @@ helper APP::ops::ZipperHierarchy::decompose(inout structure : APP::Structure

/**
* EXTRACT CLASS
* Create new class with selecter properties from source class.
* Create new class from source class.
* Extracted Class is not part of hierarchy - Source class and Extracted Class are
* connected by pointer.
* In source class we create new property which is poiner to extractClass.
* In source class we create new property which is poiner to extractClass with kardinality 1:1.
* @restriction : Class with @sourceClassName must exists in model
* @restriction : Class with @extractClassName cannot exist in model
* @restriction : Properties must exists in @sourceClass
*/
query APP::ops::ExtractClass::isValid(structure : APP::Structure, inout errorLog : ErrorLog,
operationIndex : Integer) : Boolean {
var existSourceClass : Boolean := checkStandardClassNotExists(self.sourceClassName, structure,
errorLog, operationIndex, getEvolutionAppTransformationId());
var existExtractClass : Boolean := checkStandardClassExists(self.extractClassName, structure,
errorLog, operationIndex, getEvolutionAppTransformationId());
var existProperties : Boolean := checkArePropertiesInGeneralClass(self.sourceClassName,
self.extractPropertiesNames, structure, errorLog, operationIndex,
getEvolutionAppTransformationId());
return existSourceClass and existExtractClass and existProperties;
query APP::ops::ExtractClass::isValid(structure : APP::Structure, inout errorLog : ErrorLog, operationIndex : Integer) : Boolean {
var existSourceClass : Boolean := checkStandardClassExists(self.sourceClassName, structure, errorLog, operationIndex, getEvolutionAppTransformationId());
var existExtractClass : Boolean := checkStandardClassNotExists(self.extractClassName, structure, errorLog, operationIndex, getEvolutionAppTransformationId());
return existSourceClass and existExtractClass;
}

helper APP::ops::ExtractClass::dekompose(inout structure : APP::Structure
) : OrderedSet(app::ops::AtomicOperation){
helper APP::ops::ExtractClass::apply(inout structure : APP::Structure){
// find Source class
var sourceClass : StandardClass := structure.findStandardClass(self.sourceClassName);
var operations : OrderedSet(app::ops::AtomicOperation) = OrderedSet{};
// Create new class - Extracted Class
operations += _addStandardClass(self.sourceClassName, false, InheritanceType::joined);

// Create attributes in Extracted Class
self.extractPropertiesNames->forEach(p){
var prop : Property := structure.findProperty(self.sourceClassName, p);
//TODO - Add this test do query
if(prop.oclIsKindOf(APP::AssociationProperty)) then {
var pr : AssociationProperty := prop.oclAsType(APP::AssociationProperty);
operations += _addProperty(self.extractClassName, pr.name, pr.type.name, pr.lowerBound,
pr.upperBound);
}endif;
if(prop.oclIsKindOf(APP::PrimitiveProperty)) then {
var pr : PrimitiveProperty := prop.oclAsType(APP::PrimitiveProperty);
operations += _addProperty(self.extractClassName, pr.name, pr.type.name, pr.lowerBound,
pr.upperBound);
}endif;
if(prop.oclIsKindOf(APP::NestedProperty)) then {
var pr : NestedProperty := prop.oclAsType(APP::NestedProperty);
operations += _addProperty(self.extractClassName, pr.name, pr.type.name, pr.lowerBound,
pr.upperBound);
}endif;
if(prop.oclIsKindOf(APP::EmbeddedProperty)) then {
operations += _addProperty(self.extractClassName, prop.name,
prop.oclAsType(APP::EmbeddedProperty).type.name );
}endif;

// TODO ostatni operace
};
return operations;
// create new "Extracted" class with name self.extractClassName, isAbstract = false, inheritance = joined
var extractedClass : StandardClass = _class(self.extractClassName, _idProperty(getIdName(self.extractClassName), structure.findDefaultIdType()));
structure.entities += extractedClass;
// create new pointer to Source class with name self.extractClassName, type = extractedClass, lowerBound = 1, upperBound = 1
//TODO - new name of property must start with small character but self.extractClassName has big
sourceClass.properties += _associationProperty(self.extractClassName, extractedClass);
return;
}

/* ++++++++++ SET OPERATIONS FOR PROPERTIES ++++++++++++++++++++ */
Expand Down Expand Up @@ -580,23 +542,19 @@ helper checkPrimitiveClassExists(primitiveClassName : String, structure : APP::S
return exist;
}

helper checkStandardClassExists(standardClassName : String, structure : APP::Structure,
inout errorLog : ErrorLog, operationIndex : Integer, transformationId : String) : Boolean{
helper checkStandardClassExists(standardClassName : String, structure : APP::Structure, inout errorLog : ErrorLog, operationIndex : Integer, transformationId : String) : Boolean{
var exist : Boolean := structure.containsGeneralClass(standardClassName);
if(not exist)then{
var errorMessage : String := "Structure doesn't contains standardClass called " +
standardClassName;
var errorMessage : String := "Structure doesn't contains standardClass called " + standardClassName;
errorLog.errors += _evolutionError(operationIndex, errorMessage, transformationId);
}endif;
return exist;
}

helper checkStandardClassNotExists(standardClassName : String, structure : APP::Structure,
inout errorLog : ErrorLog, operationIndex : Integer, transformationId : String) : Boolean{
helper checkStandardClassNotExists(standardClassName : String, structure : APP::Structure, inout errorLog : ErrorLog, operationIndex : Integer, transformationId : String) : Boolean{
var exist : Boolean := structure.containsGeneralClass(standardClassName);
if(exist)then{
var errorMessage : String := "Structure contains standardClass called " +
standardClassName;
var errorMessage : String := "Structure contains standardClass called " + standardClassName;
errorLog.errors += _evolutionError(operationIndex, errorMessage, transformationId);
}endif;
return exist;
Expand Down
4 changes: 2 additions & 2 deletions migdb.qvto/transforms/tests/code_generation/secondAPP.qvto
Expand Up @@ -11,8 +11,8 @@ main() {

var root : APP::Operations = outModel.rootObjects()![APP::Operations];

root.operations += _extractClass("Party", OrderedSet{"street", "city","zip", "country"},
"Address");
root.operations += _extractClass("Party", "Address");
//TODO move of property City, Street, Zip and Country
root.operations += _renameProperty("Party", "address", "residentialAddress");
root.operations += _addProperty("Party", "contactAddress", "Country");

Expand Down

This file was deleted.

12 changes: 0 additions & 12 deletions migdb.qvto/transforms/tests/tests_rdb_atomic/addColumn.qvto

This file was deleted.

13 changes: 0 additions & 13 deletions migdb.qvto/transforms/tests/tests_rdb_atomic/addColumn_ops.qvto

This file was deleted.

This file was deleted.

26 changes: 0 additions & 26 deletions migdb.qvto/transforms/tests/tests_rdb_atomic/addForeignKey.qvto

This file was deleted.

0 comments on commit ed33f79

Please sign in to comment.