2005-08-17 15:45:10 +00:00
|
|
|
|
(*****************************************************************************
|
2005-08-18 05:55:15 +00:00
|
|
|
|
* su4sml - a SecureUML repository for SML
|
2005-08-17 15:45:10 +00:00
|
|
|
|
*
|
|
|
|
|
* xmi_parser.sml - an xmi-parser for the import interface for su4sml
|
|
|
|
|
* Copyright (C) 2005 Achim D. Brucker <brucker@inf.ethz.ch>
|
|
|
|
|
* J<EFBFBD>rgen Doser <doserj@inf.ethz.ch>
|
|
|
|
|
*
|
|
|
|
|
* This file is part of su4sml.
|
|
|
|
|
*
|
|
|
|
|
* su4sml is free software; you can redistribute it and/or modify it under
|
|
|
|
|
* the terms of the GNU General Public License as published by the Free
|
|
|
|
|
* Software Foundation; either version 2 of the License, or (at your option)
|
|
|
|
|
* any later version.
|
|
|
|
|
*
|
|
|
|
|
* su4sml is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
|
|
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
|
|
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
|
|
|
* details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
|
******************************************************************************)
|
|
|
|
|
|
2005-08-19 16:04:10 +00:00
|
|
|
|
structure ParseXMI :
|
|
|
|
|
sig
|
2005-09-07 17:32:04 +00:00
|
|
|
|
val readFile: string -> XMI.XmiContent
|
2005-08-23 08:03:09 +00:00
|
|
|
|
(* generic exception if something is wrong *)
|
|
|
|
|
exception IllFormed of string
|
2005-08-19 16:04:10 +00:00
|
|
|
|
end =
|
2005-08-17 15:45:10 +00:00
|
|
|
|
struct
|
2005-08-18 16:18:28 +00:00
|
|
|
|
|
2005-08-23 08:03:09 +00:00
|
|
|
|
exception NotYetImplemented
|
2005-08-18 16:18:28 +00:00
|
|
|
|
(* generic exception if something is wrong *)
|
2005-08-23 08:03:09 +00:00
|
|
|
|
exception IllFormed of string
|
2005-08-18 16:18:28 +00:00
|
|
|
|
|
2005-08-17 15:45:10 +00:00
|
|
|
|
|
2005-08-18 16:18:28 +00:00
|
|
|
|
|
2005-08-20 18:42:39 +00:00
|
|
|
|
fun getStringAtt string atts = valOf (XmlTree.attvalue_of string atts)
|
2005-08-18 16:18:28 +00:00
|
|
|
|
handle Option => raise IllFormed ("in getAttValue: did not find attribute "^string)
|
|
|
|
|
|
|
|
|
|
fun getBoolAtt string atts =
|
2005-08-19 16:04:10 +00:00
|
|
|
|
let val att = getStringAtt string atts
|
2005-08-18 16:18:28 +00:00
|
|
|
|
in
|
|
|
|
|
(valOf o Bool.fromString) att
|
|
|
|
|
handle Option => raise IllFormed ("in getBoolAtt: found attribute "^string^
|
|
|
|
|
" with unexpected value "^att)
|
|
|
|
|
end
|
2005-08-17 15:45:10 +00:00
|
|
|
|
|
|
|
|
|
|
2005-08-19 11:39:04 +00:00
|
|
|
|
fun getIntAtt string atts =
|
2005-08-19 16:04:10 +00:00
|
|
|
|
let val att = getStringAtt string atts
|
2005-08-18 16:18:28 +00:00
|
|
|
|
in
|
|
|
|
|
(valOf o Int.fromString) att
|
2005-08-19 11:39:04 +00:00
|
|
|
|
handle Option => raise IllFormed ("in getIntAtt: found attribute "^string^
|
2005-08-18 16:18:28 +00:00
|
|
|
|
" with unexpected value "^att)
|
|
|
|
|
end
|
|
|
|
|
|
2005-09-12 20:13:23 +00:00
|
|
|
|
val getLang = getStringAtt "language"
|
|
|
|
|
val getBody = getStringAtt "body"
|
2005-09-08 17:00:46 +00:00
|
|
|
|
val getXmiId = getStringAtt "xmi.id"
|
|
|
|
|
val getName = getStringAtt "name"
|
|
|
|
|
val getXmiIdref = getStringAtt "xmi.idref"
|
2005-08-17 15:45:10 +00:00
|
|
|
|
|
2005-08-18 16:18:28 +00:00
|
|
|
|
fun getVisibility atts =
|
2005-08-20 18:42:39 +00:00
|
|
|
|
let val att = XmlTree.attvalue_of "visibility" atts
|
2005-08-18 16:18:28 +00:00
|
|
|
|
in
|
2005-09-07 17:32:04 +00:00
|
|
|
|
case att of SOME "public" => XMI.public
|
|
|
|
|
| SOME "private" => XMI.private
|
|
|
|
|
| SOME "protected" => XMI.protected
|
|
|
|
|
| SOME "package" => XMI.package
|
|
|
|
|
| NONE => XMI.public
|
2005-08-18 16:18:28 +00:00
|
|
|
|
| SOME string => raise IllFormed ("in getVisibility: found unexpected attribute value "^string)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
fun getOrdering atts =
|
2005-08-19 16:04:10 +00:00
|
|
|
|
let val att = getStringAtt "ordering" atts
|
2005-08-18 16:18:28 +00:00
|
|
|
|
in
|
2005-09-07 17:32:04 +00:00
|
|
|
|
case att of "unordered" => XMI.Unordered
|
|
|
|
|
| "ordered" => XMI.Ordered
|
2005-08-18 16:18:28 +00:00
|
|
|
|
| _ => raise IllFormed ("in getOrdering: found unexpected attribute value "^att)
|
|
|
|
|
end
|
|
|
|
|
|
2005-08-23 15:03:15 +00:00
|
|
|
|
fun getOrderingMaybe atts =
|
|
|
|
|
let val att = XmlTree.attvalue_of "ordering" atts
|
|
|
|
|
in
|
2005-09-07 17:32:04 +00:00
|
|
|
|
case att of SOME "unordered" => XMI.Unordered
|
|
|
|
|
| SOME "ordered" => XMI.Ordered
|
|
|
|
|
| _ => XMI.Unordered
|
2005-08-23 15:03:15 +00:00
|
|
|
|
end
|
|
|
|
|
|
2005-08-18 16:18:28 +00:00
|
|
|
|
fun getAggregation atts =
|
2005-08-19 16:04:10 +00:00
|
|
|
|
let val att = getStringAtt "aggregation" atts in
|
2005-09-07 17:32:04 +00:00
|
|
|
|
case att of "none" => XMI.NoAggregation
|
|
|
|
|
| "aggregate" => XMI.Aggregate
|
|
|
|
|
| "composite" => XMI.Composite
|
2005-08-18 16:18:28 +00:00
|
|
|
|
| _ => raise IllFormed ("in getAggregation: found unexpected attribute value "^att)
|
|
|
|
|
end
|
|
|
|
|
|
2005-09-13 15:56:31 +00:00
|
|
|
|
fun getAggregationMaybe atts =
|
|
|
|
|
let val att = XmlTree.attvalue_of "aggregation" atts in
|
|
|
|
|
case att of SOME "none" => XMI.NoAggregation
|
|
|
|
|
| SOME "aggregate" => XMI.Aggregate
|
|
|
|
|
| SOME "composite" => XMI.Composite
|
|
|
|
|
| NONE => XMI.NoAggregation
|
|
|
|
|
| SOME x => raise IllFormed ("in getAggregation: found unexpected attribute value "^x)
|
|
|
|
|
end
|
|
|
|
|
|
2005-08-18 16:18:28 +00:00
|
|
|
|
fun getChangeability atts =
|
2005-08-19 16:04:10 +00:00
|
|
|
|
let val att = getStringAtt "changeability" atts in
|
2005-09-07 17:32:04 +00:00
|
|
|
|
case att of "changeable" => XMI.Changeable
|
|
|
|
|
| "frozen" => XMI.Frozen
|
|
|
|
|
| "addonly" => XMI.AddOnly
|
2005-08-18 16:18:28 +00:00
|
|
|
|
| _ => raise IllFormed ("in getChangeability: found unexpected attribute value "^att)
|
|
|
|
|
end
|
2005-09-13 15:56:31 +00:00
|
|
|
|
|
|
|
|
|
fun getChangeabilityMaybe atts =
|
|
|
|
|
let val att = XmlTree.attvalue_of "changeability" atts in
|
|
|
|
|
case att of SOME "changeable" => XMI.Changeable
|
|
|
|
|
| SOME "frozen" => XMI.Frozen
|
|
|
|
|
| SOME "addonly" => XMI.AddOnly
|
|
|
|
|
| NONE => XMI.Changeable
|
|
|
|
|
| SOME x => raise IllFormed ("in getChangeability: found unexpected attribute value "^x)
|
|
|
|
|
end
|
2005-08-18 16:18:28 +00:00
|
|
|
|
|
|
|
|
|
fun getKind atts =
|
2005-08-19 16:04:10 +00:00
|
|
|
|
let val att = getStringAtt "kind" atts in
|
2005-09-07 17:32:04 +00:00
|
|
|
|
case att of "in" => XMI.In
|
|
|
|
|
| "out" => XMI.Out
|
|
|
|
|
| "inout" => XMI.Inout
|
|
|
|
|
| "return" => XMI.Return
|
2005-08-18 16:18:28 +00:00
|
|
|
|
| _ => raise IllFormed ("in getKind: found unexpected attribute value "^att)
|
|
|
|
|
end
|
|
|
|
|
|
2005-08-19 13:58:50 +00:00
|
|
|
|
fun getRange atts = (getIntAtt "lower" atts, getIntAtt "upper" atts)
|
2005-08-18 16:18:28 +00:00
|
|
|
|
|
2005-08-23 15:03:15 +00:00
|
|
|
|
fun mkMultiplicity tree = map (getRange o XmlTree.attributes_of)
|
|
|
|
|
(((XmlTree.filter "UML:MultiplicityRange") o
|
|
|
|
|
(XmlTree.skip "UML:Multiplicity.range") o hd o
|
|
|
|
|
(XmlTree.skip "UML:Multiplicity")) tree)
|
2005-08-18 16:18:28 +00:00
|
|
|
|
|
2005-08-20 18:42:39 +00:00
|
|
|
|
fun mkAssociationEnd tree =
|
|
|
|
|
let fun f atts trees =
|
|
|
|
|
{ xmiid = getXmiId atts,
|
2005-09-13 15:56:31 +00:00
|
|
|
|
name = XmlTree.attvalue_of "name" atts,
|
2005-08-20 18:42:39 +00:00
|
|
|
|
isNavigable = getBoolAtt "isNavigable" atts,
|
2005-09-13 15:56:31 +00:00
|
|
|
|
ordering = getOrderingMaybe atts,
|
|
|
|
|
aggregation = getAggregationMaybe atts,
|
|
|
|
|
multiplicity = if XmlTree.exists "UML:AssociationEnd.multiplicity" trees
|
|
|
|
|
then (mkMultiplicity o hd o (XmlTree.follow "UML:AssociationEnd.multiplicity"))
|
|
|
|
|
trees
|
|
|
|
|
else [(0,~1)],
|
|
|
|
|
changeability = getChangeabilityMaybe atts,
|
2005-08-20 18:42:39 +00:00
|
|
|
|
visibility = getVisibility atts,
|
|
|
|
|
participant_id = (getXmiIdref o XmlTree.attributes_of o hd o
|
|
|
|
|
(XmlTree.follow "UML:AssociationEnd.participant")) trees }
|
|
|
|
|
in
|
|
|
|
|
XmlTree.apply_on "UML:AssociationEnd" f tree
|
2005-08-23 09:13:15 +00:00
|
|
|
|
handle XmlTree.IllFormed msg => raise IllFormed ("in mkAssociationEnd: "^msg)
|
2005-08-20 18:42:39 +00:00
|
|
|
|
end
|
2005-08-17 15:45:10 +00:00
|
|
|
|
|
2005-08-23 11:37:41 +00:00
|
|
|
|
fun mkAssociationClass tree =
|
|
|
|
|
let fun f atts trees = { xmiid = getXmiId atts,
|
|
|
|
|
name = XmlTree.attvalue_of "name" atts,
|
|
|
|
|
connection = (map mkAssociationEnd
|
|
|
|
|
(XmlTree.follow "UML:Association.connection"
|
|
|
|
|
trees)) }
|
|
|
|
|
in
|
|
|
|
|
XmlTree.apply_on "UML:AssociationClass" f tree
|
|
|
|
|
handle XmlTree.IllFormed msg => raise IllFormed ("in mkAssociation: "^msg)
|
|
|
|
|
end
|
|
|
|
|
|
2005-08-20 18:42:39 +00:00
|
|
|
|
fun mkAssociation tree =
|
|
|
|
|
let fun f atts trees = { xmiid = getXmiId atts,
|
2005-08-20 18:55:18 +00:00
|
|
|
|
name = XmlTree.attvalue_of "name" atts,
|
2005-08-20 18:42:39 +00:00
|
|
|
|
connection = (map mkAssociationEnd
|
|
|
|
|
(XmlTree.skip "UML:Association.connection"
|
|
|
|
|
(hd trees))) }
|
|
|
|
|
in
|
|
|
|
|
XmlTree.apply_on "UML:Association" f tree
|
2005-08-23 09:13:15 +00:00
|
|
|
|
handle XmlTree.IllFormed msg => raise IllFormed ("in mkAssociation: "^msg)
|
2005-08-20 18:42:39 +00:00
|
|
|
|
end
|
2005-08-22 15:04:08 +00:00
|
|
|
|
|
|
|
|
|
fun mkVariableDec tree =
|
|
|
|
|
let fun f atts trees =
|
|
|
|
|
{ xmiid = getXmiId atts,
|
|
|
|
|
name = getName atts,
|
|
|
|
|
declaration_type = (getXmiIdref o XmlTree.attributes_of o hd o
|
|
|
|
|
(XmlTree.follow "OCL.Expressions.VariableDeclaration.type")) trees
|
|
|
|
|
}
|
|
|
|
|
in XmlTree.apply_on "UML15OCL.Expressions.VariableDeclaration" f tree
|
2005-08-23 09:13:15 +00:00
|
|
|
|
handle XmlTree.IllFormed msg => raise IllFormed ("in mkVariableDec: "^msg)
|
2005-08-22 15:04:08 +00:00
|
|
|
|
end
|
|
|
|
|
|
2005-08-20 18:42:39 +00:00
|
|
|
|
|
2005-08-17 15:45:10 +00:00
|
|
|
|
(* find the xmi.idref attribute of an element pinted to by name *)
|
2005-08-20 18:42:39 +00:00
|
|
|
|
fun findXmiIdRef name trees = (getXmiIdref o XmlTree.attributes_of o hd)
|
|
|
|
|
(XmlTree.follow name trees)
|
2005-08-17 15:45:10 +00:00
|
|
|
|
|
|
|
|
|
(* find the type of an OCl sub-expression *)
|
|
|
|
|
fun findExpressionType trees = findXmiIdRef "OCL.Expressions.OclExpression.type"
|
|
|
|
|
trees
|
2005-08-26 11:50:39 +00:00
|
|
|
|
handle _ => "DummyT"
|
|
|
|
|
(* hack: return a reference to a dummy*)
|
|
|
|
|
(* type if the real type is not found *)
|
2005-08-17 15:45:10 +00:00
|
|
|
|
|
2005-08-26 12:29:56 +00:00
|
|
|
|
(* this is a hack. This will still throw an exception in xmi2mdr, because the *)
|
|
|
|
|
(* expression_type should be the xmiid of oclLib.Boolean, which we do not know *)
|
2005-09-07 17:32:04 +00:00
|
|
|
|
val triv_expr = XMI.LiteralExp {symbol = "true",
|
2005-08-26 12:29:56 +00:00
|
|
|
|
expression_type = "bool" }
|
|
|
|
|
|
2005-08-20 18:42:39 +00:00
|
|
|
|
fun mkOCLExpression tree =
|
|
|
|
|
let val elem = XmlTree.tagname_of tree
|
|
|
|
|
val atts = XmlTree.attributes_of tree
|
|
|
|
|
val trees = XmlTree.children_of tree
|
2005-08-17 15:45:10 +00:00
|
|
|
|
in
|
|
|
|
|
if elem = "UML15OCL.Expressions.BooleanLiteralExp" then
|
2005-09-07 17:32:04 +00:00
|
|
|
|
XMI.LiteralExp { symbol = getStringAtt "booleanSymbol" atts,
|
2005-08-26 11:56:18 +00:00
|
|
|
|
expression_type = findExpressionType trees }
|
2005-08-17 15:45:10 +00:00
|
|
|
|
else if elem = "UML15OCL.Expressions.IntegerLiteralExp" then
|
2005-09-07 17:32:04 +00:00
|
|
|
|
XMI.LiteralExp { symbol = getStringAtt "integerSymbol" atts,
|
2005-08-26 11:56:18 +00:00
|
|
|
|
expression_type = findExpressionType trees }
|
|
|
|
|
else if elem = "UML15OCL.Expressions.StringLiteralExp" then
|
2005-09-07 17:32:04 +00:00
|
|
|
|
XMI.LiteralExp { symbol = getStringAtt "stringSymbol" atts,
|
2005-08-26 11:56:18 +00:00
|
|
|
|
expression_type = findExpressionType trees }
|
|
|
|
|
else if elem = "UML15OCL.Expressions.RealLiteralExp" then
|
2005-09-07 17:32:04 +00:00
|
|
|
|
XMI.LiteralExp { symbol = getStringAtt "realSymbol" atts,
|
2005-08-26 11:56:18 +00:00
|
|
|
|
expression_type = findExpressionType trees }
|
2005-08-17 15:45:10 +00:00
|
|
|
|
else if elem = "UML15OCL.Expressions.OperationCallExp" then
|
2005-08-20 18:42:39 +00:00
|
|
|
|
let val op_src = hd (XmlTree.follow
|
2005-08-17 15:45:10 +00:00
|
|
|
|
"OCL.Expressions.PropertyCallExp.source"
|
|
|
|
|
trees)
|
|
|
|
|
val op_ref =
|
|
|
|
|
findXmiIdRef
|
|
|
|
|
"OCL.Expressions.OperationCallExp.referredOperation" trees
|
2005-08-20 18:42:39 +00:00
|
|
|
|
val op_args = XmlTree.follow_all
|
2005-08-17 15:45:10 +00:00
|
|
|
|
"OCL.Expressions.OperationCallExp.arguments"
|
|
|
|
|
trees
|
2005-09-07 17:32:04 +00:00
|
|
|
|
in XMI.OperationCallExp
|
2005-08-20 18:42:39 +00:00
|
|
|
|
{ source = mkOCLExpression op_src,
|
|
|
|
|
arguments = map (mkOCLExpression o hd) op_args,
|
2005-08-17 15:45:10 +00:00
|
|
|
|
referredOperation = op_ref,
|
|
|
|
|
expression_type = findExpressionType trees }
|
|
|
|
|
end
|
2005-09-07 07:35:31 +00:00
|
|
|
|
else if elem = "UML15OCL.Expressions.OclOperationWithTypeArgExp" then
|
|
|
|
|
let val op_src = hd (XmlTree.follow
|
|
|
|
|
"OCL.Expressions.PropertyCallExp.source"
|
|
|
|
|
trees)
|
2005-09-07 17:32:04 +00:00
|
|
|
|
in XMI.OperationWithTypeArgExp
|
2005-09-07 07:35:31 +00:00
|
|
|
|
{ source = mkOCLExpression op_src,
|
|
|
|
|
name = getName atts,
|
|
|
|
|
typeArgument = findXmiIdRef "OCL.Expressions.OclOperationWithTypeArgExp.typeArgument" trees,
|
|
|
|
|
expression_type = findExpressionType trees }
|
|
|
|
|
end
|
2005-08-17 15:45:10 +00:00
|
|
|
|
else if elem = "UML15OCL.Expressions.AttributeCallExp" then
|
|
|
|
|
let val att_ref =
|
|
|
|
|
findXmiIdRef
|
|
|
|
|
"OCL.Expressions.AttributeCallExp.referredAttribute" trees
|
2005-08-20 18:42:39 +00:00
|
|
|
|
val att_src = (hd o XmlTree.follow
|
2005-08-17 15:45:10 +00:00
|
|
|
|
"OCL.Expressions.PropertyCallExp.source")
|
|
|
|
|
trees
|
2005-09-07 17:32:04 +00:00
|
|
|
|
in XMI.AttributeCallExp
|
2005-08-20 18:42:39 +00:00
|
|
|
|
{ source = mkOCLExpression att_src,
|
2005-08-17 15:45:10 +00:00
|
|
|
|
referredAttribute = att_ref,
|
|
|
|
|
expression_type = findExpressionType trees }
|
2005-08-20 18:42:39 +00:00
|
|
|
|
end
|
2005-08-17 15:45:10 +00:00
|
|
|
|
else if elem = "UML15OCL.Expressions.AssociationEndCallExp" then
|
2005-08-20 18:42:39 +00:00
|
|
|
|
let val assoc_src = (hd o XmlTree.follow
|
2005-08-17 15:45:10 +00:00
|
|
|
|
"OCL.Expressions.PropertyCallExp.source")
|
|
|
|
|
trees
|
|
|
|
|
val assoc_ref =
|
|
|
|
|
findXmiIdRef
|
|
|
|
|
"OCL.Expressions.AssociationEndCallExp.referredAssociationEnd"
|
|
|
|
|
trees
|
2005-09-07 17:32:04 +00:00
|
|
|
|
in XMI.AssociationEndCallExp
|
2005-08-20 18:42:39 +00:00
|
|
|
|
{ source = mkOCLExpression assoc_src,
|
2005-08-17 15:45:10 +00:00
|
|
|
|
referredAssociationEnd = assoc_ref,
|
|
|
|
|
expression_type = findExpressionType trees }
|
|
|
|
|
end
|
2005-08-23 09:13:15 +00:00
|
|
|
|
else if elem = "UML15OCL.Expressions.AssociationClassCallExp" then
|
2005-08-17 15:45:10 +00:00
|
|
|
|
raise NotYetImplemented
|
|
|
|
|
else if elem = "UML15OCL.Expressions.VariableExp" then
|
|
|
|
|
let val var_ref = findXmiIdRef
|
|
|
|
|
"OCL.Expressions.VariableExp.referredVariable"
|
|
|
|
|
trees
|
2005-09-07 17:32:04 +00:00
|
|
|
|
in XMI.VariableExp { referredVariable = var_ref,
|
2005-08-17 15:45:10 +00:00
|
|
|
|
expression_type = findExpressionType trees }
|
|
|
|
|
end
|
|
|
|
|
else if elem = "UML15OCL.Expressions.IfExp" then
|
2005-08-20 18:42:39 +00:00
|
|
|
|
let val cond = (hd o XmlTree.follow
|
2005-08-17 15:45:10 +00:00
|
|
|
|
"OCL.Expressions.IfExp.condition") trees
|
2005-08-20 18:42:39 +00:00
|
|
|
|
val then_exp = (hd o XmlTree.follow
|
2005-08-17 15:45:10 +00:00
|
|
|
|
"OCL.Expressions.IfExp.thenExpression")
|
|
|
|
|
trees
|
2005-08-20 18:42:39 +00:00
|
|
|
|
val else_exp = (hd o XmlTree.follow
|
2005-08-17 15:45:10 +00:00
|
|
|
|
"OCL.Expressions.IfExp.elseExpression")
|
|
|
|
|
trees
|
2005-09-07 17:32:04 +00:00
|
|
|
|
in XMI.IfExp { condition = mkOCLExpression cond,
|
2005-08-20 18:42:39 +00:00
|
|
|
|
thenExpression = mkOCLExpression then_exp,
|
|
|
|
|
elseExpression = mkOCLExpression else_exp,
|
2005-08-17 15:45:10 +00:00
|
|
|
|
expression_type = findExpressionType trees }
|
|
|
|
|
end
|
|
|
|
|
else if elem = "UML15OCL.Expressions.LetExp" then
|
2005-08-20 18:42:39 +00:00
|
|
|
|
let val var_decl = (hd o XmlTree.follow
|
2005-08-17 15:45:10 +00:00
|
|
|
|
"OCL.Expressions.LetExp.variable") trees
|
2005-08-20 18:42:39 +00:00
|
|
|
|
val var_xmiid = getXmiId (XmlTree.attributes_of var_decl)
|
|
|
|
|
val var_name = getName (XmlTree.attributes_of var_decl)
|
2005-08-17 15:45:10 +00:00
|
|
|
|
val var_type_ref = findXmiIdRef
|
|
|
|
|
"OCL.Expressions.VariableDeclaration.type"
|
2005-08-20 18:42:39 +00:00
|
|
|
|
(XmlTree.children_of var_decl)
|
|
|
|
|
val in_exp = (hd o XmlTree.follow "OCL.Expressions.LetExp.in") trees
|
2005-08-17 15:45:10 +00:00
|
|
|
|
val init_exp =
|
2005-08-20 18:42:39 +00:00
|
|
|
|
(hd o XmlTree.follow
|
2005-08-17 15:45:10 +00:00
|
|
|
|
"OCL.Expressions.VariableDeclaration.initExpression")
|
2005-08-20 18:42:39 +00:00
|
|
|
|
(XmlTree.children_of var_decl)
|
2005-09-07 17:32:04 +00:00
|
|
|
|
in XMI.LetExp
|
2005-08-17 15:45:10 +00:00
|
|
|
|
{ variable = { xmiid = var_xmiid,
|
|
|
|
|
name = var_name,
|
|
|
|
|
declaration_type = var_type_ref },
|
2005-08-20 18:42:39 +00:00
|
|
|
|
initExpression = mkOCLExpression init_exp ,
|
|
|
|
|
inExpression = mkOCLExpression in_exp,
|
2005-08-17 15:45:10 +00:00
|
|
|
|
expression_type = findExpressionType trees }
|
|
|
|
|
end
|
|
|
|
|
else if elem = "UML15OCL.Expressions.IterateExp" then
|
|
|
|
|
raise NotYetImplemented
|
|
|
|
|
else if elem = "UML15OCL.Expressions.IteratorExp" then
|
2005-08-22 15:04:08 +00:00
|
|
|
|
let val iterator_src = (hd o XmlTree.follow
|
|
|
|
|
"OCL.Expressions.PropertyCallExp.source")
|
|
|
|
|
trees
|
|
|
|
|
val iterator_body = (hd o XmlTree.follow
|
|
|
|
|
"OCL.Expressions.LoopExp.body")
|
|
|
|
|
trees
|
|
|
|
|
val iterators = XmlTree.follow "OCL.Expressions.LoopExp.iterators"
|
|
|
|
|
trees
|
|
|
|
|
in
|
2005-09-07 17:32:04 +00:00
|
|
|
|
XMI.IteratorExp { name = getName atts,
|
2005-08-22 15:04:08 +00:00
|
|
|
|
iterators = map mkVariableDec iterators,
|
|
|
|
|
body = mkOCLExpression iterator_body,
|
|
|
|
|
source = mkOCLExpression iterator_src,
|
|
|
|
|
expression_type = findExpressionType trees }
|
|
|
|
|
end
|
2005-08-20 18:42:39 +00:00
|
|
|
|
else raise IllFormed ("in mkOCLExpression: found unexpected element "^elem)
|
2005-08-17 15:45:10 +00:00
|
|
|
|
end
|
|
|
|
|
|
2005-08-23 11:37:41 +00:00
|
|
|
|
fun getAssociations t = (map mkAssociation (XmlTree.filter "UML:Association" t))@
|
|
|
|
|
(map mkAssociationClass (XmlTree.filter "UML:AssociationClass" t))
|
2005-08-17 15:45:10 +00:00
|
|
|
|
|
2005-09-08 17:00:46 +00:00
|
|
|
|
val filterConstraints = XmlTree.filter "UML:Constraint"
|
|
|
|
|
val filterStereotypes = XmlTree.filter "UML:Stereotype"
|
|
|
|
|
val filterVariableDecs = XmlTree.filter "UML15OCL.Expressions.VariableDeclaration"
|
|
|
|
|
val filterPackages = fn trees => append (XmlTree.filter "UML:Package" trees)
|
|
|
|
|
(XmlTree.filter "UML:Model" trees)
|
|
|
|
|
val filterStateMachines = XmlTree.filter "UML:StateMachine"
|
|
|
|
|
val filterActivityGraphs= XmlTree.filter "UML:ActivityGraph"
|
|
|
|
|
|
|
|
|
|
|
2005-08-17 15:45:10 +00:00
|
|
|
|
(* FIX: other classifiers *)
|
|
|
|
|
fun filterClassifiers trees =
|
2005-08-20 18:42:39 +00:00
|
|
|
|
filter (fn x => let val elem = XmlTree.tagname_of x in
|
2005-08-17 15:45:10 +00:00
|
|
|
|
elem = "UML:Class" orelse
|
|
|
|
|
elem = "UML:Primitive" orelse
|
|
|
|
|
elem = "UML:DataType" orelse
|
|
|
|
|
elem = "UML:Interface" orelse
|
|
|
|
|
elem = "UML:Enumeration" orelse
|
|
|
|
|
elem = "UML15OCL.Types.SequenceType" orelse
|
|
|
|
|
elem = "UML15OCL.Types.BagType" orelse
|
|
|
|
|
elem = "UML15OCL.Types.SetType" orelse
|
|
|
|
|
elem = "UML15OCL.Types.CollectionType" orelse
|
2005-08-23 11:37:41 +00:00
|
|
|
|
elem = "UML15OCL.Types.VoidType" orelse
|
|
|
|
|
elem = "UML:AssociationClass"
|
2005-08-17 15:45:10 +00:00
|
|
|
|
end) trees
|
|
|
|
|
|
2005-08-20 18:42:39 +00:00
|
|
|
|
fun mkConstraint tree =
|
|
|
|
|
let fun f atts trees =
|
|
|
|
|
let val expr = (hd o (XmlTree.follow
|
|
|
|
|
"OCL.Expressions.ExpressionInOcl.bodyExpression") o
|
|
|
|
|
(XmlTree.follow "UML15OCL.Expressions.ExpressionInOcl") o
|
|
|
|
|
(XmlTree.follow "UML:Constraint.body"))
|
|
|
|
|
trees
|
|
|
|
|
val st_type = hd (XmlTree.follow "UML:ModelElement.stereotype" trees)
|
|
|
|
|
val st_type_ref = getXmiIdref (XmlTree.attributes_of st_type)
|
|
|
|
|
in { xmiid = getXmiId atts,
|
|
|
|
|
name = case XmlTree.attvalue_of "name" atts of SOME s => SOME s | _ => NONE,
|
|
|
|
|
constraint_type = st_type_ref,
|
2005-08-26 12:29:56 +00:00
|
|
|
|
body = (mkOCLExpression expr (* if something goes wrong, we return *)
|
|
|
|
|
handle _ => triv_expr) (* return trivial expression "true" *)
|
|
|
|
|
}
|
2005-08-20 18:42:39 +00:00
|
|
|
|
end
|
|
|
|
|
in XmlTree.apply_on "UML:Constraint" f tree
|
2005-08-23 09:13:15 +00:00
|
|
|
|
handle XmlTree.IllFormed msg => raise IllFormed ("in mkConstraint: "^msg)
|
2005-08-20 18:42:39 +00:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fun mkParameter tree =
|
|
|
|
|
let fun f atts trees = { xmiid = getXmiId atts,
|
|
|
|
|
name = getName atts,
|
|
|
|
|
kind = getKind atts,
|
|
|
|
|
type_id = (getXmiIdref o
|
|
|
|
|
XmlTree.attributes_of o hd o
|
|
|
|
|
(XmlTree.follow "UML:Parameter.type"))
|
|
|
|
|
trees }
|
|
|
|
|
in XmlTree.apply_on "UML:Parameter" f tree
|
2005-08-23 09:13:15 +00:00
|
|
|
|
handle XmlTree.IllFormed msg => raise IllFormed ("in mkParameter: "^msg)
|
2005-08-20 18:42:39 +00:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
fun mkOperation tree =
|
|
|
|
|
let fun f atts trees =
|
|
|
|
|
{ xmiid = getXmiId atts,
|
|
|
|
|
name = getName atts,
|
|
|
|
|
visibility = getVisibility atts,
|
|
|
|
|
isQuery = getBoolAtt "isQuery" atts,
|
|
|
|
|
parameter = (map mkParameter
|
|
|
|
|
(XmlTree.follow "UML:BehavioralFeature.parameter"
|
|
|
|
|
trees)),
|
|
|
|
|
constraints = if XmlTree.exists "UML:ModelElement.constraint" trees
|
|
|
|
|
then map (getXmiIdref o XmlTree.attributes_of)
|
|
|
|
|
(XmlTree.follow "UML:ModelElement.constraint"
|
|
|
|
|
trees)
|
|
|
|
|
else nil}
|
|
|
|
|
in XmlTree.apply_on "UML:Operation" f tree
|
2005-08-23 09:13:15 +00:00
|
|
|
|
handle XmlTree.IllFormed msg => raise IllFormed ("in mkOperation: "^msg)
|
2005-08-20 18:42:39 +00:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
fun mkAttribute tree =
|
|
|
|
|
let fun f atts trees =
|
|
|
|
|
{ xmiid = getXmiId atts,
|
|
|
|
|
name = getName atts,
|
|
|
|
|
visibility = getVisibility atts,
|
2005-09-13 15:56:31 +00:00
|
|
|
|
changeability = getChangeabilityMaybe atts,
|
2005-08-23 15:03:15 +00:00
|
|
|
|
ordering = getOrderingMaybe atts,
|
2005-08-20 18:42:39 +00:00
|
|
|
|
type_id = (getXmiIdref o XmlTree.attributes_of o hd o
|
2005-08-23 15:03:15 +00:00
|
|
|
|
(XmlTree.follow "UML:StructuralFeature.type")) trees,
|
|
|
|
|
multiplicity = (mkMultiplicity o hd o (XmlTree.follow "UML:StructuralFeature.multiplicity"))
|
|
|
|
|
trees}
|
2005-08-20 18:42:39 +00:00
|
|
|
|
in XmlTree.apply_on "UML:Attribute" f tree
|
2005-08-23 09:13:15 +00:00
|
|
|
|
handle XmlTree.IllFormed msg => raise IllFormed ("in mkAttribute: "^msg)
|
2005-08-20 18:42:39 +00:00
|
|
|
|
end
|
2005-08-17 15:45:10 +00:00
|
|
|
|
|
2005-08-19 11:39:04 +00:00
|
|
|
|
fun mkClass atts trees
|
2005-09-07 17:32:04 +00:00
|
|
|
|
= XMI.Class { xmiid = getXmiId atts,
|
2005-08-17 15:45:10 +00:00
|
|
|
|
name = getName atts,
|
|
|
|
|
isActive = getBoolAtt "isActive" atts,
|
|
|
|
|
visibility = getVisibility atts,
|
|
|
|
|
isLeaf = getBoolAtt "isLeaf" atts,
|
2005-08-20 18:42:39 +00:00
|
|
|
|
generalizations = (map (getXmiIdref o XmlTree.attributes_of o hd)
|
|
|
|
|
(XmlTree.follow_all
|
2005-08-17 15:45:10 +00:00
|
|
|
|
"UML:GeneralizableElement.generalization"
|
|
|
|
|
trees)),
|
2005-08-20 18:42:39 +00:00
|
|
|
|
attributes = if XmlTree.exists "UML:Classifier.feature" trees
|
|
|
|
|
then map mkAttribute
|
|
|
|
|
((XmlTree.filter "UML:Attribute")
|
|
|
|
|
(XmlTree.follow "UML:Classifier.feature"
|
2005-08-17 15:45:10 +00:00
|
|
|
|
trees))
|
|
|
|
|
else nil,
|
2005-08-20 18:42:39 +00:00
|
|
|
|
operations = if XmlTree.exists "UML:Classifier.feature" trees
|
|
|
|
|
then map mkOperation
|
|
|
|
|
((XmlTree.filter "UML:Operation")
|
|
|
|
|
(XmlTree.follow "UML:Classifier.feature"
|
2005-08-17 15:45:10 +00:00
|
|
|
|
trees))
|
|
|
|
|
else nil,
|
2005-08-20 18:42:39 +00:00
|
|
|
|
invariant = if XmlTree.exists "UML:ModelElement.constraint" trees
|
|
|
|
|
then map (getXmiIdref o XmlTree.attributes_of)
|
|
|
|
|
(XmlTree.follow "UML:ModelElement.constraint"
|
2005-08-17 15:45:10 +00:00
|
|
|
|
trees)
|
|
|
|
|
else nil}
|
|
|
|
|
|
2005-08-19 11:39:04 +00:00
|
|
|
|
fun mkPrimitive atts trees
|
2005-09-07 17:32:04 +00:00
|
|
|
|
= XMI.Primitive { xmiid = getXmiId atts,
|
2005-08-17 15:45:10 +00:00
|
|
|
|
name = getName atts,
|
2005-08-20 18:42:39 +00:00
|
|
|
|
operations = if XmlTree.exists "UML:Classifier.feature" trees
|
|
|
|
|
then map mkOperation
|
|
|
|
|
((XmlTree.filter "UML:Operation")
|
|
|
|
|
(XmlTree.follow "UML:Classifier.feature"
|
2005-08-17 15:45:10 +00:00
|
|
|
|
trees))
|
|
|
|
|
else nil,
|
2005-08-20 18:42:39 +00:00
|
|
|
|
generalizations = (map (getXmiIdref o XmlTree.attributes_of o hd)
|
|
|
|
|
(XmlTree.follow_all
|
2005-08-17 15:45:10 +00:00
|
|
|
|
"UML:GeneralizableElement.generalization"
|
|
|
|
|
trees)),
|
2005-08-20 18:42:39 +00:00
|
|
|
|
invariant = if XmlTree.exists "UML:ModelElement.constraint" trees
|
|
|
|
|
then map (getXmiIdref o XmlTree.attributes_of)
|
|
|
|
|
(XmlTree.follow "UML:ModelElement.constraint"
|
2005-08-17 15:45:10 +00:00
|
|
|
|
trees)
|
|
|
|
|
else nil
|
|
|
|
|
}
|
2005-08-23 09:13:15 +00:00
|
|
|
|
handle XmlTree.IllFormed msg => raise IllFormed ("in mkPrimitive: "^msg)
|
2005-08-17 15:45:10 +00:00
|
|
|
|
|
2005-08-19 11:39:04 +00:00
|
|
|
|
fun mkEnumeration atts trees
|
2005-09-07 17:32:04 +00:00
|
|
|
|
= XMI.Enumeration { xmiid = getXmiId atts,
|
2005-08-20 18:42:39 +00:00
|
|
|
|
name = getName atts,
|
|
|
|
|
operations = if XmlTree.exists "UML:Classifier.feature" trees
|
|
|
|
|
then map mkOperation
|
|
|
|
|
((XmlTree.filter "UML:Operation")
|
|
|
|
|
(XmlTree.follow "UML:Classifier.feature"
|
|
|
|
|
trees))
|
|
|
|
|
else nil,
|
|
|
|
|
generalizations = (map (getXmiIdref o XmlTree.attributes_of o hd)
|
|
|
|
|
(XmlTree.follow_all
|
|
|
|
|
"UML:GeneralizableElement.generalization"
|
|
|
|
|
trees)),
|
|
|
|
|
literals = nil, (* FIX *)
|
|
|
|
|
invariant = if XmlTree.exists "UML:ModelElement.constraint" trees
|
|
|
|
|
then map (getXmiIdref o XmlTree.attributes_of)
|
|
|
|
|
(XmlTree.follow "UML:ModelElement.constraint"
|
|
|
|
|
trees)
|
|
|
|
|
else nil
|
|
|
|
|
}
|
2005-08-23 09:13:15 +00:00
|
|
|
|
handle XmlTree.IllFormed msg => raise IllFormed ("in mkEnumeration: "^msg)
|
2005-08-17 15:45:10 +00:00
|
|
|
|
|
2005-09-07 17:32:04 +00:00
|
|
|
|
fun mkVoid atts trees = XMI.Void { xmiid = getXmiId atts,
|
2005-08-20 18:42:39 +00:00
|
|
|
|
name = getName atts }
|
2005-08-23 09:13:15 +00:00
|
|
|
|
handle XmlTree.IllFormed msg => raise IllFormed ("in mkVoid: "^msg)
|
2005-08-18 16:18:28 +00:00
|
|
|
|
|
2005-08-17 15:45:10 +00:00
|
|
|
|
|
|
|
|
|
fun mkGenericCollection atts trees =
|
|
|
|
|
{ xmiid = getXmiId atts,
|
|
|
|
|
name = getName atts,
|
2005-08-20 18:42:39 +00:00
|
|
|
|
operations = if XmlTree.exists "UML:Classifier.feature" trees
|
|
|
|
|
then map mkOperation
|
|
|
|
|
((XmlTree.filter "UML:Operation")
|
|
|
|
|
(XmlTree.follow "UML:Classifier.feature"
|
2005-08-17 15:45:10 +00:00
|
|
|
|
trees))
|
|
|
|
|
else nil,
|
2005-08-20 18:42:39 +00:00
|
|
|
|
generalizations = (map (getXmiIdref o XmlTree.attributes_of o hd)
|
|
|
|
|
(XmlTree.follow_all
|
2005-08-17 15:45:10 +00:00
|
|
|
|
"UML:GeneralizableElement.generalization"
|
|
|
|
|
trees)),
|
2005-08-20 18:42:39 +00:00
|
|
|
|
elementtype = ((getXmiIdref o XmlTree.attributes_of o hd)
|
|
|
|
|
(XmlTree.follow
|
2005-08-17 15:45:10 +00:00
|
|
|
|
"OCL.Types.CollectionType.elementType"
|
|
|
|
|
trees))
|
|
|
|
|
}
|
2005-08-23 09:13:15 +00:00
|
|
|
|
handle XmlTree.IllFormed msg => raise IllFormed ("in mkGenericCollection: "^msg)
|
2005-08-18 16:18:28 +00:00
|
|
|
|
|
2005-08-20 18:42:39 +00:00
|
|
|
|
|
2005-09-07 17:32:04 +00:00
|
|
|
|
fun mkCollection atts trees = XMI.Collection (mkGenericCollection atts trees)
|
|
|
|
|
fun mkSequence atts trees = XMI.Sequence (mkGenericCollection atts trees)
|
|
|
|
|
fun mkSet atts trees = XMI.Set (mkGenericCollection atts trees)
|
|
|
|
|
fun mkBag atts trees = XMI.Bag (mkGenericCollection atts trees)
|
|
|
|
|
fun mkOrderedSet atts trees = XMI.OrderedSet (mkGenericCollection atts trees)
|
2005-08-17 15:45:10 +00:00
|
|
|
|
|
2005-09-13 20:15:00 +00:00
|
|
|
|
fun mkStereotype tree =
|
|
|
|
|
let fun f atts trees = { xmiid = getXmiId atts,
|
|
|
|
|
name = getName atts,
|
|
|
|
|
baseClass = NONE, (*FIX*)
|
|
|
|
|
stereotypeConstraint = NONE (*FIX*)
|
|
|
|
|
}
|
|
|
|
|
in XmlTree.apply_on "UML:Stereotype" f tree
|
|
|
|
|
handle XmlTree.IllFormed msg => raise IllFormed ("in mkStereotype: "^msg)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
fun mkStereotypeR tree =
|
|
|
|
|
let fun f atts trees = { xmiid = getXmiIdref atts,
|
|
|
|
|
name = "",
|
|
|
|
|
baseClass = NONE, (*FIX*)
|
|
|
|
|
stereotypeConstraint = NONE (*FIX*)
|
|
|
|
|
}
|
|
|
|
|
in XmlTree.apply_on "UML:Stereotype" f tree
|
|
|
|
|
handle XmlTree.IllFormed msg => raise IllFormed ("in mkStereotype: "^msg)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2005-08-20 18:42:39 +00:00
|
|
|
|
fun mkClassifier tree =
|
|
|
|
|
let val elem = XmlTree.tagname_of tree
|
|
|
|
|
val atts = XmlTree.attributes_of tree
|
|
|
|
|
val trees = XmlTree.children_of tree
|
2005-08-17 15:45:10 +00:00
|
|
|
|
in
|
2005-08-23 11:37:41 +00:00
|
|
|
|
if elem = "UML:Class" orelse
|
|
|
|
|
elem = "UML:AssociationClass" then mkClass atts trees
|
|
|
|
|
else if elem = "UML:Interface" orelse (* FIX: use a custom mkInterface *)
|
|
|
|
|
elem = "UML:DataType" orelse
|
|
|
|
|
elem = "UML:Primitive" then mkPrimitive atts trees
|
2005-08-19 11:39:04 +00:00
|
|
|
|
else if elem = "UML:Enumeration" then mkEnumeration atts trees
|
|
|
|
|
else if elem = "UML15OCL.Types.VoidType" then mkVoid atts trees
|
2005-08-17 15:45:10 +00:00
|
|
|
|
else if elem = "UML15OCL.Types.CollectionType" then
|
2005-08-19 11:39:04 +00:00
|
|
|
|
mkCollection atts trees
|
|
|
|
|
else if elem = "UML15OCL.Types.SequenceType" then mkSequence atts trees
|
|
|
|
|
else if elem = "UML15OCL.Types.SetType" then mkSet atts trees
|
|
|
|
|
else if elem = "UML15OCL.Types.BagType" then mkBag atts trees
|
2005-08-17 15:45:10 +00:00
|
|
|
|
else if elem = "UML15OCL.Types.OrderedSetType" then
|
2005-08-19 11:39:04 +00:00
|
|
|
|
mkOrderedSet atts trees
|
2005-08-20 18:42:39 +00:00
|
|
|
|
else raise IllFormed ("in mkClassifier: found unexpected element "^elem)
|
2005-08-17 15:45:10 +00:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2005-08-20 18:42:39 +00:00
|
|
|
|
fun mkGeneralization tree =
|
|
|
|
|
let fun f atts trees =
|
|
|
|
|
{ xmiid = getXmiId atts,
|
|
|
|
|
child_id = (getXmiIdref o XmlTree.attributes_of o hd o
|
|
|
|
|
(XmlTree.follow "UML:Generalization.child")) trees,
|
|
|
|
|
parent_id = (getXmiIdref o XmlTree.attributes_of o hd o
|
|
|
|
|
(XmlTree.follow "UML:Generalization.parent")) trees }
|
|
|
|
|
in XmlTree.apply_on "UML:Generalization" f tree
|
2005-08-23 09:13:15 +00:00
|
|
|
|
handle XmlTree.IllFormed msg => raise IllFormed ("in mkGeneralization: "^msg)
|
2005-08-20 18:42:39 +00:00
|
|
|
|
end
|
2005-08-17 15:45:10 +00:00
|
|
|
|
|
2005-09-07 17:02:47 +00:00
|
|
|
|
|
2005-09-12 20:13:23 +00:00
|
|
|
|
fun mkProcedure tree =
|
|
|
|
|
let fun get_AttrL x = (XmlTree.attributes_of o (XmlTree.find "UML:ActionExpression") o
|
|
|
|
|
XmlTree.children_of o (XmlTree.find "UML:Action.script")) x
|
|
|
|
|
handle _ => (writeln(getXmiId(XmlTree.attributes_of tree)); [])
|
|
|
|
|
fun f atts trees = XMI.mk_Procedure{
|
|
|
|
|
xmiid = getXmiId atts,
|
|
|
|
|
name = getName atts,
|
|
|
|
|
isSpecification = getBoolAtt "isSpecification" atts,
|
|
|
|
|
isAsynchronous = getBoolAtt "isAsynchronous" atts,
|
|
|
|
|
language = getLang(get_AttrL trees),
|
|
|
|
|
body = getBody(get_AttrL trees),
|
|
|
|
|
expression = nil}
|
|
|
|
|
in XmlTree.apply_on "UML:CallAction" f tree
|
|
|
|
|
(* POSEIDON specific ! According to UML 1.5, should be: "UML:Method" *)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fun mkGuard tree =
|
|
|
|
|
let val getExpr = XmlTree.attributes_of o (XmlTree.find "UML:BooleanExpression") o
|
|
|
|
|
XmlTree.children_of o (XmlTree.find "UML:Guard.expression")
|
|
|
|
|
fun f atts trees = XMI.mk_Guard{
|
|
|
|
|
xmiid = getXmiId atts,
|
|
|
|
|
name = getName atts,
|
|
|
|
|
isSpecification = getBoolAtt "isSpecification" atts,
|
|
|
|
|
visibility = getVisibility atts,
|
|
|
|
|
language = getLang(getExpr trees),
|
|
|
|
|
body = getBody(getExpr trees),
|
|
|
|
|
expression = nil}
|
|
|
|
|
in XmlTree.apply_on "UML:Guard" f tree
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
2005-09-13 20:15:00 +00:00
|
|
|
|
fun mkTaggedValue tree =
|
|
|
|
|
let fun f atts trees ={xmiid = getXmiId atts,
|
|
|
|
|
dataValue= "", (* BUG in unserem xml *)
|
|
|
|
|
tag_type = (getXmiIdref o XmlTree.attributes_of o
|
|
|
|
|
(XmlTree.find "UML:TagDefinition") o
|
|
|
|
|
XmlTree.children_of o
|
|
|
|
|
(XmlTree.find "UML:TaggedValue.type")) trees
|
|
|
|
|
}
|
|
|
|
|
in XmlTree.apply_on "UML:TaggedValue" f tree
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
2005-09-08 17:00:46 +00:00
|
|
|
|
fun mkTransition tree =
|
2005-09-12 20:13:23 +00:00
|
|
|
|
let val getGuard = (ap_some (mkGuard o
|
|
|
|
|
(XmlTree.find "UML:Guard") o
|
|
|
|
|
XmlTree.children_of)) o
|
|
|
|
|
(XmlTree.find_some "UML:Transition.guard")
|
2005-09-13 20:15:00 +00:00
|
|
|
|
|
|
|
|
|
val getTagVal = List.concat o
|
|
|
|
|
(map ((map mkTaggedValue) o XmlTree.children_of)) o
|
|
|
|
|
(XmlTree.filter "UML:ModelElement.taggedValue")
|
|
|
|
|
|
2005-09-12 20:13:23 +00:00
|
|
|
|
fun f atts trees = XMI.mk_Transition
|
|
|
|
|
{isSpecification = getBoolAtt "isSpecification" atts,
|
2005-09-08 17:00:46 +00:00
|
|
|
|
xmiid = getXmiId atts,
|
|
|
|
|
source = (getXmiIdref o XmlTree.attributes_of o
|
|
|
|
|
hd o XmlTree.children_of o
|
|
|
|
|
(XmlTree.find "UML:Transition.source"))
|
|
|
|
|
(trees),
|
|
|
|
|
target = (getXmiIdref o XmlTree.attributes_of o
|
|
|
|
|
hd o XmlTree.children_of o
|
|
|
|
|
(XmlTree.find "UML:Transition.target"))
|
|
|
|
|
(trees),
|
2005-09-12 20:13:23 +00:00
|
|
|
|
guard = getGuard trees,
|
2005-09-08 17:00:46 +00:00
|
|
|
|
trigger= NONE, (* TO BE DONE *)
|
2005-09-13 20:15:00 +00:00
|
|
|
|
effect = NONE (* TO BE DONE *),
|
|
|
|
|
taggedValue = getTagVal trees}
|
|
|
|
|
|
2005-09-08 17:00:46 +00:00
|
|
|
|
in XmlTree.apply_on "UML:Transition" f tree
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fun getPseudoStateKindAttr atts =
|
|
|
|
|
(case getStringAtt "kind" atts of
|
|
|
|
|
"initial" => XMI.initial
|
|
|
|
|
| "deep" => XMI.deep
|
|
|
|
|
| "shallow" => XMI.shallow
|
|
|
|
|
| "join" => XMI.join
|
|
|
|
|
| "fork" => XMI.fork
|
|
|
|
|
| "junction" => XMI.junction
|
|
|
|
|
| "choice" => XMI.choice)
|
|
|
|
|
|
|
|
|
|
|
2005-09-13 20:15:00 +00:00
|
|
|
|
|
2005-09-08 17:00:46 +00:00
|
|
|
|
fun mkState tree =
|
2005-09-12 20:13:23 +00:00
|
|
|
|
let val elem = XmlTree.tagname_of tree
|
|
|
|
|
val atts = XmlTree.attributes_of tree
|
|
|
|
|
val trees = XmlTree.children_of tree
|
|
|
|
|
val xmiid = getXmiId atts
|
|
|
|
|
val name = getName atts
|
2005-09-08 17:00:46 +00:00
|
|
|
|
val isSpecification = getBoolAtt "isSpecification" atts
|
2005-09-12 20:13:23 +00:00
|
|
|
|
val getTid = getXmiIdref o XmlTree.attributes_of
|
2005-09-13 20:15:00 +00:00
|
|
|
|
fun getTrans str = List.concat o
|
|
|
|
|
(map ((map getTid) o XmlTree.children_of)) o
|
2005-09-09 14:58:20 +00:00
|
|
|
|
(XmlTree.filter str)
|
2005-09-12 20:13:23 +00:00
|
|
|
|
val getIncoming = getTrans "UML:StateVertex.incoming"
|
|
|
|
|
val getOutgoing = getTrans "UML:StateVertex.outgoing"
|
|
|
|
|
val getSubvertex = (map mkState) o XmlTree.children_of o
|
|
|
|
|
(XmlTree.find "UML:CompositeState.subvertex")
|
|
|
|
|
val getEntry = (ap_some (mkProcedure o
|
|
|
|
|
(XmlTree.find "UML:CallAction") o
|
|
|
|
|
XmlTree.children_of)) o
|
|
|
|
|
(XmlTree.find_some "UML:State.entry")
|
2005-09-13 20:15:00 +00:00
|
|
|
|
val getTagVal = List.concat o
|
|
|
|
|
(map ((map mkTaggedValue) o XmlTree.children_of)) o
|
|
|
|
|
(XmlTree.filter "UML:ModelElement.taggedValue")
|
|
|
|
|
val getStereo = List.concat o
|
|
|
|
|
(map ((map mkStereotypeR) o XmlTree.children_of)) o
|
|
|
|
|
(XmlTree.filter "UML:ModelElement.stereotype")
|
|
|
|
|
|
2005-09-08 17:00:46 +00:00
|
|
|
|
(*
|
|
|
|
|
val visibility = getVisibility atts
|
|
|
|
|
*)
|
|
|
|
|
in case elem of
|
|
|
|
|
"UML:CompositeState" =>
|
2005-09-12 20:13:23 +00:00
|
|
|
|
XMI.CompositeState{
|
|
|
|
|
xmiid=xmiid,name=name,isSpecification=isSpecification,
|
2005-09-13 20:15:00 +00:00
|
|
|
|
stereotype = getStereo trees,
|
2005-09-08 17:00:46 +00:00
|
|
|
|
isConcurrent = getBoolAtt "isConcurrent" atts,
|
2005-09-09 14:58:20 +00:00
|
|
|
|
outgoing = getOutgoing trees, incoming = getIncoming trees,
|
|
|
|
|
subvertex = getSubvertex trees,
|
2005-09-12 20:13:23 +00:00
|
|
|
|
entry = getEntry trees,
|
2005-09-08 17:00:46 +00:00
|
|
|
|
exit = NONE,
|
2005-09-13 20:15:00 +00:00
|
|
|
|
doActivity = NONE,
|
|
|
|
|
taggedValue = getTagVal trees}
|
|
|
|
|
|"UML:SubactivityState" =>
|
2005-09-12 20:13:23 +00:00
|
|
|
|
XMI.SubactivityState{
|
|
|
|
|
xmiid=xmiid,name=name,isSpecification=isSpecification,
|
2005-09-13 20:15:00 +00:00
|
|
|
|
stereotype = getStereo trees,
|
2005-09-09 14:58:20 +00:00
|
|
|
|
isConcurrent = getBoolAtt "isConcurrent" atts,
|
|
|
|
|
isDynamic = getBoolAtt "isDynamic" atts,
|
|
|
|
|
outgoing = getOutgoing trees, incoming = getIncoming trees,
|
|
|
|
|
subvertex = getSubvertex trees,
|
2005-09-12 20:13:23 +00:00
|
|
|
|
entry = getEntry trees,
|
2005-09-09 14:58:20 +00:00
|
|
|
|
exit = NONE,
|
|
|
|
|
doActivity = NONE,
|
|
|
|
|
submachine = mkStateMachine (hd trees)
|
|
|
|
|
(* HACK ! So far, no UML tool supports this. Parser has to be adapted
|
2005-09-13 20:15:00 +00:00
|
|
|
|
of we find a first example ... *),
|
|
|
|
|
taggedValue = getTagVal trees}
|
2005-09-08 17:00:46 +00:00
|
|
|
|
|"UML:ActionState" =>
|
2005-09-12 20:13:23 +00:00
|
|
|
|
XMI.ActionState {
|
|
|
|
|
xmiid=xmiid,name=name,isSpecification=isSpecification,
|
2005-09-13 20:15:00 +00:00
|
|
|
|
stereotype = getStereo trees,
|
2005-09-09 14:58:20 +00:00
|
|
|
|
outgoing = getOutgoing trees, incoming = getIncoming trees,
|
2005-09-08 17:00:46 +00:00
|
|
|
|
isDynamic = getBoolAtt "isDynamic" atts,
|
2005-09-12 20:13:23 +00:00
|
|
|
|
entry = getEntry trees,
|
2005-09-08 17:00:46 +00:00
|
|
|
|
exit = NONE,
|
2005-09-13 20:15:00 +00:00
|
|
|
|
doActivity = NONE,
|
|
|
|
|
taggedValue = getTagVal trees}
|
2005-09-08 17:00:46 +00:00
|
|
|
|
|"UML:Pseudostate" =>
|
|
|
|
|
XMI.PseudoState {
|
2005-09-12 20:13:23 +00:00
|
|
|
|
xmiid=xmiid,name=name,isSpecification=isSpecification,
|
2005-09-13 20:15:00 +00:00
|
|
|
|
stereotype = getStereo trees,
|
2005-09-12 20:13:23 +00:00
|
|
|
|
entry = getEntry trees,
|
2005-09-08 17:00:46 +00:00
|
|
|
|
exit = NONE,
|
|
|
|
|
doActivity = NONE,
|
2005-09-09 14:58:20 +00:00
|
|
|
|
kind = getPseudoStateKindAttr atts,
|
2005-09-13 20:15:00 +00:00
|
|
|
|
outgoing = getOutgoing trees,incoming = getIncoming trees,
|
|
|
|
|
taggedValue = getTagVal trees}
|
2005-09-08 17:00:46 +00:00
|
|
|
|
|"UML:SimpleState" =>
|
2005-09-12 20:13:23 +00:00
|
|
|
|
XMI.SimpleState{
|
|
|
|
|
xmiid=xmiid,name=name,isSpecification=isSpecification,
|
2005-09-13 20:15:00 +00:00
|
|
|
|
stereotype = getStereo trees,
|
2005-09-12 20:13:23 +00:00
|
|
|
|
entry = getEntry trees,
|
2005-09-08 17:00:46 +00:00
|
|
|
|
exit = NONE,
|
|
|
|
|
doActivity = NONE,
|
2005-09-13 20:15:00 +00:00
|
|
|
|
outgoing = getOutgoing trees, incoming = getIncoming trees,
|
|
|
|
|
taggedValue = getTagVal trees}
|
2005-09-12 20:13:23 +00:00
|
|
|
|
|"UML:ObjectFlowState" =>
|
|
|
|
|
XMI.ObjectFlowState{
|
|
|
|
|
xmiid=xmiid,name=name,isSpecification=isSpecification,
|
2005-09-13 20:15:00 +00:00
|
|
|
|
stereotype = getStereo trees,
|
2005-09-12 20:13:23 +00:00
|
|
|
|
entry = getEntry trees,
|
2005-09-09 14:58:20 +00:00
|
|
|
|
exit = NONE,
|
|
|
|
|
doActivity = NONE,
|
|
|
|
|
outgoing = getOutgoing trees, incoming = getIncoming trees,
|
|
|
|
|
isSynch = getBoolAtt "isSynch" atts,
|
|
|
|
|
parameter = nil,
|
2005-09-13 20:15:00 +00:00
|
|
|
|
type_ = NONE,
|
|
|
|
|
taggedValue = getTagVal trees}
|
2005-09-09 14:58:20 +00:00
|
|
|
|
|"UML:FinalState" =>
|
2005-09-12 20:13:23 +00:00
|
|
|
|
XMI.FinalState{
|
|
|
|
|
xmiid=xmiid,name=name,isSpecification=isSpecification,
|
2005-09-13 20:15:00 +00:00
|
|
|
|
stereotype = getStereo trees,
|
2005-09-12 20:13:23 +00:00
|
|
|
|
entry = getEntry trees,
|
2005-09-09 14:58:20 +00:00
|
|
|
|
exit = NONE,
|
|
|
|
|
doActivity = NONE,
|
2005-09-13 20:15:00 +00:00
|
|
|
|
outgoing = getOutgoing trees,incoming = getIncoming trees,
|
|
|
|
|
taggedValue = getTagVal trees}
|
2005-09-09 14:58:20 +00:00
|
|
|
|
|"UML:SyncState" =>
|
|
|
|
|
XMI.SyncState{
|
2005-09-12 20:13:23 +00:00
|
|
|
|
xmiid=xmiid,name=name,isSpecification=isSpecification,
|
2005-09-13 20:15:00 +00:00
|
|
|
|
stereotype = getStereo trees,
|
2005-09-09 14:58:20 +00:00
|
|
|
|
bound = 0,
|
2005-09-13 20:15:00 +00:00
|
|
|
|
outgoing = getOutgoing trees,incoming = getIncoming trees,
|
|
|
|
|
taggedValue = getTagVal trees}
|
2005-09-08 17:00:46 +00:00
|
|
|
|
|
2005-09-09 14:58:20 +00:00
|
|
|
|
| _ => raise IllFormed ("in mkState: Unknown State Vertex.")
|
2005-09-08 17:00:46 +00:00
|
|
|
|
|
2005-09-09 14:58:20 +00:00
|
|
|
|
end
|
2005-09-08 17:00:46 +00:00
|
|
|
|
|
2005-09-12 20:13:23 +00:00
|
|
|
|
|
2005-09-09 14:58:20 +00:00
|
|
|
|
and mkStateMachine tree =
|
2005-09-08 17:00:46 +00:00
|
|
|
|
let fun f atts trees = XMI.mk_StateMachine
|
2005-09-12 20:13:23 +00:00
|
|
|
|
{isSpecification = getBoolAtt "isSpecification" atts,
|
2005-09-08 17:00:46 +00:00
|
|
|
|
xmiid = getXmiId atts,
|
|
|
|
|
contextxmiid = (getXmiIdref o XmlTree.attributes_of o hd o
|
|
|
|
|
XmlTree.children_of o
|
|
|
|
|
(XmlTree.find "UML:StateMachine.context"))
|
|
|
|
|
(trees),
|
|
|
|
|
top = (hd o (map mkState) o XmlTree.children_of o
|
|
|
|
|
(XmlTree.find "UML:StateMachine.top"))
|
|
|
|
|
(trees),
|
|
|
|
|
transitions = ((map mkTransition) o XmlTree.children_of o
|
|
|
|
|
(XmlTree.find "UML:StateMachine.transitions"))
|
|
|
|
|
(trees)}
|
|
|
|
|
in XmlTree.apply_on "UML:StateMachine" f tree
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
2005-09-07 17:02:47 +00:00
|
|
|
|
fun mkActivityGraph tree =
|
2005-09-08 10:27:14 +00:00
|
|
|
|
let fun f atts trees = XMI.mk_ActivityGraph
|
2005-09-12 20:13:23 +00:00
|
|
|
|
{isSpecification = getBoolAtt "isSpecification" atts,
|
2005-09-08 17:00:46 +00:00
|
|
|
|
xmiid = getXmiId atts,
|
|
|
|
|
contextxmiid = (getXmiIdref o XmlTree.attributes_of o hd o
|
|
|
|
|
XmlTree.children_of o
|
|
|
|
|
(XmlTree.find "UML:StateMachine.context"))
|
|
|
|
|
(trees),
|
|
|
|
|
top = (hd o (map mkState) o XmlTree.children_of o
|
|
|
|
|
(XmlTree.find "UML:StateMachine.top"))
|
|
|
|
|
(trees),
|
|
|
|
|
transitions = ((map mkTransition) o XmlTree.children_of o
|
|
|
|
|
(XmlTree.find "UML:StateMachine.transitions"))
|
2005-09-09 14:58:20 +00:00
|
|
|
|
(trees),
|
|
|
|
|
partition = nil}
|
2005-09-08 10:27:14 +00:00
|
|
|
|
|
2005-09-07 17:02:47 +00:00
|
|
|
|
in XmlTree.apply_on "UML:ActivityGraph" f tree
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
2005-09-08 17:00:46 +00:00
|
|
|
|
|
2005-08-20 18:42:39 +00:00
|
|
|
|
fun mkPackage tree =
|
|
|
|
|
(if XmlTree.tagname_of tree = "UML:Model" orelse
|
|
|
|
|
XmlTree.tagname_of tree = "UML:Package" then
|
|
|
|
|
let val trees = XmlTree.skip "UML:Namespace.ownedElement"
|
|
|
|
|
((hd o XmlTree.children_of) tree)
|
|
|
|
|
val atts = XmlTree.attributes_of tree in
|
2005-09-08 17:00:46 +00:00
|
|
|
|
XMI.Package { xmiid = getXmiId atts,
|
2005-08-20 18:42:39 +00:00
|
|
|
|
name = getName atts,
|
|
|
|
|
visibility = getVisibility atts,
|
|
|
|
|
packages = (map mkPackage
|
|
|
|
|
(filterPackages trees)),
|
|
|
|
|
classifiers = (map mkClassifier
|
|
|
|
|
(filterClassifiers trees)),
|
|
|
|
|
associations = getAssociations trees,
|
|
|
|
|
generalizations = (map mkGeneralization
|
|
|
|
|
(XmlTree.filter "UML:Generalization"
|
|
|
|
|
trees)),
|
|
|
|
|
constraints = map mkConstraint
|
2005-09-07 17:02:47 +00:00
|
|
|
|
(filterConstraints trees),
|
2005-09-08 17:00:46 +00:00
|
|
|
|
state_machines = nil,
|
|
|
|
|
activity_graphs = nil
|
2005-09-07 17:02:47 +00:00
|
|
|
|
}
|
2005-08-18 16:18:28 +00:00
|
|
|
|
end
|
2005-08-20 18:42:39 +00:00
|
|
|
|
else raise IllFormed "did not find a UML:Model or UML: Package")
|
2005-08-23 09:13:15 +00:00
|
|
|
|
handle XmlTree.IllFormed msg => raise IllFormed ("in mkPackage: "^msg)
|
2005-08-20 18:42:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fun mkXmiContent tree =
|
|
|
|
|
let fun f atts trees =
|
|
|
|
|
{ packages = (map mkPackage (filterPackages trees)),
|
|
|
|
|
constraints = (map mkConstraint (filterConstraints trees)),
|
|
|
|
|
classifiers = (map mkClassifier (filterClassifiers trees)),
|
|
|
|
|
stereotypes = (map mkStereotype (filterStereotypes trees)),
|
2005-09-08 17:00:46 +00:00
|
|
|
|
variable_declarations = map mkVariableDec (filterVariableDecs trees),
|
|
|
|
|
activity_graphs = map mkActivityGraph(filterActivityGraphs trees),
|
|
|
|
|
state_machines = map mkStateMachine (filterStateMachines trees)}
|
2005-08-20 20:50:18 +00:00
|
|
|
|
in XmlTree.apply_on "XMI.content" f tree
|
2005-08-23 09:13:15 +00:00
|
|
|
|
handle XmlTree.IllFormed msg => raise IllFormed ("in mkXmiContent: "^msg)
|
2005-08-20 18:42:39 +00:00
|
|
|
|
end
|
|
|
|
|
|
2005-08-17 15:45:10 +00:00
|
|
|
|
|
2005-09-08 17:00:46 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val emptyXmiContent = { packages = nil,
|
|
|
|
|
constraints = nil,
|
|
|
|
|
classifiers = nil,
|
|
|
|
|
stereotypes = nil,
|
|
|
|
|
variable_declarations = nil,
|
|
|
|
|
activity_graphs = nil,
|
|
|
|
|
state_machines = nil}
|
2005-08-20 20:50:18 +00:00
|
|
|
|
|
|
|
|
|
fun findXmiContent tree = valOf (XmlTree.dfs "XMI.content" tree)
|
|
|
|
|
handle Option => raise IllFormed "in findXmiContent: did not find XMI.content"
|
2005-08-17 15:45:10 +00:00
|
|
|
|
|
2005-08-20 20:50:18 +00:00
|
|
|
|
fun readFile f = (mkXmiContent o findXmiContent o ParseXmlTree.readFile) f
|
2005-08-23 08:03:09 +00:00
|
|
|
|
handle XmlTree.IllFormed msg => (print ("Warning: "^msg^"\n"); emptyXmiContent)
|
2005-08-23 09:13:15 +00:00
|
|
|
|
| IllFormed msg => (print ("Warning: "^msg^"\n"); emptyXmiContent)
|
2005-08-17 15:45:10 +00:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|