Packages

A model management framework supporting multi-layered abstraction structures, pluggable data layers, and arbitrary command-line transform tools.

Current section

Files

Jump to
paradigm lib abstraction.ex
Raw

lib/abstraction.ex

defmodule Paradigm.Abstraction do
@moduledoc """
Functions for moving between Paradigm structs and corresponding graph data.
"""
@doc """
Takes any `Paradigm` and produces the corresponding graph that is invariant against the Metamodel paradigm.
"""
def embed(paradigm, graph \\ nil) do
graph = graph || Paradigm.Graph.MapGraph.new(name: paradigm.name, description: paradigm.description)
graph
|> add_primitive_types(paradigm)
|> add_packages(paradigm)
|> add_classes(paradigm)
|> add_enumerations(paradigm)
|> add_properties(paradigm)
end
defp add_primitive_types(graph, paradigm) do
Enum.reduce(paradigm.primitive_types, graph, fn {id, primitive_type}, acc ->
data = %{
"name" => primitive_type.name
}
Paradigm.Graph.insert_node(acc, id, "primitive_type", data)
end)
end
defp add_packages(graph, paradigm) do
Enum.reduce(paradigm.packages, graph, fn {id, package}, acc ->
data = %{
"name" => package.name,
"uri" => package.uri,
"nested_packages" => package.nested_packages,
"owned_types" => package.owned_types
}
Paradigm.Graph.insert_node(acc, id, "package", data)
end)
end
defp add_classes(graph, paradigm) do
Enum.reduce(paradigm.classes, graph, fn {id, class}, acc ->
data = %{
"name" => class.name,
"is_abstract" => class.is_abstract,
"owned_attributes" => class.owned_attributes,
"super_classes" => class.super_classes
}
Paradigm.Graph.insert_node(acc, id, "class", data)
end)
end
defp add_enumerations(graph, paradigm) do
Enum.reduce(paradigm.enumerations, graph, fn {id, enum}, acc ->
data = %{
"name" => enum.name,
"literals" => enum.literals
}
Paradigm.Graph.insert_node(acc, id, "enumeration", data)
end)
end
defp add_properties(graph, paradigm) do
Enum.reduce(paradigm.properties, graph, fn {id, property}, acc ->
data = %{
"name" => property.name,
"is_ordered" => property.is_ordered,
"type" => property.type,
"is_composite" => property.is_composite,
"lower_bound" => property.lower_bound,
"upper_bound" => property.upper_bound,
"default_value" => property.default_value
}
Paradigm.Graph.insert_node(acc, id, "property", data)
end)
end
@doc """
Takes a graph of metamodel type, and returns a top-level `Paradigm` object.
"""
def extract(graph) do
primitive_types =
Paradigm.Graph.get_all_nodes_of_class(graph, "primitive_type")
|> Enum.map(fn id -> {id, Paradigm.Graph.get_node(graph, id)} end)
|> Enum.map(fn {id, node} ->
{id,
%Paradigm.PrimitiveType{
name: node.data["name"]
}}
end)
|> Map.new()
packages =
Paradigm.Graph.get_all_nodes_of_class(graph, "package")
|> Enum.map(fn id -> {id, Paradigm.Graph.get_node(graph, id)} end)
|> Enum.map(fn {id, node} ->
{id,
%Paradigm.Package{
name: node.data["name"],
uri: node.data["uri"],
nested_packages: node.data["nested_packages"],
owned_types: node.data["owned_types"]
}}
end)
|> Map.new()
classes =
Paradigm.Graph.get_all_nodes_of_class(graph, "class")
|> Enum.map(fn id -> {id, Paradigm.Graph.get_node(graph, id)} end)
|> Enum.map(fn {id, node} ->
{id,
%Paradigm.Class{
name: node.data["name"],
is_abstract: node.data["is_abstract"],
owned_attributes: node.data["owned_attributes"],
super_classes: node.data["super_classes"]
}}
end)
|> Map.new()
enumerations =
Paradigm.Graph.get_all_nodes_of_class(graph, "enumeration")
|> Enum.map(fn id -> {id, Paradigm.Graph.get_node(graph, id)} end)
|> Enum.map(fn {id, node} ->
{id,
%Paradigm.Enumeration{
name: node.data["name"],
literals: node.data["literals"]
}}
end)
|> Map.new()
properties =
Paradigm.Graph.get_all_nodes_of_class(graph, "property")
|> Enum.map(fn id -> {id, Paradigm.Graph.get_node(graph, id)} end)
|> Enum.map(fn {id, node} ->
{id,
%Paradigm.Property{
name: node.data["name"],
is_ordered: node.data["is_ordered"],
type: node.data["type"],
is_composite: node.data["is_composite"],
lower_bound: node.data["lower_bound"],
upper_bound: node.data["upper_bound"],
default_value: node.data["default_value"]
}}
end)
|> Map.new()
%Paradigm{
name: graph.metadata[:name],
description: graph.metadata[:description],
primitive_types: primitive_types,
packages: packages,
classes: classes,
enumerations: enumerations,
properties: properties
}
end
end