2005-09-14 16:51:46 +00:00
|
|
|
(*****************************************************************************
|
2007-07-04 06:41:30 +00:00
|
|
|
* su4sml --- a SML repository for managing (Secure)UML/OCL models
|
|
|
|
* http://projects.brucker.ch/su4sml/
|
2005-09-14 16:51:46 +00:00
|
|
|
*
|
2007-07-04 06:41:30 +00:00
|
|
|
* xmi_idtable.sml ---
|
|
|
|
* This file is part of su4sml.
|
|
|
|
*
|
|
|
|
* Copyright (c) 2005-2007, ETH Zurich, Switzerland
|
|
|
|
*
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions are
|
|
|
|
* met:
|
|
|
|
*
|
|
|
|
* * Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
*
|
|
|
|
* * Redistributions in binary form must reproduce the above
|
|
|
|
* copyright notice, this list of conditions and the following
|
|
|
|
* disclaimer in the documentation and/or other materials provided
|
|
|
|
* with the distribution.
|
|
|
|
*
|
|
|
|
* * Neither the name of the copyright holders nor the names of its
|
|
|
|
* contributors may be used to endorse or promote products derived
|
|
|
|
* from this software without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
2005-09-14 16:51:46 +00:00
|
|
|
******************************************************************************)
|
2007-07-04 06:41:30 +00:00
|
|
|
(* $Id$ *)
|
2005-09-14 16:51:46 +00:00
|
|
|
|
|
|
|
structure Xmi_IDTable =
|
|
|
|
struct
|
2005-09-15 13:33:06 +00:00
|
|
|
open library
|
2005-09-14 16:51:46 +00:00
|
|
|
|
|
|
|
datatype HashTableEntry = Package of Rep_OclType.Path
|
|
|
|
| Type of (Rep_OclType.OclType *
|
2005-09-15 13:33:59 +00:00
|
|
|
(XMI.AssociationEnd list) *
|
2005-09-19 16:03:43 +00:00
|
|
|
XMI.Classifier *
|
|
|
|
(XMI.ActivityGraph list))
|
2005-09-14 16:51:46 +00:00
|
|
|
| Generalization of (string * string)
|
|
|
|
| Constraint of XMI.Constraint
|
|
|
|
| Stereotype of string
|
|
|
|
| Variable of XMI.VariableDeclaration
|
|
|
|
| Attribute of Rep_OclType.Path
|
|
|
|
| Operation of Rep_OclType.Path
|
2006-05-09 13:17:45 +00:00
|
|
|
| AssociationEnd of XMI.AssociationEnd
|
2005-09-20 13:26:26 +00:00
|
|
|
| State of XMI.StateVertex
|
|
|
|
| Transition of XMI.Transition
|
2005-09-21 14:17:47 +00:00
|
|
|
| Dependency of XMI.Dependency
|
2005-09-21 16:11:45 +00:00
|
|
|
| TagDefinition of string
|
2005-10-05 17:18:41 +00:00
|
|
|
| ClassifierInState of string
|
2005-11-11 16:15:47 +00:00
|
|
|
| Event of XMI.Event
|
|
|
|
|
2005-09-21 16:11:45 +00:00
|
|
|
fun find_tagdefinition t xmiid =
|
|
|
|
(case valOf (HashTable.find t xmiid)
|
|
|
|
of TagDefinition x => x
|
|
|
|
| _ => raise Option)
|
2007-02-05 17:44:37 +00:00
|
|
|
handle Option => error ("expected TagDefinition "^xmiid^" in table")
|
2005-09-20 13:26:26 +00:00
|
|
|
|
|
|
|
fun find_state t xmiid =
|
|
|
|
(case valOf (HashTable.find t xmiid)
|
|
|
|
of State x => x
|
|
|
|
| _ => raise Option)
|
2007-02-05 17:44:37 +00:00
|
|
|
handle Option => error ("expected State "^xmiid^" in table")
|
2005-09-20 13:26:26 +00:00
|
|
|
|
2005-11-11 16:15:47 +00:00
|
|
|
fun find_event t xmiid =
|
|
|
|
(case valOf (HashTable.find t xmiid)
|
|
|
|
of Event x => x
|
|
|
|
| _ => raise Option)
|
2007-02-05 17:44:37 +00:00
|
|
|
handle Option => error ("expected Event "^xmiid^" in table")
|
2005-11-11 16:15:47 +00:00
|
|
|
|
2005-09-20 13:26:26 +00:00
|
|
|
fun find_transition t xmiid =
|
|
|
|
(case valOf (HashTable.find t xmiid)
|
|
|
|
of Transition x => x
|
|
|
|
| _ => raise Option)
|
2007-02-05 17:44:37 +00:00
|
|
|
handle Option => error ("expected Transition "^xmiid^" in table")
|
2005-09-14 16:51:46 +00:00
|
|
|
|
2005-09-21 14:17:47 +00:00
|
|
|
fun find_dependency t xmiid =
|
|
|
|
(case valOf (HashTable.find t xmiid)
|
|
|
|
of Dependency x => x
|
|
|
|
| _ => raise Option)
|
2007-02-05 17:44:37 +00:00
|
|
|
handle Option => error ("expected Dependency "^xmiid^" in table")
|
2005-09-21 14:17:47 +00:00
|
|
|
|
2005-09-14 16:51:46 +00:00
|
|
|
fun find_generalization t xmiid =
|
|
|
|
(case valOf (HashTable.find t xmiid)
|
|
|
|
of Generalization x => x
|
|
|
|
| _ => raise Option)
|
2007-02-05 17:44:37 +00:00
|
|
|
handle Option => error ("expected Generalization "^xmiid^" in table")
|
2005-09-14 16:51:46 +00:00
|
|
|
|
|
|
|
fun find_stereotype t xmiid =
|
|
|
|
(case valOf (HashTable.find t xmiid)
|
|
|
|
of Stereotype x => x
|
|
|
|
| _ => raise Option)
|
2007-02-05 17:44:37 +00:00
|
|
|
handle Option => error ("expected Stereotype "^xmiid^" in table")
|
2005-09-14 16:51:46 +00:00
|
|
|
|
|
|
|
fun find_attribute t xmiid =
|
|
|
|
(case valOf (HashTable.find t xmiid)
|
|
|
|
of Attribute x => x
|
|
|
|
| _ => raise Option)
|
2007-02-05 17:44:37 +00:00
|
|
|
handle Option => error ("expected Attribute "^xmiid^" in table")
|
2005-09-14 16:51:46 +00:00
|
|
|
|
|
|
|
fun find_operation t xmiid =
|
|
|
|
(case valOf (HashTable.find t xmiid)
|
|
|
|
of Operation x => x
|
|
|
|
| _ => raise Option)
|
2007-02-05 17:44:37 +00:00
|
|
|
handle Option => error ("expected Operation "^xmiid^" in table")
|
2005-09-14 16:51:46 +00:00
|
|
|
|
|
|
|
fun find_type t xmiid =
|
|
|
|
(case valOf (HashTable.find t xmiid)
|
|
|
|
of Type x => x
|
|
|
|
| _ => raise Option)
|
2007-02-05 17:44:37 +00:00
|
|
|
handle Option => error ("expected Type "^xmiid^" in table (find_type)")
|
2005-09-14 16:51:46 +00:00
|
|
|
|
|
|
|
fun find_aends t xmiid =
|
|
|
|
(case valOf (HashTable.find t xmiid)
|
2005-09-19 16:03:43 +00:00
|
|
|
of (Type (c,xs,_,_)) => xs
|
2005-09-14 16:51:46 +00:00
|
|
|
| _ => raise Option)
|
2007-02-05 17:44:37 +00:00
|
|
|
handle Option => error ("expected Type "^xmiid^" in table (find_aends)")
|
2005-09-14 16:51:46 +00:00
|
|
|
|
|
|
|
fun find_variable_dec t xmiid =
|
|
|
|
(case valOf (HashTable.find t xmiid)
|
|
|
|
of Variable x => x
|
|
|
|
| _ => raise Option)
|
2007-02-05 17:44:37 +00:00
|
|
|
handle Option => error ("expected VariableDeclaration "^xmiid^" in table")
|
2005-09-14 16:51:46 +00:00
|
|
|
|
|
|
|
fun find_parent t xmiid = #2 (find_generalization t xmiid)
|
|
|
|
|
|
|
|
fun find_package t xmiid =
|
|
|
|
(case valOf (HashTable.find t xmiid)
|
|
|
|
of Package path => path
|
|
|
|
| _ => raise Option)
|
2007-02-05 17:44:37 +00:00
|
|
|
handle Option => error ("expected Path "^xmiid^" in table")
|
2005-09-14 16:51:46 +00:00
|
|
|
|
|
|
|
fun path_of_classifier (Rep_OclType.Classifier x) = x
|
2007-02-05 17:44:37 +00:00
|
|
|
| path_of_classifier _ = error ("path_of_classifier called on non-Classifier argument")
|
2005-09-14 16:51:46 +00:00
|
|
|
|
|
|
|
fun find_constraint t xmiid =
|
|
|
|
(case valOf (HashTable.find t xmiid)
|
|
|
|
of Constraint c => c
|
|
|
|
| _ => raise Option)
|
2007-02-05 17:44:37 +00:00
|
|
|
handle Option => error ("expected Constraint "^xmiid^" in table")
|
2005-09-14 16:51:46 +00:00
|
|
|
|
|
|
|
fun find_associationend t xmiid =
|
|
|
|
(case valOf (HashTable.find t xmiid)
|
2006-05-09 13:17:45 +00:00
|
|
|
of AssociationEnd ae => ae
|
2005-09-14 16:51:46 +00:00
|
|
|
| _ => raise Option)
|
2007-02-05 17:44:37 +00:00
|
|
|
handle Option => error ("expected AssociationEnd "^xmiid^" in table")
|
2005-09-14 16:51:46 +00:00
|
|
|
|
2006-04-07 14:35:12 +00:00
|
|
|
|
|
|
|
fun filter_exists t cs =
|
|
|
|
filter (fn x => Option.isSome (HashTable.find t x)) cs
|
|
|
|
|
2005-09-14 16:51:46 +00:00
|
|
|
fun filter_precondition t cs
|
|
|
|
= filter (fn x => let val constraint = find_constraint t x
|
|
|
|
val name = #name constraint
|
|
|
|
val constr_type_ref = #constraint_type constraint
|
|
|
|
val constr_type_name = find_stereotype t constr_type_ref
|
|
|
|
in
|
|
|
|
constr_type_name = "pre"
|
|
|
|
end) cs
|
|
|
|
|
|
|
|
fun filter_postcondition t cs
|
|
|
|
= filter (fn x => let val constraint = find_constraint t x
|
|
|
|
val name = #name constraint
|
|
|
|
val constr_type_ref = #constraint_type constraint
|
|
|
|
val constr_type_name = find_stereotype t constr_type_ref
|
|
|
|
in
|
|
|
|
constr_type_name = "post"
|
|
|
|
end) cs
|
|
|
|
|
2005-11-02 15:23:23 +00:00
|
|
|
fun filter_bodyconstraint t cs
|
|
|
|
= filter (fn x => let val constraint = find_constraint t x
|
|
|
|
val name = #name constraint
|
|
|
|
val constr_type_ref = #constraint_type constraint
|
|
|
|
val constr_type_name = find_stereotype t constr_type_ref
|
|
|
|
in
|
|
|
|
constr_type_name = "body"
|
|
|
|
end) cs
|
|
|
|
|
2005-10-05 17:18:41 +00:00
|
|
|
|
2005-09-15 13:33:59 +00:00
|
|
|
fun find_classifier t xmiid =
|
|
|
|
(case valOf (HashTable.find t xmiid)
|
2005-09-19 16:03:43 +00:00
|
|
|
of Type (_,_,c,_) => c
|
2005-09-15 13:33:59 +00:00
|
|
|
| _ => raise Option)
|
2007-02-05 17:44:37 +00:00
|
|
|
handle Option => error ("expected Classifier "^xmiid^" in table (in find_classifer)")
|
2005-09-19 16:03:43 +00:00
|
|
|
|
2005-10-05 17:18:41 +00:00
|
|
|
fun find_classifierInState_classifier t cis_id =
|
|
|
|
(case valOf (HashTable.find t cis_id)
|
|
|
|
of ClassifierInState c => find_classifier t c
|
2006-04-07 12:04:18 +00:00
|
|
|
| Type (_,_,c,_) => c
|
|
|
|
| _ => raise Option)
|
2007-02-05 17:44:37 +00:00
|
|
|
handle Option => error ("expected ClassifierInState "
|
2005-10-05 17:18:41 +00:00
|
|
|
^cis_id^" in table")
|
|
|
|
|
2005-09-19 16:03:43 +00:00
|
|
|
fun find_activity_graph_of t xmiid =
|
|
|
|
(case valOf (HashTable.find t xmiid)
|
|
|
|
of Type (_,_,_,ag) => ag
|
|
|
|
| _ => raise Option)
|
2007-02-05 17:44:37 +00:00
|
|
|
handle Option => error ("expected Classifier "^xmiid^" in table (in find_activity_graph_of)")
|
2005-09-19 16:03:43 +00:00
|
|
|
|
2005-09-14 16:51:46 +00:00
|
|
|
|
|
|
|
fun find_classifier_type t xmiid
|
2005-09-19 16:03:43 +00:00
|
|
|
= let val ocltype = case valOf (HashTable.find t xmiid) of (Type (x,xs,_,_)) => x
|
2005-09-14 16:51:46 +00:00
|
|
|
| _ => raise Option
|
|
|
|
in
|
|
|
|
case ocltype of Rep_OclType.Integer => ocltype
|
|
|
|
| Rep_OclType.String => ocltype
|
|
|
|
| Rep_OclType.Real => ocltype
|
|
|
|
| Rep_OclType.Boolean => ocltype
|
|
|
|
| Rep_OclType.Classifier x => ocltype
|
|
|
|
| Rep_OclType.OclVoid => ocltype
|
|
|
|
| Rep_OclType.OclAny => ocltype
|
|
|
|
| Rep_OclType.DummyT => ocltype
|
|
|
|
| Rep_OclType.Collection (Rep_OclType.Classifier [x]) => Rep_OclType.Collection (find_classifier_type t x)
|
|
|
|
| Rep_OclType.Sequence (Rep_OclType.Classifier [x]) => Rep_OclType.Sequence (find_classifier_type t x)
|
|
|
|
| Rep_OclType.Set (Rep_OclType.Classifier [x]) => Rep_OclType.Set (find_classifier_type t x)
|
|
|
|
| Rep_OclType.Bag (Rep_OclType.Classifier [x]) => Rep_OclType.Bag (find_classifier_type t x)
|
|
|
|
| Rep_OclType.OrderedSet (Rep_OclType.Classifier [x]) => Rep_OclType.OrderedSet (find_classifier_type t x)
|
2007-02-05 17:44:37 +00:00
|
|
|
| _ => error ("unexpected Classifier-Type "^xmiid^" in table")
|
2005-09-14 16:51:46 +00:00
|
|
|
end
|
2007-02-05 17:44:37 +00:00
|
|
|
handle Option => error ("expected Classifier "^xmiid^" in table (in find_classifier_type)")
|
2005-09-14 16:51:46 +00:00
|
|
|
|
|
|
|
|
|
|
|
fun insert_constraint table (c:XMI.Constraint) =
|
|
|
|
HashTable.insert table (#xmiid c, Constraint c)
|
|
|
|
|
|
|
|
fun insert_variable_dec table (v:XMI.VariableDeclaration) =
|
|
|
|
HashTable.insert table (#xmiid v, Variable v)
|
|
|
|
|
|
|
|
fun insert_stereotype table (s:XMI.Stereotype) =
|
|
|
|
HashTable.insert table (#xmiid s, Stereotype (#name s))
|
|
|
|
|
|
|
|
fun insert_generalization table (g:XMI.Generalization) =
|
|
|
|
HashTable.insert table (#xmiid g, Generalization (#child_id g, #parent_id g))
|
|
|
|
|
|
|
|
fun insert_attribute table path_prefix (a:XMI.Attribute) =
|
|
|
|
HashTable.insert table (#xmiid a, Attribute (path_prefix @ [#name a]))
|
|
|
|
|
|
|
|
fun insert_operation table path_prefix (a:XMI.Operation) =
|
|
|
|
HashTable.insert table (#xmiid a, Operation (path_prefix @ [#name a]))
|
|
|
|
|
|
|
|
fun add_aend table xmiid (aend:Rep.associationend) = () (* FIX *)
|
|
|
|
|
2005-09-20 13:26:26 +00:00
|
|
|
fun insert_state table (XMI.CompositeState st) =
|
2005-09-22 12:02:31 +00:00
|
|
|
(List.app (insert_state table) (#subvertex st);
|
2005-09-20 13:26:26 +00:00
|
|
|
HashTable.insert table (#xmiid st, State (XMI.CompositeState st)))
|
|
|
|
| insert_state table (XMI.SubactivityState st) =
|
2005-09-22 12:02:31 +00:00
|
|
|
(List.app (insert_state table) (#subvertex st);
|
2005-09-20 13:26:26 +00:00
|
|
|
HashTable.insert table (#xmiid st, State (XMI.SubactivityState st)))
|
|
|
|
| insert_state table (st:XMI.StateVertex) =
|
|
|
|
HashTable.insert table (XMI.state_xmiid_of st, State st)
|
|
|
|
|
2005-11-11 16:15:47 +00:00
|
|
|
fun insert_event table (e as XMI.CallEvent ev) =
|
|
|
|
HashTable.insert table (#xmiid ev, Event e)
|
2006-04-05 10:29:18 +00:00
|
|
|
| insert_event table (e as XMI.SignalEvent ev) =
|
|
|
|
HashTable.insert table (#xmiid ev, Event e)
|
2005-11-11 16:15:47 +00:00
|
|
|
|
2005-09-20 13:26:26 +00:00
|
|
|
fun insert_transition table (XMI.mk_Transition trans) =
|
|
|
|
HashTable.insert table (#xmiid trans, Transition (XMI.mk_Transition trans))
|
|
|
|
|
2005-09-19 16:03:43 +00:00
|
|
|
fun insert_activity_graph table (XMI.mk_ActivityGraph ag) =
|
|
|
|
let val context = #contextxmiid ag
|
|
|
|
in
|
|
|
|
(case valOf (HashTable.find table context)
|
|
|
|
of (Type (c,xs,aes,ags)) => HashTable.insert
|
|
|
|
table (context, Type (c,xs,aes,
|
|
|
|
XMI.mk_ActivityGraph ag::ags))
|
|
|
|
| _ => raise Option)
|
2007-02-05 17:44:37 +00:00
|
|
|
handle Option => error ("expected Type "^context^" in table (insert_activity_graph)");
|
2005-09-22 12:02:31 +00:00
|
|
|
List.app (insert_transition table) (#transitions ag);
|
2005-09-20 13:26:26 +00:00
|
|
|
insert_state table (#top ag)
|
2005-09-19 16:03:43 +00:00
|
|
|
end
|
|
|
|
|
2005-09-21 14:17:47 +00:00
|
|
|
fun insert_dependency table dep =
|
|
|
|
HashTable.insert table (#xmiid dep, Dependency dep)
|
2005-09-14 16:51:46 +00:00
|
|
|
|
2005-09-21 16:11:45 +00:00
|
|
|
fun insert_tagdefinition table (td:XMI.TagDefinition) =
|
|
|
|
HashTable.insert table (#xmiid td, TagDefinition (#name td))
|
|
|
|
|
2005-10-05 17:18:41 +00:00
|
|
|
fun insert_classifierInState table cls_id cis_id =
|
|
|
|
HashTable.insert table (cis_id,ClassifierInState cls_id)
|
|
|
|
|
2005-09-14 16:51:46 +00:00
|
|
|
fun insert_classifier table package_prefix class =
|
|
|
|
let val id = XMI.classifier_xmiid_of class
|
|
|
|
val name = XMI.classifier_name_of class
|
|
|
|
val path = package_prefix @ [name]
|
|
|
|
val ocltype = if (package_prefix = ["oclLib"]
|
|
|
|
orelse package_prefix = ["UML_OCL"])
|
|
|
|
then if name = "Integer" then Rep_OclType.Integer
|
|
|
|
else if name = "Boolean" then Rep_OclType.Boolean
|
|
|
|
else if name = "String" then Rep_OclType.String
|
|
|
|
else if name = "Real" then Rep_OclType.Real
|
|
|
|
else if name = "OclVoid" then Rep_OclType.OclVoid
|
2006-02-13 12:11:44 +00:00
|
|
|
(* this shouldn't be necessary: *)
|
|
|
|
else if name = "Void" then Rep_OclType.OclVoid
|
2005-09-14 16:51:46 +00:00
|
|
|
else if name = "OclAny" then Rep_OclType.OclAny
|
|
|
|
(* now this is really ugly... *)
|
|
|
|
else if String.isPrefix "Collection(" name then Rep_OclType.Collection (Rep_OclType.Classifier [XMI.classifier_elementtype_of class])
|
|
|
|
else if String.isPrefix "Sequence(" name then Rep_OclType.Sequence (Rep_OclType.Classifier [XMI.classifier_elementtype_of class])
|
|
|
|
else if String.isPrefix "Set(" name then Rep_OclType.Set (Rep_OclType.Classifier [XMI.classifier_elementtype_of class])
|
|
|
|
else if String.isPrefix "Bag(" name then Rep_OclType.Bag (Rep_OclType.Classifier [XMI.classifier_elementtype_of class])
|
|
|
|
else if String.isPrefix "OrderedSet(" name then Rep_OclType.OrderedSet (Rep_OclType.Classifier [XMI.classifier_elementtype_of class])
|
2007-02-05 17:44:37 +00:00
|
|
|
else error ("didn't recognize ocltype "^name)
|
2005-09-14 16:51:46 +00:00
|
|
|
else Rep_OclType.Classifier path
|
|
|
|
(* This function is called before the associations are handled, *)
|
|
|
|
(* so we do not have to take care of them now... *)
|
|
|
|
val aends = nil
|
2005-09-19 16:03:43 +00:00
|
|
|
val ag = nil
|
2005-09-14 16:51:46 +00:00
|
|
|
in
|
2005-09-19 16:03:43 +00:00
|
|
|
HashTable.insert table (id,Type (ocltype,aends,class,ag));
|
2005-09-14 16:51:46 +00:00
|
|
|
case class
|
2005-09-22 12:02:31 +00:00
|
|
|
of XMI.Class c => (List.app (insert_attribute table path) (#attributes c);
|
2005-10-05 17:18:41 +00:00
|
|
|
List.app (insert_operation table path) (#operations c);
|
|
|
|
List.app (insert_classifierInState table id) (#classifierInState c);
|
|
|
|
())
|
2005-09-22 12:02:31 +00:00
|
|
|
| XMI.Primitive c => (List.app (insert_operation table path) (#operations c); ())
|
|
|
|
| XMI.Enumeration c => (List.app (insert_operation table path) (#operations c); ())
|
|
|
|
| XMI.Interface c => (List.app (insert_operation table path) (#operations c); ())
|
|
|
|
| XMI.Collection c => (List.app (insert_operation table path) (#operations c); ())
|
|
|
|
| XMI.Sequence c => (List.app (insert_operation table path) (#operations c); ())
|
|
|
|
| XMI.Set c => (List.app (insert_operation table path) (#operations c); ())
|
|
|
|
| XMI.Bag c => (List.app (insert_operation table path) (#operations c); ())
|
|
|
|
| XMI.OrderedSet c => (List.app (insert_operation table path) (#operations c); ())
|
2005-09-14 16:51:46 +00:00
|
|
|
| _ => ()
|
|
|
|
end
|
2006-02-13 12:11:44 +00:00
|
|
|
|
2005-09-21 16:11:45 +00:00
|
|
|
|
|
|
|
|
2005-09-15 10:55:49 +00:00
|
|
|
(* recursively insert mapping of xmi.id's to model elements into Hashtable *)
|
|
|
|
fun insert_package table package_prefix (XMI.Package p) =
|
|
|
|
let val full_name = package_prefix @ [#name p]
|
|
|
|
in
|
2005-09-22 12:02:31 +00:00
|
|
|
List.app (insert_generalization table) (#generalizations p);
|
|
|
|
List.app (insert_constraint table) (#constraints p);
|
|
|
|
List.app (insert_stereotype table) (#stereotypes p);
|
|
|
|
List.app (insert_classifier table full_name) (#classifiers p);
|
|
|
|
List.app (insert_package table full_name) (#packages p);
|
|
|
|
List.app (insert_activity_graph table) (#activity_graphs p);
|
|
|
|
List.app (insert_dependency table) (#dependencies p);
|
|
|
|
List.app (insert_tagdefinition table) (#tag_definitions p);
|
2005-11-11 16:15:47 +00:00
|
|
|
List.app (insert_event table) (#events p);
|
2005-09-15 10:55:49 +00:00
|
|
|
HashTable.insert table (#xmiid p,Package full_name)
|
|
|
|
end
|
|
|
|
|
|
|
|
(* We do not want the name of the model to be part of the package hierarchy, *)
|
|
|
|
(* therefore we handle the top-level model seperately *)
|
|
|
|
fun insert_model table (XMI.Package p) =
|
|
|
|
let val full_name = nil
|
|
|
|
in
|
2005-09-22 12:02:31 +00:00
|
|
|
List.app (insert_generalization table) (#generalizations p);
|
|
|
|
List.app (insert_constraint table) (#constraints p);
|
|
|
|
List.app (insert_stereotype table) (#stereotypes p);
|
|
|
|
List.app (insert_classifier table full_name) (#classifiers p);
|
|
|
|
List.app (insert_package table full_name) (#packages p);
|
|
|
|
List.app (insert_activity_graph table) (#activity_graphs p);
|
|
|
|
List.app (insert_dependency table) (#dependencies p);
|
|
|
|
List.app (insert_tagdefinition table) (#tag_definitions p);
|
2005-11-11 16:15:47 +00:00
|
|
|
List.app (insert_event table) (#events p);
|
2005-09-15 10:55:49 +00:00
|
|
|
HashTable.insert table (#xmiid p,Package full_name)
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2005-09-20 16:20:08 +00:00
|
|
|
fun initial_state_of table (XMI.mk_ActivityGraph ag) =
|
|
|
|
valOf (List.find (fn (XMI.PseudoState{kind,...}) => kind = XMI.initial
|
|
|
|
| _ => false)
|
|
|
|
(XMI.state_subvertices_of (#top ag)))
|
|
|
|
|
|
|
|
|
|
|
|
fun successor_states_of table (st:XMI.StateVertex) =
|
|
|
|
map ((find_state table) o XMI.transition_target_of o
|
|
|
|
(find_transition table))
|
2005-09-21 14:17:47 +00:00
|
|
|
(XMI.state_outgoing_trans_of st)
|
2005-09-21 16:40:24 +00:00
|
|
|
|
|
|
|
(* returns a list of tag-value pairs *)
|
|
|
|
fun class_taggedvalues_of table (XMI.Class c) =
|
|
|
|
map (fn x => (find_tagdefinition table (#tag_type x),#dataValue x))
|
|
|
|
(#taggedValue c)
|
2005-09-26 11:02:10 +00:00
|
|
|
| class_taggedvalues_of table (XMI.AssociationClass c) =
|
|
|
|
map (fn x => (find_tagdefinition table (#tag_type x),#dataValue x))
|
|
|
|
(#taggedValue c)
|
2007-02-28 12:33:33 +00:00
|
|
|
| class_taggedvalues_of table (XMI.Primitive c) =
|
|
|
|
map (fn x => (find_tagdefinition table (#tag_type x),#dataValue x))
|
|
|
|
(#taggedValue c)
|
2007-02-05 17:44:37 +00:00
|
|
|
| class_taggedvalues_of table _ = error "in class_taggedvalues_of: \
|
|
|
|
\argument doesn't support tagged values"
|
2005-09-26 11:02:10 +00:00
|
|
|
|
2005-09-21 16:40:24 +00:00
|
|
|
|
|
|
|
(* returns the value of the given tag *)
|
|
|
|
fun class_taggedvalue_of table tag (XMI.Class c) =
|
|
|
|
Option.map #2 ((List.find (fn (x,y) => x=tag))
|
|
|
|
(class_taggedvalues_of table (XMI.Class c)))
|
2005-09-26 11:02:10 +00:00
|
|
|
| class_taggedvalue_of table tag (XMI.AssociationClass c) =
|
|
|
|
Option.map #2 ((List.find (fn (x,y) => x=tag))
|
|
|
|
(class_taggedvalues_of table (XMI.AssociationClass c)))
|
2007-02-28 12:33:33 +00:00
|
|
|
| class_taggedvalue_of table tag (XMI.Primitive c) =
|
|
|
|
Option.map #2 ((List.find (fn (x,y) => x=tag))
|
|
|
|
(class_taggedvalues_of table (XMI.Primitive c)))
|
2007-02-05 17:44:37 +00:00
|
|
|
| class_taggedvalue_of table tag _ = error "in class_taggedvalues_of: \
|
|
|
|
\argument doesn't support tagged values"
|
2005-09-26 11:02:10 +00:00
|
|
|
|
|
|
|
|
2005-10-06 16:30:20 +00:00
|
|
|
(* returns a list of tag-value pairs *)
|
|
|
|
fun attribute_taggedvalues_of table (a:XMI.Attribute) =
|
|
|
|
map (fn x => (find_tagdefinition table (#tag_type x),#dataValue x))
|
|
|
|
(#taggedValue a)
|
|
|
|
|
|
|
|
|
|
|
|
(* returns the value of the given tag *)
|
|
|
|
fun attribute_taggedvalue_of table tag (a:XMI.Attribute) =
|
|
|
|
Option.map #2 ((List.find (fn (x,y) => x=tag))
|
|
|
|
(attribute_taggedvalues_of table a))
|
|
|
|
|
|
|
|
|
2005-09-27 11:18:26 +00:00
|
|
|
(* returns a list of tag-value pairs *)
|
|
|
|
fun state_taggedvalues_of table st =
|
|
|
|
map (fn x => (find_tagdefinition table (#tag_type x),#dataValue x))
|
|
|
|
(XMI.state_taggedValue_of st)
|
|
|
|
|
|
|
|
(* returns the value of the given tag *)
|
|
|
|
fun state_taggedvalue_of table tag st =
|
|
|
|
Option.map #2 ((List.find (fn (x,y) => x=tag))
|
|
|
|
(state_taggedvalues_of table st))
|
|
|
|
|
|
|
|
|
2005-09-28 16:55:59 +00:00
|
|
|
(* returns a list of tag-value pairs *)
|
|
|
|
fun package_taggedvalues_of table (XMI.Package p) =
|
|
|
|
map (fn x => (find_tagdefinition table (#tag_type x),#dataValue x))
|
|
|
|
(#taggedValue p)
|
|
|
|
|
|
|
|
(* returns the value of the given tag *)
|
|
|
|
fun package_taggedvalue_of table tag (XMI.Package p) =
|
|
|
|
Option.map #2 ((List.find (fn (x,y) => x=tag))
|
|
|
|
(package_taggedvalues_of table (XMI.Package p)))
|
|
|
|
|
|
|
|
|
2005-09-27 09:20:59 +00:00
|
|
|
(* check whether a class has the given stereotype *)
|
|
|
|
fun classifier_has_stereotype t st c =
|
|
|
|
List.exists (fn x => (find_stereotype t x) = st)
|
|
|
|
(XMI.classifier_stereotype_of c)
|
|
|
|
|
2006-05-08 12:44:07 +00:00
|
|
|
(**
|
|
|
|
* split an association into association ends, and put the association ends
|
|
|
|
* ends into the xmi.id table under the corresponding (i.e., opposite)
|
|
|
|
* classifier.
|
|
|
|
* 1. split the association into a list of two (or more) association ends
|
|
|
|
* 2. pair each association end with the participant_id's of all other
|
|
|
|
* association ends: when a class is a participant in an association,
|
|
|
|
* this association end is a feature of all _other_ participants in the
|
|
|
|
* association
|
|
|
|
* 3. insert the mapping xmi.id of class to association end into the
|
|
|
|
* hashtable
|
|
|
|
* 4. insert mapping xmi.id of association end to path into the hashtable
|
|
|
|
*)
|
2005-09-26 12:30:02 +00:00
|
|
|
fun transform_assocation t (assoc:XMI.Association) =
|
|
|
|
let val aends = #connection assoc
|
|
|
|
fun all_others x xs = List.filter
|
|
|
|
(fn (y:XMI.AssociationEnd) => y <> x) xs
|
|
|
|
fun pair_with ae aes =
|
|
|
|
map (fn (x:XMI.AssociationEnd) => (#participant_id x, ae)) aes
|
|
|
|
val mappings = List.concat (map (fn x => pair_with x (all_others x aends)) aends)
|
|
|
|
fun add_aend_to_type (id,ae) =
|
2006-04-07 13:45:04 +00:00
|
|
|
if not (Option.isSome (HashTable.find t id)) then () else
|
2005-09-26 12:30:02 +00:00
|
|
|
let val type_of_id = find_classifier_type t id
|
|
|
|
val cls_of_id = find_classifier t id
|
|
|
|
val aends_of_id = ae::(find_aends t id)
|
|
|
|
val ags_of_id = find_activity_graph_of t id
|
|
|
|
in
|
|
|
|
(HashTable.insert t (id,Type (type_of_id,aends_of_id,cls_of_id,ags_of_id));
|
2006-05-09 13:17:45 +00:00
|
|
|
HashTable.insert t (#xmiid ae, AssociationEnd ae))
|
2005-09-26 12:30:02 +00:00
|
|
|
end
|
|
|
|
in
|
2006-05-09 09:33:16 +00:00
|
|
|
List.app add_aend_to_type mappings
|
2005-09-26 12:30:02 +00:00
|
|
|
end
|
|
|
|
|
2006-05-08 12:44:07 +00:00
|
|
|
|
2006-05-09 09:33:16 +00:00
|
|
|
(* recursively transforms all associations in the package p. *)
|
2005-09-26 12:30:02 +00:00
|
|
|
fun transform_associations t (XMI.Package p) =
|
|
|
|
(List.app (transform_associations t) (#packages p);
|
2007-09-24 10:06:18 +00:00
|
|
|
List.app (transform_assocation t) (#associations p))
|
2005-09-14 16:51:46 +00:00
|
|
|
end
|