more work...
git-svn-id: https://projects.brucker.ch/su4sml/svn/infsec-import/trunk/src/su4sml@4551 3260e6d1-4efc-4170-b0a7-36055960796d
This commit is contained in:
parent
9fb8dba9f1
commit
2e6e913e5c
|
@ -32,10 +32,14 @@ structure Base_Gcg = GCG_Core (Base_Cartridge)
|
|||
structure CSharp_Gcg = GCG_Core (CSharp_Cartridge(Base_Cartridge))
|
||||
|
||||
structure CSharpSecure_Gcg
|
||||
= GCG_Core (CSharp_Cartridge( ComponentUML_Cartridge( SecureUML_Cartridge(structure SuperCart=Base_Cartridge; structure D=ComponentUML))))
|
||||
= GCG_Core (CSharp_Cartridge( ComponentUML_Cartridge(Base_Cartridge)))
|
||||
|
||||
structure CSharp_NET1_Gcg
|
||||
= GCG_Core (CSharp_NET1_Cartridge(Base_Cartridge))
|
||||
|
||||
structure CSharpSecure_NET1_Gcg
|
||||
= GCG_Core (CSharp_NET1_Cartridge(ComponentUML_Cartridge(Base_Cartridge)))
|
||||
|
||||
structure CSharp_NET1_Gcg = GCG_Core (CSharp_NET1_Cartridge(Base_Cartridge));
|
||||
structure CSharpSecure_NET1_Gcg = GCG_Core (CSharp_NET1_Cartridge(SecureUML_Cartridge(structure SuperCart=Base_Cartridge; structure D=ComponentUML)));
|
||||
(*
|
||||
structure Java_Gcg = GCG_Core (Java_Cartridge(Base_Cartridge));
|
||||
structure JavaSecure_Gcg = GCG_Core (Java_Cartridge(SecureUML_Cartridge(Base_Cartridge)));
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
functor ComponentUML_Cartridge(SuperCart : SECUREUML_CARTRIDGE) : DESIGN_LANGUAGE_CARTRIDGE =
|
||||
functor ComponentUML_Cartridge(S : BASE_CARTRIDGE) : DESIGN_LANGUAGE_CARTRIDGE =
|
||||
struct
|
||||
|
||||
structure Design = ComponentUML
|
||||
structure SuperCart = SecureUML_Cartridge(structure SuperCart=S; structure D=ComponentUML)
|
||||
|
||||
structure Design = SuperCart.Security.Design
|
||||
open library
|
||||
|
||||
(* TODO: fill out *)
|
||||
type environment = { curPermissionList: SuperCart.Security.Permission list option,
|
||||
|
@ -34,62 +37,57 @@ fun curArgument (env : environment) = SuperCart.curArgument (unpack env)
|
|||
* Maybe sme of this should be moved to component_uml.sml...
|
||||
*)
|
||||
fun atomic_actions_from_context env =
|
||||
if Option.isSome(curAttribute env) then
|
||||
if Option.isSome (curAttribute env) then
|
||||
let fun make_action s =
|
||||
ComponentUML.SimpleAction (s,
|
||||
ComponentUMLResource.EntityAttribute
|
||||
(Option.valOf (curAttribute env)))
|
||||
ComponentUML.SimpleAction (s, ComponentUMLResource.EntityAttribute
|
||||
(Option.valOf (curAttribute env)))
|
||||
in [make_action "read", make_action "update"] end
|
||||
else if Option.isSome(curOperation env) then
|
||||
else if Option.isSome (curOperation env) then
|
||||
let fun make_action s =
|
||||
ComponentUML.SimpleAction (s,
|
||||
ComponentUMLResource.EntityMethod
|
||||
(Option.valOf (curOperation env)))
|
||||
ComponentUML.SimpleAction (s, ComponentUMLResource.EntityMethod
|
||||
(Option.valOf (curOperation env)))
|
||||
in [make_action "execute"] end
|
||||
else if Option.isSome(curClassifier env) then
|
||||
else if Option.isSome (curClassifier env) then
|
||||
let fun make_action s =
|
||||
ComponentUML.SimpleAction (s,
|
||||
ComponentUMLResource.Entity
|
||||
(Option.valOf (curClassifier env)))
|
||||
ComponentUML.SimpleAction (s, ComponentUMLResource.Entity
|
||||
(Option.valOf (curClassifier env)))
|
||||
in [make_action "create", make_action "delete"] end
|
||||
else []
|
||||
|
||||
else error "blubb"
|
||||
|
||||
(* FIX *)
|
||||
fun permissions_for_action env act = nil
|
||||
|
||||
fun permissions_for_action env act =
|
||||
List.filter (fn x => SuperCart.Security.permission_includes_action x act)
|
||||
(SuperCart.PermissionSet (unpack env))
|
||||
|
||||
(********** ADDING/MODIFYING VARIABLE SUBSTITUTIONS *****************************************)
|
||||
(* lookup environment -> string -> string
|
||||
* might override some lookup entries of the base cartridge
|
||||
*)
|
||||
|
||||
fun lookup (env:environment) "permission_name" =
|
||||
let val p = #curPermission env
|
||||
in case p of
|
||||
SOME x => #name x
|
||||
| NONE => SuperCart.lookup (unpack env) "permission_name"
|
||||
end
|
||||
(case #curPermission env of
|
||||
SOME x => #name x
|
||||
| NONE => SuperCart.lookup (unpack env) "permission_name")
|
||||
| lookup env s = SuperCart.lookup (unpack env) s
|
||||
|
||||
(********** ADDING IF-CONDITION TYPE *****************************************)
|
||||
(** no cartridge specific predicates are defined (yet). *)
|
||||
fun test env "first_permission" = let val p = #curPermission env
|
||||
in case p of
|
||||
SOME x => x = hd (Option.valOf (#curPermissionList env))
|
||||
| NONE => SuperCart.test (unpack env) "first_permission"
|
||||
end
|
||||
| test env "last_permission" = let val p = #curPermission env
|
||||
in case p of
|
||||
SOME x => x = List.last (Option.valOf (#curPermissionList env))
|
||||
| NONE => SuperCart.test (unpack env) "first_permission"
|
||||
end
|
||||
fun test env "first_permission" =
|
||||
(case #curPermission env of
|
||||
SOME x => x = hd (Option.valOf (#curPermissionList env))
|
||||
| NONE => SuperCart.test (unpack env) "first_permission" )
|
||||
| test env "last_permission" =
|
||||
(case #curPermission env of
|
||||
SOME x => x = List.last (Option.valOf (#curPermissionList env))
|
||||
| NONE => SuperCart.test (unpack env) "first_permission" )
|
||||
| test env s = SuperCart.test (unpack env) s
|
||||
|
||||
|
||||
(********** ADDING FOREACH TYPE **********************************************)
|
||||
|
||||
fun foreach_permission env name =
|
||||
let val action = List.find (fn x => ComponentUML.action_type_of x = name)
|
||||
(atomic_actions_from_context env)
|
||||
let val action = Option.valOf (List.find (fn x => ComponentUML.action_type_of x = name)
|
||||
(atomic_actions_from_context env))
|
||||
val permissions = permissions_for_action env action
|
||||
fun env_from_list_item c = { curPermissionList = SOME permissions,
|
||||
curPermission = SOME c,
|
||||
|
|
|
@ -33,12 +33,11 @@ structure Security:SECUREUML
|
|||
include BASE_CARTRIDGE where
|
||||
type Model = Rep.Classifier list * Security.Configuration
|
||||
|
||||
val curPermissionSet: environment -> Security.Permission list option
|
||||
val PermissionSet: environment -> Security.Permission list
|
||||
val curPermission : environment -> Security.Permission option
|
||||
val curRole : environment -> string option
|
||||
val curConstraint : environment -> Rep_OclTerm.OclTerm option
|
||||
|
||||
val isInPermission : Security.Design.Action -> Security.Permission -> bool
|
||||
|
||||
end
|
||||
|
||||
|
@ -58,18 +57,17 @@ structure Security = SecureUML(structure Design = D)
|
|||
type Model = Rep.Classifier list * Security.Configuration
|
||||
|
||||
type environment = { model : Model,
|
||||
curPermissionSet: Security.Permission list option,
|
||||
PermissionSet : Security.Permission list,
|
||||
curPermission : Security.Permission option,
|
||||
curRole : string option,
|
||||
curConstraint : Rep_OclTerm.OclTerm option,
|
||||
extension : SuperCart.environment }
|
||||
|
||||
fun curPermissionSet (env : environment) = (#curPermissionSet env)
|
||||
fun PermissionSet (env : environment) = (#PermissionSet env)
|
||||
fun curPermission (env : environment) = (#curPermission env)
|
||||
fun curRole (env : environment) = (#curRole env)
|
||||
fun curConstraint (env : environment) = (#curConstraint env)
|
||||
|
||||
fun curPermissionSet' (env : environment) = Option.valOf (#curPermissionSet env)
|
||||
fun curPermission' (env : environment) = Option.valOf (#curPermission env)
|
||||
fun curRole' (env : environment) = Option.valOf (#curRole env)
|
||||
fun curConstraint' (env : environment) = Option.valOf (#curConstraint env)
|
||||
|
@ -77,7 +75,7 @@ fun curConstraint' (env : environment) = Option.valOf (#curConstraint env)
|
|||
fun initEnv model = let val m = Security.parse model
|
||||
in
|
||||
{ model = m,
|
||||
curPermissionSet = SOME (#permissions (#2 m)),
|
||||
PermissionSet = (#permissions (#2 m)),
|
||||
curPermission = NONE,
|
||||
curRole = NONE,
|
||||
curConstraint = NONE,
|
||||
|
@ -90,7 +88,7 @@ fun unpack (env : environment) = #extension env
|
|||
(* pack : environment -> SuperCart.environment -> environment *)
|
||||
fun pack (env: environment) (new_env : SuperCart.environment)
|
||||
= { model = #model env,
|
||||
curPermissionSet = #curPermissionSet env,
|
||||
PermissionSet = #PermissionSet env,
|
||||
curPermission = #curPermission env,
|
||||
curRole = #curRole env,
|
||||
curConstraint = #curConstraint env,
|
||||
|
@ -104,11 +102,6 @@ fun curAttribute (env : environment) = SuperCart.curAttribute (unpack env)
|
|||
fun curOperation (env : environment) = SuperCart.curOperation (unpack env)
|
||||
fun curArgument (env : environment) = SuperCart.curArgument (unpack env)
|
||||
|
||||
fun is_contained_in a1 a2 = (a1 = a2) orelse
|
||||
List.exists (fn x=> x=true) ((List.map (is_contained_in a1) (D.subordinated_actions a2)))
|
||||
|
||||
|
||||
fun isInPermission a (p:Security.Permission) = List.exists (is_contained_in a) (#actions p)
|
||||
|
||||
fun name_of_role r = r
|
||||
|
||||
|
@ -124,12 +117,12 @@ fun lookup env "permission_name" = #name (curPermission' env)
|
|||
| lookup env s = SuperCart.lookup (unpack env) s
|
||||
|
||||
(********** ADDING IF-CONDITION TYPE *****************************************)
|
||||
fun test env "first_permission" = (curPermission' env = hd (curPermissionSet' env))
|
||||
fun test env "first_permission" = (curPermission' env = hd (PermissionSet env))
|
||||
| test env "first_role" = (curRole' env = hd (#roles (curPermission' env)))
|
||||
| test env "first_constraint" = (curConstraint' env
|
||||
= hd (#constraints (curPermission' env)))
|
||||
| test env "last_permission" = (curPermission' env
|
||||
= List.last (curPermissionSet' env))
|
||||
= List.last (PermissionSet env))
|
||||
| test env "last_role" = (curRole' env
|
||||
= List.last (#roles (curPermission' env)))
|
||||
| test env "last_constraint" = (curConstraint' env
|
||||
|
@ -141,7 +134,7 @@ fun test env "first_permission" = (curPermission' env = hd (curPermissionSet' en
|
|||
fun foreach_role env
|
||||
= let val roles = #roles (curPermission' env);
|
||||
fun env_from_list_item r ={ model = #model env,
|
||||
curPermissionSet = #curPermissionSet env,
|
||||
PermissionSet = #PermissionSet env,
|
||||
curPermission = #curPermission env,
|
||||
curRole = SOME r ,
|
||||
curConstraint = NONE,
|
||||
|
@ -153,7 +146,7 @@ fun foreach_role env
|
|||
fun foreach_constraint env
|
||||
= let val cons = #constraints (curPermission' env);
|
||||
fun env_from_list_item c ={ model = #model env,
|
||||
curPermissionSet = #curPermissionSet env,
|
||||
PermissionSet = #PermissionSet env,
|
||||
curPermission = #curPermission env,
|
||||
curRole = NONE ,
|
||||
curConstraint = SOME c,
|
||||
|
@ -163,9 +156,9 @@ fun foreach_constraint env
|
|||
end
|
||||
|
||||
fun foreach_permission env
|
||||
= let val perms = curPermissionSet' env
|
||||
= let val perms = PermissionSet env
|
||||
fun env_from_list_item p ={ model = #model env,
|
||||
curPermissionSet = #curPermissionSet env,
|
||||
PermissionSet = #PermissionSet env,
|
||||
curPermission = SOME p,
|
||||
curRole = NONE ,
|
||||
curConstraint = NONE ,
|
||||
|
|
|
@ -111,7 +111,7 @@
|
|||
)
|
||||
@nl @tab@tab {
|
||||
|
||||
@foreach permission_list
|
||||
@foreach executePermission_list
|
||||
@if first_permission
|
||||
@nl@tab@tab@tab
|
||||
MdsEngine.Assert(this, new string[] {
|
||||
|
@ -163,4 +163,4 @@
|
|||
@nl @tab }
|
||||
@end
|
||||
@end
|
||||
@nl} @// End
|
||||
@nl} @// End
|
||||
|
|
|
@ -48,12 +48,13 @@ struct
|
|||
open ComponentUMLResource
|
||||
(* val resource_types = ["Entity","EntityMethod","EntityAttribute"] *)
|
||||
|
||||
val action_stereotypes = ["dialect.entityaction","dialect.methodaction","dialect.attributeaction"]
|
||||
|
||||
val action_stereotypes = ["dialect.entityaction",
|
||||
"dialect.entitymethodaction",
|
||||
"dialect.entityattributeaction"]
|
||||
|
||||
(** The list of all attributes of an entity. *)
|
||||
fun entity_contained_attributes (Entity c)
|
||||
= map EntityAttribute (Rep.attributes_of c)
|
||||
fun entity_contained_attributes (Entity c) =
|
||||
map EntityAttribute (Rep.attributes_of c)
|
||||
| entity_contained_attributes _ = nil
|
||||
|
||||
(** the list of all methods of an entity *)
|
||||
|
@ -61,13 +62,13 @@ fun entity_contained_methods (Entity c) = map EntityMethod (Rep.operations_of c)
|
|||
| entity_contained_methods _ = nil
|
||||
|
||||
(** The list of all side-effect free methods of an entity. *)
|
||||
fun entity_contained_read_methods (Entity c)
|
||||
= map EntityMethod (List.filter #isQuery (Rep.operations_of c))
|
||||
fun entity_contained_read_methods (Entity c) =
|
||||
map EntityMethod (List.filter #isQuery (Rep.operations_of c))
|
||||
| entity_contained_read_methods _ = nil
|
||||
|
||||
(** The list of all methods with side-effects of an entity *)
|
||||
fun entity_contained_update_methods (Entity c)
|
||||
= map EntityMethod (List.filter (not o #isQuery) (Rep.operations_of c))
|
||||
fun entity_contained_update_methods (Entity c) =
|
||||
map EntityMethod (List.filter (not o #isQuery) (Rep.operations_of c))
|
||||
| entity_contained_update_methods _ = nil
|
||||
|
||||
(** The resources that are contained in the given resource. *)
|
||||
|
@ -93,24 +94,28 @@ fun parse_entity_action root att_name "create" =
|
|||
|
||||
(** parses an entity attribute action permission attribute. *)
|
||||
fun parse_attribute_action root name "read" =
|
||||
SimpleAction ("read",
|
||||
(EntityAttribute ((hd o List.filter (fn x => #name x = name))
|
||||
(SimpleAction ("read",
|
||||
(EntityAttribute ((hd o List.filter (fn x => #name x = name))
|
||||
(Rep.attributes_of root))))
|
||||
handle Empty => library.error "did not find attribute")
|
||||
| parse_attribute_action root name "update" =
|
||||
SimpleAction ("update",
|
||||
(EntityAttribute ((hd o List.filter (fn x => #name x = name))
|
||||
(Rep.attributes_of root))))
|
||||
( SimpleAction ("update",
|
||||
(EntityAttribute ((hd o List.filter (fn x => #name x = name))
|
||||
(Rep.attributes_of root))))
|
||||
handle Empty => library.error "did not find attribute")
|
||||
| parse_attribute_action root name "fullaccess" =
|
||||
CompositeAction ("fullaccess",
|
||||
(EntityAttribute ((hd o List.filter (fn x => #name x = name))
|
||||
(Rep.attributes_of root))))
|
||||
( CompositeAction ("fullaccess",
|
||||
(EntityAttribute ((hd o List.filter (fn x => #name x = name))
|
||||
(Rep.attributes_of root))))
|
||||
handle Empty => library.error "did not find attribute")
|
||||
|
||||
(** parses an entity method action permission attribute. *)
|
||||
fun parse_method_action root name "execute"
|
||||
= SimpleAction ("execute",
|
||||
(EntityMethod ((hd o List.filter (fn x => #name x = name))
|
||||
(Rep.operations_of root))))
|
||||
|
||||
handle Empty => library.error "did not find method"
|
||||
|
||||
(**
|
||||
* parses a permission attribute according to the ComponentUML
|
||||
* dialect for SecureUML.
|
||||
|
@ -119,10 +124,14 @@ fun parse_action root (att:Rep.attribute) =
|
|||
let val att_name = #name att
|
||||
val att_type = #attr_type att
|
||||
val action_name = (hd o rev o (fn Rep_OclType.Classifier x => x)) att_type
|
||||
fun resource_path name = (hd o List.tl) (String.tokens (fn x => x= #".") name)
|
||||
in case hd (#stereotypes att)
|
||||
of "dialect.entityaction" => parse_entity_action root att_name action_name
|
||||
| "dialect.methodaction" => parse_method_action root att_name action_name
|
||||
| "dialect.attributeaction" => parse_attribute_action root att_name action_name
|
||||
of "dialect.entityaction" =>
|
||||
parse_entity_action root att_name action_name
|
||||
| "dialect.entitymethodaction" =>
|
||||
parse_method_action root (resource_path att_name) action_name
|
||||
| "dialect.entityattributeaction" =>
|
||||
parse_attribute_action root (resource_path att_name) action_name
|
||||
| s => library.error ("in ComponentUML.parse_action: "^
|
||||
"found unexpected stereotype "^s^
|
||||
" for permission attribute")
|
||||
|
@ -130,8 +139,8 @@ fun parse_action root (att:Rep.attribute) =
|
|||
handle _ => library.error "in ComponentUML.parse_action: could not parse attribute"
|
||||
|
||||
fun action_type_of (SimpleAction (t,_)) = t
|
||||
| action_type_of (CompositeAction (t,_)) = t
|
||||
|
||||
| action_type_of (CompositeAction (t,_)) = t
|
||||
|
||||
(* val action_names = ["create","read","update","delete","full_access","execute"] *)
|
||||
|
||||
(** The actions possible on the given resource. *)
|
||||
|
@ -153,11 +162,11 @@ fun resource_of (SimpleAction x) = #2 x
|
|||
fun subordinated_actions (SimpleAction _) = nil
|
||||
| subordinated_actions (CompositeAction ("read", e as (Entity c))) =
|
||||
let val read_attributes = List.map (fn x => SimpleAction ("read", x))
|
||||
(entity_contained_attributes e)
|
||||
val read_methods = List.map (fn x => SimpleAction ("execute",x))
|
||||
(entity_contained_read_methods e)
|
||||
(entity_contained_attributes e)
|
||||
val read_methods = List.map (fn x => SimpleAction ("execute",x))
|
||||
(entity_contained_read_methods e)
|
||||
in
|
||||
List.concat [read_attributes,read_methods]
|
||||
List.concat [read_attributes,read_methods]
|
||||
end
|
||||
| subordinated_actions (CompositeAction ("full_access", e as (Entity c)))
|
||||
= [SimpleAction ("create",e),
|
||||
|
@ -166,11 +175,11 @@ fun subordinated_actions (SimpleAction _) = nil
|
|||
SimpleAction ("delete",e)]
|
||||
| subordinated_actions (CompositeAction ("update", e as (Entity c))) =
|
||||
let val update_attributes = List.map (fn x => SimpleAction ("update", x))
|
||||
(entity_contained_attributes e)
|
||||
val update_methods = List.map (fn x => SimpleAction ("execute",x))
|
||||
(entity_contained_update_methods e)
|
||||
(entity_contained_attributes e)
|
||||
val update_methods = List.map (fn x => SimpleAction ("execute",x))
|
||||
(entity_contained_update_methods e)
|
||||
in
|
||||
List.concat [update_attributes,update_methods]
|
||||
List.concat [update_attributes,update_methods]
|
||||
end
|
||||
| subordinated_actions (CompositeAction ("full_access", a as (EntityAttribute ae)))
|
||||
= [SimpleAction ("read", a),
|
||||
|
|
|
@ -52,6 +52,7 @@ sig
|
|||
val actions_of : Permission -> Design.Action list
|
||||
val permissions_of : Design.Action -> Permission list
|
||||
|
||||
val permission_includes_action : Permission -> Design.Action -> bool
|
||||
val parse: Rep_Core.Classifier list ->
|
||||
(Rep_Core.Classifier list * Configuration)
|
||||
|
||||
|
@ -86,6 +87,19 @@ type Permission = {name: string,
|
|||
|
||||
fun actions_of (p:Permission) = #actions p
|
||||
|
||||
fun permission_includes_action (p:Permission) (a:Design.Action) =
|
||||
(List.exists (fn x => x=a ) (actions_of p))
|
||||
orelse (List.exists (fn x => x) (map (permission_includes_action p)
|
||||
(Design.subordinated_actions a)))
|
||||
|
||||
fun is_contained_in a1 a2 = (a1 = a2) orelse
|
||||
List.exists (fn x=> x=true)
|
||||
((List.map (is_contained_in a1)
|
||||
(Design.subordinated_actions a2)))
|
||||
|
||||
fun isInPermission a (p:Permission) =
|
||||
List.exists (is_contained_in a) (#actions p)
|
||||
|
||||
type Config_Type = string
|
||||
|
||||
type 'a partial_order = ('a * 'a) list
|
||||
|
@ -114,6 +128,7 @@ fun users_of p = nil
|
|||
fun check_permission (u,p) = false
|
||||
fun permissions_of u = nil
|
||||
|
||||
|
||||
fun stereotypes_of (Rep.Class {stereotypes,...}) = stereotypes
|
||||
| stereotypes_of (Rep.Enumeration {stereotypes,...}) = stereotypes
|
||||
| stereotypes_of (Rep.Primitive {stereotypes,...}) = stereotypes
|
||||
|
@ -170,7 +185,10 @@ fun mkPermission cs (Rep.Class c) =
|
|||
Design.action_stereotypes) atts
|
||||
handle _ => library.error "could not parse permission attributes"
|
||||
in
|
||||
map (Design.parse_action root_resource) action_attributes
|
||||
if action_attributes = []
|
||||
then library.error ("no action attributes found in permission "^
|
||||
(Rep.string_of_path (#name c)))
|
||||
else map (Design.parse_action root_resource) action_attributes
|
||||
end }
|
||||
handle _ => library.error "error in mkPermission"
|
||||
|
||||
|
|
|
@ -103,6 +103,14 @@ fun transform_expression t (XMI.LiteralExp {symbol,expression_type}) =
|
|||
Rep_OclType.Classifier _ => cls
|
||||
| OclAny => find_type (XMI.expression_source_of exp)
|
||||
end
|
||||
(* this is a bit problematic: an associationendcall should always
|
||||
* have a (user-defined) classifier as source type. However, the
|
||||
* atPre() operation call returns OclAny, which is not a classifier.
|
||||
* Therefore, we look (recursively), at the source of the expression
|
||||
* source until we find a user-defined classifier type and take this type.
|
||||
* This works for the case of atPre(), but I'm not sure if there are other
|
||||
* cases where this hack has unwanted consequences.
|
||||
*)
|
||||
val classifier_type = find_type source
|
||||
val path_of_classifier = (fn (Rep_OclType.Classifier p) => p
|
||||
| x => error (Rep_OclType.string_of_OclType x)) classifier_type
|
||||
|
@ -448,8 +456,9 @@ fun transformXMI ({classifiers,constraints,packages,
|
|||
handle Empty => raise Option
|
||||
|
||||
|
||||
(** read and transform a .xmi file
|
||||
* @return a list of rep classifiers, or nil in case of problems
|
||||
(**
|
||||
* read and transform a .xmi file.
|
||||
* @return a list of rep classifiers, or nil in case of problems
|
||||
*)
|
||||
fun readXMI f = (transformXMI o ParseXMI.readFile) f
|
||||
handle ParseXMI.IllFormed msg => (print ("Warning: in Xmi2Mdr.readXMI: could not parse file "^f^":\n"^msg^"\n");
|
||||
|
|
Loading…
Reference in New Issue