duplicate dummy node generated for associationclasses

git-svn-id: https://projects.brucker.ch/su4sml/svn/su4sml/trunk@6962 3260e6d1-4efc-4170-b0a7-36055960796d
This commit is contained in:
Martin Bill 2007-11-27 22:53:53 +00:00
parent 20cc35e774
commit 5323d2fd42
3 changed files with 44 additions and 18 deletions

View File

@ -205,7 +205,10 @@ val update_postcondition : (string option * Rep_OclTerm.OclTerm) list -> operat
val addInvariant : constraint -> Classifier -> Classifier
val addOperation : operation -> Classifier -> Classifier
exception InvalidArguments of string
end
structure Rep_Core : REP_CORE =
@ -319,6 +322,8 @@ datatype Classifier =
type transform_model = (Classifier list * association list)
exception InvalidArguments of string
(* convert an association end into the corresponding collection type *)
fun aend_to_attr_type ({name,aend_type,multiplicity,ordered,visibility,init}:associationend) =
case multiplicity of
@ -427,13 +432,14 @@ fun association_to_associationends (associations:association list) (self_type:Oc
let
val _ = trace function_calls "association_to_associationends\n"
val _ = trace function_arguments ("assoc: "^(string_of_path assoc)^"\n")
val (association::rest) = filter (fn {name,...} => name=assoc ) associations
val aends = if rest <> []
then
error ("in association_to_associationends: non-unique association name: "^
(string_of_path assoc))
else
#aends association
val _ = trace function_arguments "associations in list:\n"
val _ = map (trace function_arguments o (fn x => "association path: "^x^"\n") o
string_of_path o (fn {name,aends,aclass} => name)) associations
val association = List.filter (fn {name,aends,aclass} => name = assoc ) associations
val aends = case association of
[] => raise InvalidArguments "association_to_associationends: no association found\n"
| [{name,aends,aclass}] => aends
| _ => raise InvalidArguments "association_to_associationends: more than 1 association found\n"
val (aendsFiltered,aendsSelf) = List.partition (fn {aend_type,...} =>
aend_type <> self_type) aends
val aendsFiltered = if List.length aendsSelf > 1 then aendsFiltered@aendsSelf (* reflexiv *)
@ -457,7 +463,14 @@ fun associationends_of (all_associations:association list) (Class{name,associati
List.concat (map (association_to_associationends all_associations name) associations)
| associationends_of all_associations (AssociationClass{name,associations,association,...}) =
(* association only contains endpoints to the other, pure classes *)
List.concat (map (association_to_associationends all_associations name) (association::associations))
let
val assocs = if List.exists (fn x => x = association ) associations then
associations
else
association::associations
in
List.concat (map (association_to_associationends all_associations name) assocs)
end
| associationends_of all_associations (Primitive{name,associations,...}) =
List.concat (map (association_to_associationends all_associations name) associations)
| associationends_of _ _ = error ("in associationends_of: This classifier has no associationends") (*FIXME: or rather []? *)
@ -472,6 +485,7 @@ fun normalize (all_associations:association list) (C as (Class {name,parent,attr
let
val _ = trace function_calls "normalize: class\n"
val _ = trace function_arguments ("number of associations: " ^ (Int.toString (List.length associations )) ^ "\n")
val _ = map (trace function_arguments o (fn x => "association path: "^x^"\n") o string_of_path) associations
in
Class {name = name,
parent = parent (*,

View File

@ -475,7 +475,8 @@ fun transform_association_class_into_association (AssociationClass {name,associa
val (assoc,others) = split_on_association all_associations association
val assoc_path = association
val assoc_class_path = path_of_OclType name
val assoc_class_name = get_short_name assoc_class_path
val assoc_class_name = StringHandling.uncapitalize (get_short_name assoc_class_path)
(* Outdated: dummy added at Xmi_Parser.mkAssociationClass *)
val new_aend= {name = assoc_path@[assoc_class_name] (* FIXME: convention? *),
aend_type = name (* target of the association is the original AssociationClass *),
multiplicity = [],
@ -488,7 +489,8 @@ fun transform_association_class_into_association (AssociationClass {name,associa
aclass=NONE}
val modified_association = add_aend_to_and_update_association new_aend assoc
in
modified_association::others
(*modified_association::others*)
assoc::others
end
| transform_association_class_into_association (cls,_) = error ("in transform_association_class_into_association: only AssociationClass supported, but "^
(short_name_of cls)^" provided")
@ -663,12 +665,18 @@ fun split_n_ary_association (ac as {name,aends=[],aclass}:association):associati
| split_n_ary_association (ac as {name,aends,aclass}:association) =
(* We need to generate the pairs as well as the new names *)
let
val _ = trace function_calls "split_n_ary_associatio\n"
val _ = trace function_calls "split_n_ary_association\n"
val qualifier = get_qualifier name
(* FIXME: update the name paths of all references to the new names *)
fun to_association (a,b) = {name=qualifier@[name_of_aend a ^ (name_of_aend b)],
aends=[a,b],
aclass=aclass}
fun to_association (a,b) =
let
val a_part = StringHandling.uncapitalize (name_of_aend a)
val b_part = StringHandling.uncapitalize (name_of_aend b)
in
{name=qualifier@[a_part^"_"^b_part^"_binary_association"],
aends=[a,b],
aclass=aclass}
end
(* FIXME: reflexiv parts? *)
(* No dupplicates due to symmetry generated *)
fun pair source targets = map (fn x => (source,x)) targets
@ -677,6 +685,7 @@ fun split_n_ary_association (ac as {name,aends=[],aclass}:association):associati
| gen_pairs [x,y] = [(x,y)]
(* pair src with all parts and continue *)
| gen_pairs (src::rest) = pair src rest @ (gen_pairs rest)
val _ = print (string_of_path name^" has "^(Int.toString (List.length aends))^"aends\n")
val pairs = gen_pairs aends
val binary_associations = map to_association pairs
in
@ -722,7 +731,7 @@ fun transform_n_ary_associations ((classifiers,associations):transform_model):tr
(**
* Transformations on Classifiers and Associations
*)
fun transformClassifiers_ext (model:transform_model):transform_model =
fun transformClassifiers_ext (model:Rep_Core.transform_model):Rep_Core.transform_model =
transform_association_classes model |>> (* split an association classe into a class and an association*)
(* transform_qualifier |>>
transform_aggregation |>> *)

View File

@ -617,8 +617,11 @@ fun fix_associationend t (assoc_path:Rep_OclType.Path) (aend:XMI.AssociationEnd)
(StringHandling.uncapitalize o XMI.classifier_name_of o
find_classifier t) participant_id)
in
(* add the association to the participant *)
(HashTable.insert t (participant_id, Type (cls_type,assoc_path::assocs,assoc,cls,ags));
((if not (List.exists (fn x => x = assoc_path) assocs) then
(* add the association to the participant *)
(HashTable.insert t (participant_id, Type (cls_type,assoc_path::assocs,assoc,cls,ags)))
else
());
HashTable.insert t (#xmiid aend, AssociationEnd (List.concat [assoc_path, [name]], aend)))
end