With this process you can develop the ecore model and the corresponding eef models and keep them in sync by regenerating the dependent models. The process is part of the template project .
The process uses the properties initializer to create an basic model. A eef-genmodel and a component file is created. In the component file are two models stored, the view and the component model. As we can only transform on in a transformation, we split the file, to the view model and the component model. In the transformation process the whole magic happens. After all the magic we need to store back the two models in one file. When we transform the genmodel, we link the elements from the merged file. Then we have a customized eef genmodel and we can use the properties generator to produce the code. The basic process
report.
There is a wizard to initialize a start configuration and a custom atl file.
The process is templated by some properties.
You can set the values for the properties in the start configuration (see there
The custom ATL file defines some helper for the transformation. All dynamic aspects of the transformation are defined here. This is the file i used to generate the eef property page of atlflow.
-- @atlcompiler atl2006
-- @nsURI ECORE=http://www.eclipse.org/emf/2002/Ecore
-- @nsURI EEF_COMPONENT=http://www.eclipse.org/emf/eef/components/1.0.0
library custom_eef;
helper def : author : String = 'Urs Zeidler';
helper def : license : String = '/*\n * (c) Urs Zeidler 2011\n */\n';
helper def : genDirectory : String = '/de.urszeidler.eclipse.callchain.eef/src-gen';
helper def : descriptorsContributorID : String = 'de.urszeidler.eclipse.callchain.diagram';
helper def : descriptorsGenericPropertiesViews : Boolean = true;
helper def : gmfPropertiesViews : Boolean = false;
helper def : generateJunitTestCases : Boolean = false;
helper def : useJMergeForUserCode : Boolean = true;
-- a map containing all classes and a list of features
helper def : orderedAttributes : Map(String,Sequence(String)) = Map{
-- ('Attribute',Sequence{'Attribute.dataType','Attribute.columnType','Attribute.property'})
('Calls',
Sequence{
'Calls.name'
,'Calls.defaultStartPoint'
, 'Calls.startPoints'
, 'Calls.properties'
, 'Calls.defaultLib'
, 'Calls.defaultSuperImposed'
, 'Calls.logDefault'
}),
('Call',
Sequence{
'Call.name'
, 'Call.res'
, 'Call.predicate'
, 'Call.next'
, 'Call.in'
, 'Call.out'
, 'Call.artifact'
, 'Call.libarys'
, 'Call.allowInterModelReferences'
, 'Call.continueAfterErrors'
, 'Call.showSummary'
, 'Call.printExecutionTime'
, 'Call.disableAttributeHelperCache'
, 'Call.profile'
,'Call.refreshWorkspace'
}),
('Generic_Generator',
Sequence{
'Generic_Generator.name'
,'Generic_Generator.generatorType'
,'Generic_Generator.predicate'
,'Generic_Generator.refreshWorkspace'
,'Generic_Generator.id'
}),
('StopCall',
Sequence{
'StopCall.name',
'StopCall.refreshWorkspace'
}),
('PredicateSwitch',
Sequence{
'PredicateSwitch.name'
, 'PredicateSwitch.predicate'
}),
('PropertyValueSwitch',
Sequence{
'PropertyValueSwitch.name'
, 'PropertyValueSwitch.property'
}),
('ExternalCallable',
Sequence{
'ExternalCallable.name'
, 'ExternalCallable.delegatedCallable'
, 'ExternalCallable.predicate'
, 'ExternalCallable.mappers'
,'ExternalCallable.refreshWorkspace'
}),
('Artifact',
Sequence{
'Artifact.name'
, 'Artifact.uri'
, 'Artifact.derived'
}),
('Model',
Sequence{
'Model.name'
, 'Model.uri'
, 'Model.mm'
, 'Model.derived'
, 'Model.isTemporary'
}),
('MM',
Sequence{
'MM.name'
, 'MM.uri'
, 'MM.handler'
}),
('MMAlias',
Sequence{
'MMAlias.aliasName'
, 'MMAlias.decoratedmodel'
}),
('ModelAlias',
Sequence{
'ModelAlias.aliasName'
, 'ModelAlias.decoratedmodel'
}),
('AtlRes',
Sequence{
'AtlRes.name',
'AtlRes.uri',
'AtlRes.superimpose'
}),
('AtlLibary',
Sequence{
'AtlLibary.name',
'AtlLibary.uri'
}),
('PropertyHasValue',
Sequence{
'PropertyHasValue.property',
'PropertyHasValue.value'
}),
('NotPredicate',
Sequence{
'NotPredicate.predicate'
}),
('BooleanPredicate',
Sequence{'BooleanPredicate.value'
}),
('Property',
Sequence{
'Property.name',
'Property.defaultValue',
'Property.value'
}),
('PropertyMapper',
Sequence{
'PropertyMapper.input',
'PropertyMapper.output'
}),
('Comment',
Sequence{'Comment.doc'
})
}
;
-- classes not tranformt
helper def : excludeClasses : Sequence(String) =
Sequence{
-- 'Application'
-- 'Comment'
}
;
-- the qualified feature name (QName) CLASS.FEATURE not transformt
helper def : excludedFeatures : Sequence(String) =
Sequence{
-- 'Attribute.column'
'Transition.callable',
'Transition.namedSwitch'
}
;
-- the qualified feature name CLASS.FEATURE and the widget to use for
helper def : featuresToWidget : Map(String,String) =
Map{
('NotPredicate.predicate','SingleCompositionEditor'),
('PredicateSwitch.predicate','SingleCompositionEditor'),
('Artifact.uri','SelectionDialog'),
('Model.uri','SelectionDialog'),
('MM.uri','SelectionDialog'),
('AtlLibary.uri','SelectionDialog'),
('AtlRes.uri','SelectionDialog'),
('Comment.doc','Textarea'),
('Generic_Generator.predicate','SingleCompositionEditor'),
('Call.predicate','SingleCompositionEditor'),
('Calls.properties','SingleCompositionEditor'),
('ExternalCallable.predicate','SingleCompositionEditor')
}
;
-- 'AdvancedEObjectFlatComboViewer' good for the use of singel containment refs
-- 'SingleCompositionViewer' strage viewer with checkbox
-- 'SingleCompositionEditor' also good for use with single contaiments
-- 'EObjectFlatComboViewer' good use for not containment single refs
-- 'AdvancedTableComposition'
You can exclude classes from the generation by list them in the excludeClasses sequence.
The important feature is the orderedAttributes, it’s a map containing the names of the elements and a sequence of the features for which widgets will be created. If an element is listed in this map, only the features in the sequence will be created. If the element is not in the input model, it is necessary to define the widget for that feature. The component transformation will print all default configuration in the ATL console.
You can define which widget will be used for the view, it’s a simple map containing the qualified feature name and the name of the widget. The name of the widget can looked up in the corresponding model files.