private void TranslateInvariantsToXPath(ClassifierConstraintBlock constraintBlock, XElement ruleElement, PSMBridge psmBridge, TranslationSettings translationSettings) { foreach (InvariantWithMessage invariant in constraintBlock.Invariants) { string xpath = TranslateInvariantToXPath(constraintBlock, psmBridge, invariant.Constraint, translationSettings); try { ruleElement.Add(new XComment(invariant.ToString())); XElement assertElement = ruleElement.SchematronAssert(xpath); #region process user error message and subexpressions in the message if (invariant.MessageIsString) { if (invariant.MessageSubExpressions.Count > 0) { foreach (SubExpressionInfo messagePart in invariant.MessageSubExpressions) { if (messagePart.SubExpression == null) { XText messageTextElement = new XText(messagePart.PartAsString); assertElement.Add(messageTextElement); } else { if (messagePart.Parsed) { string subExpressionTranslation = TranslateInvariantToXPath(constraintBlock, psmBridge, messagePart.SubExpression, translationSettings, true); assertElement.SchematronValueOf(subExpressionTranslation); } else { Log.AddWarning(string.Format("Failed to integrate subexpression `{0}` into the schema. ", messagePart.PartAsString), messagePart.SubExpression); } } } } else { XText messageTextElement = new XText(((StringLiteralExp)invariant.Message).Value); assertElement.Add(messageTextElement); } } #endregion } catch { ruleElement.Add(new XComment("Translation of the constraint failed. ")); } } }
public OclExpression TranslateConstraint(ClassifierConstraintBlock classifierConstraintBlock, OclExpression pimInvariant, Dictionary <VariableDeclaration, List <PSMClass> > initialVariableMappings, Dictionary <PIMPath, List <PSMPath> > initialPathMappings, Dictionary <VariableDeclaration, VariableDeclaration> variableTranslations, out Classifier psmContextSuggestion) { #region fill prepared translations foreach (KeyValuePair <VariableDeclaration, List <PSMClass> > kvp in initialVariableMappings) { VariableClassMappings.CreateSubCollectionIfNeeded(kvp.Key); VariableClassMappings[kvp.Key].AddRange(kvp.Value); } foreach (KeyValuePair <PIMPath, List <PSMPath> > kvp in initialPathMappings) { PathMappings.CreateSubCollectionIfNeeded(kvp.Key); PathMappings[kvp.Key].AddRange(kvp.Value); } foreach (KeyValuePair <VariableDeclaration, VariableDeclaration> kvp in variableTranslations) { VariableTranslations[kvp.Key] = kvp.Value; } #endregion psmBridge = new PSMBridge(TargetPSMSchema); #region prepare self variable PSMClass psmClass = VariableClassMappings[classifierConstraintBlock.Self].First(); Classifier variableType = psmBridge.Find(psmClass); VariableDeclaration vd = new VariableDeclaration(classifierConstraintBlock.Self.Name, variableType, null); this.SelfVariableDeclaration = vd; #endregion OclExpression translateConstraint = pimInvariant.Accept(this); psmContextSuggestion = psmBridge.Find(VariableClassMappings[classifierConstraintBlock.Self].First()); if (isSuitable) { return(translateConstraint); } else { return(null); } }
public bool CheckConstraintSuitability(ClassifierConstraintBlock classifierConstraintBlock, OclExpression oclExpression) { Clear(); psmBridge = new PSMBridge(TargetPSMSchema); PIMClass contextClass = (PIMClass)classifierConstraintBlock.Context.Tag; VariableClassMappings.CreateSubCollectionIfNeeded(classifierConstraintBlock.Self); VariableClassMappings[classifierConstraintBlock.Self].AddRange(GetInterpretations(contextClass)); oclExpression.Accept(this); IEnumerable <VariableDeclaration> f = from m in VariableClassMappings where m.Value.Count == 0 select m.Key; if (f.Count() > 0) { isSuitable = false; } return(isSuitable); }
public IList <ClassifierConstraintBlock> FindSuitableConstraints(PIMSchema pimSchema, PSMSchema psmSchema) { List <ClassifierConstraintBlock> result = new List <ClassifierConstraintBlock>(); foreach (OCLScript oclScript in pimSchema.OCLScripts) { OclCompilerResult compilerResult = oclScript.CompileToAst(); if (!compilerResult.Errors.HasError) { ConstraintSuitabilityChecker constraintSuitabilityChecker = new ConstraintSuitabilityChecker { TargetPSMSchema = psmSchema, Bridge = compilerResult.Bridge }; ConstraintConvertor constraintConvertor = new ConstraintConvertor { TargetPSMSchema = psmSchema, Bridge = compilerResult.Bridge }; foreach (ClassifierConstraintBlock classifierConstraint in compilerResult.Constraints.ClassifierConstraintBlocks) { /* constraints from one PIM context can be distributed amont several * PSM contexts (different PSM classes with identical interpretation) */ Dictionary <Classifier, ClassifierConstraintBlock> translatedInvariants = new Dictionary <Classifier, ClassifierConstraintBlock>(); foreach (InvariantWithMessage pimInvariant in classifierConstraint.Invariants) { constraintSuitabilityChecker.Clear(); bool suitable = constraintSuitabilityChecker.CheckConstraintSuitability( classifierConstraint, pimInvariant.Constraint); if (suitable) { Classifier psmContextSuggestion = null; constraintConvertor.Clear(); try { OclExpression psmInvariant = constraintConvertor.TranslateConstraint(classifierConstraint, pimInvariant.Constraint, constraintSuitabilityChecker.VariableClassMappings, constraintSuitabilityChecker.PathMappings, constraintSuitabilityChecker.VariableTranslations, out psmContextSuggestion); if (!translatedInvariants.ContainsKey(psmContextSuggestion)) { translatedInvariants[psmContextSuggestion] = new ClassifierConstraintBlock(psmContextSuggestion, new List <InvariantWithMessage>(), constraintConvertor.SelfVariableDeclaration); } translatedInvariants[psmContextSuggestion].Invariants.Add(new InvariantWithMessage(psmInvariant)); } catch { } } } foreach (KeyValuePair <Classifier, ClassifierConstraintBlock> kvp in translatedInvariants) { result.Add(kvp.Value); } } } } return(result); }
private string TranslateInvariantToXPath(ClassifierConstraintBlock constraintBlock, IBridgeToOCL bridge, OclExpression invariant, TranslationSettings translationSettings, bool forceTranslation = false) { invariant.IsInvariant = true; invariant.ConstraintContext = constraintBlock; PSMOCLtoXPathConverter xpathConverter; if (translationSettings.Functional) { xpathConverter = new PSMOCLtoXPathConverterFunctional(); } else { xpathConverter = new PSMOCLtoXPathConverterDynamic(); } xpathConverter.Bridge = (PSMBridge)bridge; xpathConverter.OclContext = constraintBlock; xpathConverter.Log = Log; xpathConverter.Settings = translationSettings; if (forceTranslation || !translationSettings.Retranslation) { try { string invariantStr = xpathConverter.TranslateExpression(invariant); translationSettings.SubexpressionTranslations.XPathContextVariableReplacementMode = xpathConverter.ContextVariableReplacementMode; translationSettings.SubexpressionTranslations.Merge(xpathConverter.SubexpressionTranslations); return(invariantStr); } catch (ExpressionNotSupportedInXPath e) { Log.AddError(e.Message, e.Expression); } catch { Log.AddError("Unable to translate invariant. ", invariant); } } else { try { // this must stay here because of the string comparison - translation renames some variables xpathConverter.TranslateExpression(invariant); foreach (OclExpression translatedExp in translationSettings.SubexpressionTranslations.Translations.Keys) { if (translatedExp.ToString() == invariant.ToString()) { translationSettings.SubexpressionTranslations.SelfVariableDeclaration = translatedExp.ConstraintContext.Self; return(translationSettings.SubexpressionTranslations.GetSubexpressionTranslation(translatedExp).GetString(true)); } } } catch (ExpressionNotSupportedInXPath e) { Log.AddError(e.Message, e.Expression); } catch { Log.AddError("Unable to translate invariant. ", invariant); } } return("### ERROR"); }