blob: 1abfb453b51c7cfd0d3da27387cb2db6ce62bc7b [file] [log] [blame]
/**
* Copyright (c) 2009, 2011, 2012 Borland Software Corporation & others
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Artem Tikhomirov (Borland) - initial API and implementation
* Guillaume Hillairet (Montages A.G.)
*/
library Audits;
import Utils;
import Mappings;
import gmf.GenModelAccess;
modeltype GMFMAP uses mappings('http://www.eclipse.org/gmf/2006/mappings');
modeltype GMFTOOL uses tooldef('http://www.eclipse.org/gmf/2005/ToolDefinition');
modeltype GMFGEN uses gmfgen('http://www.eclipse.org/gmf/2009/GenModel');
modeltype GMFGRAPH uses gmfgraph('http://www.eclipse.org/gmf/2006/GraphicalDefinition');
modeltype ECORE uses ecore('http://www.eclipse.org/emf/2002/Ecore');
modeltype GENMODEL uses genmodel('http://www.eclipse.org/emf/2002/GenModel');
--
-- Audits
--
mapping GMFMAP::AuditContainer::audits() : GMFGEN::GenAuditRoot {
result.categories += self.allContainers().map category();
result.rules += self.allContainers().audits.map rule();
var allRulesWithContext := result.rules->select(not target.oclIsUndefined());
var rulesWithDiagramElementTarget := allRulesWithContext->select(target.oclIsTypeOf(GMFGEN::GenDiagramElementTarget));
rulesWithDiagramElementTarget.target[GMFGEN::GenDiagramElementTarget]->forEach(t) {
-- Basically, all rules with targets != null
-- get a context (emf.validation), which is a scope or set of elements audit is evaluated against.
-- For certain cases, e.g. diagram elements as audit targets, special logic to select these
-- elements should get generated - to filter diagram views by visualID, and hence
-- there's another implementation of IClientSelector and dedicated context.
var ctx : GMFGEN::GenAuditContext;
-- use of exists seems to be sufficient, as all ruleTargets for a given context should get same elements
-- by the nature of construction. However, more honest way would be to use forAll, accompanied with not isEmpty():
-- not cc.ruleTargets[GMFGEN::GenDiagramElementTarget]->isEmpty() and cc.ruleTargets[...]->forAll(element = t.element)
ctx := result.clientContexts->selectOne(cc | cc.ruleTargets[GMFGEN::GenDiagramElementTarget]->exists(element = t.element));
-- there might be already a context to pick same elements this target has
if ctx.oclIsUndefined() then {
ctx := object GMFGEN::GenAuditContext {
id := t.element.visualID.repr()->asList()->joinfields('_','Ctx_','')
};
result.clientContexts += ctx;
} endif;
t.contextSelector := ctx;
};
var defaultAuditContext := object GMFGEN::GenAuditContext {};
result.clientContexts += defaultAuditContext;
(allRulesWithContext - rulesWithDiagramElementTarget).target->forEach(t) { t.contextSelector := defaultAuditContext };
}
mapping GMFMAP::AuditContainer::category() : GMFGEN::GenAuditContainer {
id := self.id;
name := self.name;
description := self.description;
path += self.parentContainer.resolveone(GMFGEN::GenAuditContainer).path;
-- alternative, not sure which one is better:
-- path += self.parentContainer.map category().path;
path += result;
}
mapping GMFMAP::AuditRule::rule() : GMFGEN::GenAuditRule {
id := self.id;
name := self.name;
message := self.message;
description := self.description;
useInLiveMode := self.useInLiveMode;
target := self.target.map auditTarget();
rule := self.rule.map createConstraint();
severity := self.severity.severity();
category := self.container.map category();
}
mapping GMFMAP::Auditable::auditTarget() : GMFGEN::GenAuditable
disjuncts
GMFMAP::DomainElementTarget::ruleTarget,
GMFMAP::NotationElementTarget::ruleTarget,
GMFMAP::DiagramElementTarget::ruleTarget,
GMFMAP::AuditedMetricTarget::ruleTarget,
GMFMAP::DomainAttributeTarget::ruleTarget
{} --assert (false) with log ('Unknown rule target', self);
mapping GMFMAP::DomainElementTarget::ruleTarget() : GMFGEN::GenDomainElementTarget {
element := self.element.findGenClass();
}
mapping GMFMAP::NotationElementTarget::ruleTarget() : GMFGEN::GenNotationElementTarget {
element := self.element.findGenClass(); -- XXX double-check if domain's genmodel should be consulted here, not notation's
}
mapping GMFMAP::DiagramElementTarget::ruleTarget() : GMFGEN::GenDiagramElementTarget {
-- alternatives:
if self.element.oclIsKindOf(LinkMapping) then {
element += self.element.oclAsType(LinkMapping).map structure();
} else if self.element.oclIsKindOf(NodeMapping) then {
var el := self.element.container();
if el.oclIsKindOf(TopNodeReference) then
element += el.oclAsType(TopNodeReference).map structure()
else
element += el.oclAsType(ChildReference).map structure(self.element.oclAsType(NodeMapping))
endif
} endif
endif;
-- element += self.element.resolveIn(GMFMAP::NodeMapping::structure, GMFGEN::GenCommonBase);
-- element += self.element.resolveIn(GMFMAP::LinkMapping::structure, GMFGEN::GenCommonBase);
-- element += self.element.resolveIn(GMFMAP::TopNodeReference::structure, GMFGEN::GenCommonBase);
-- element += self.element.resolve(GMFGEN::GenCommonBase);
}
mapping GMFMAP::AuditedMetricTarget::ruleTarget() : GMFGEN::GenAuditedMetricTarget {
result.metric := self.metric.map rule();
var resultClassifier := loadEcoreGenModel().genPackages->first().genClassifiers[GENMODEL::GenDataType]->selectOne(ecoreDataType.name='EDoubleObject');
assert (not resultClassifier.oclIsUndefined()) with log ('Troubles loading ecore.genmodel and accessing EDoubleObject');
result.metricValueContext := resultClassifier;
}
mapping GMFMAP::DomainAttributeTarget::ruleTarget() : GMFGEN::GenDomainAttributeTarget {
attribute := self.attribute.findGenFeature();
nullAsError := self.nullAsError;
}
--
-- Metrics
--
mapping GMFMAP::MetricContainer::metrics() : GMFGEN::GenMetricContainer {
metrics += self.metrics.map rule();
}
mapping GMFMAP::MetricRule::rule() : GMFGEN::GenMetricRule {
key := self.key;
name := self.name;
description := self.description;
lowLimit := self.lowLimit;
highLimit := self.highLimit;
rule := self.rule.map createValueExpression();
target := self.target.map metricTarget();
}
mapping GMFMAP::Measurable::metricTarget() : GMFGEN::GenMeasurable
disjuncts
GMFMAP::DomainElementTarget::ruleTarget,
GMFMAP::NotationElementTarget::ruleTarget,
GMFMAP::DiagramElementTarget::ruleTarget
{} --assert (false) with log ('Unknown rule target', self);
--
-- Queries
--
query GMFMAP::AuditContainer::allContainers() : Sequence(GMFMAP::AuditContainer) =
self.childContainers.allContainers()->flatten()->prepend(self);
query GMFMAP::Severity::severity() : GMFGEN::GenSeverity =
switch {
case (self = GMFMAP::Severity::INFO) return GMFGEN::GenSeverity::INFO;
case (self = GMFMAP::Severity::WARNING) return GMFGEN::GenSeverity::WARNING;
case (self = GMFMAP::Severity::ERROR) return GMFGEN::GenSeverity::ERROR;
else return null;
};