TRANSFORMATION uml2rel : uml -> rel NAMESPACE http://simpleuml NAMESPACE http://relational // Produces a Table and Key for each persistent UMLClass. // RULE Class2Table(c, t, k) FORALL UMLClass c { kind: "persistent"; } MAKE Table t { name: c.name; key: Key k { name: c.name; }; } ; // Produces Columns belonging to a Table for // each persistent UMLClass with storable Attributes. // RULE Attr2Column(c, a, t, k, col) EXTENDS Class2Table(c, t, k) FORALL Attribute a WHERE hasAttr(c, a, n) MAKE Column col FROM c4a(c,a,n) { name: n; } SET t.column = col ; // Immediate Attributes of a UMLClass that are primary have // their corresponding Column as part of the Table's Key. // ABSTRACT RULE KeyColumns(c, a, t, k, col) EXTENDS Attr2Column(c, a, t, k, col) WHERE a.kind = "primary" AND inhAttr(c, a) SET col.belongsTo = k ; // An Attribute is "storable" if it is a simple type (PrimitiveDataType), // or it is UMLClass-valued and that UMLClass is persistent. // PATTERN storable(A) FORALL Attribute A WHERE C = A.type AND ( PrimitiveDataType C OR (UMLClass C AND A.type.kind = "persistent") ) ; // A UMLClass "inherits" an Attribute if it owns it directly, // or it has a superclass that "inherits" the Attribute. // // [Note - other's mapping examples ignore this, but what is a // "class" model without inheritance?] // PATTERN inhAttr(C, A) FORALL UMLClass C, Attribute A, UMLClass C2 WHERE A.owner = C OR (C.parents = C2 AND inhAttr(C2, A)) ; // This pattern is used to handle so-called "complex types". // A UMLClass "has" and Attribute with a fully qualified name // if it "inherits" the attribute and the attribute is storable, // or it "inherits" another UMLClass-valued attribute for which the // UMLClass is not persistent (ie a complex type) and that UMLClass // "has" the attribute. // // This will cycle if two non-persistent UMLClasses transitively // reference each other. // PATTERN hasAttr(C, A, N) FORALL UMLClass C, Attribute A WHERE ( ( inhAttr(C, A) AND storable(A) AND A.name = N ) OR ( inhAttr(C, A2) AND A2.type = C2 AND UMLClass C2 AND C2.kind != "persistent" AND hasAttr(C2, A, N2) AND N = append(A2.name, append("_", N2)) ) ) ;