require 'erb'
# EXPRESS to OWL Structural Mapping
# Version 0.5
# This function navigates the EXPRESS STEPMod Model Ruby Classes
# and performs a structural EXPRESS-to-OWL mapping using Ruby ERB templates.
# The output is in OWL RDF/XML abbreviated syntax.
# Mapping summary reports constructs where mapping is not sufficient (i.e. may need editing) or uses newer OWL capabilities
#
# Configurable items are:
# If file named definitions.csv is found, definitions of items are read from that CSV.
# Double quotes around ITEM and DEFINITION column values is required
# include_dublin_core - If true, import of the Dublin Core OWL is included. Set to true if dc used in annotation_list
# annotation_list - added to each construct created if found. Annotations are added if not 'nil'.
# usr_base of namespace for OWL constructs
# top_class - if not nil, makes every OWL class created a subclass if this class which is added to output
# thing_attributes - if specified, OWL DatatypeProperty domain is set to OWL Thing and range set to string
# datatype_hash - sets mappings for EXPRESS builtin to XSD datatypes
# post_processed_schema - If true, write post-processed schema data (e.g. propety hash) for inclusion in other program or script
#
# Mappings are:
# Entity Types and Subtypes are mapped to OWL Class hierarchy.
# Entity Type SUPERTYPE OF ONEOF( list-of-EntityTypes ) are mapped to OWL disjoint between Classes
# Select Types that resolve to all Entity Types are mapped to OWL Class hierarchy.
# Select Types that resolve to all Type are mapped to RDFS Datatype.
# Select Types that resolve to mixed Entity Types and Type are mapped to OWL Class hierarchy, so may need cleanup
# Enumeration Types are mapped to OWL Enumerated Classes
# Type = builtin are mapped to RDFS Datatypes that subtype XSD datatypes
# Type of Type of ... that ultimately resolve to builtin are mapped to datatype subtype hierarchy
# Explicit attrs of Type = builtin are mapped to OWL DatatypeProperties
# Type = AGGR are mapped to subClassOf rdf:List and type of element not specified
# Explicit attrs of 1-D LIST/ARRAY OF builtin/Type = builtin mapped to OWL ObjectProperty and subClassOf rdf:List and cardinality 1
# Explicit attrs of n-D AGGR mapped to OWL ObjectProperty and subClassOf rdf:List, type of element not specified, and cardinality 1
# Inverse attrs are mapped to OWL DatatypeProperties with inverseOf set, except inverse of inherited not mapped
# BOOLEAN attributes are mapped to OWL DatatypeProperties.
# Attribute redeclarations that ref Entity/Select are mapped to ObjectProperty that is subproperty of that it redeclares
# Attribute redeclarations that ref builting simple types are mapped to DatatypeProperty that is subproperty of that it redeclares
# Type = type that is a select are mapped to Class subclass of referenced select Class
# Single Attribute OPTIONAL or not maps to cardinality restriction on Class owning attribute
# 1D SET/BAG Attribute bound maps to cardinality restriction on Class owning attribute
# n-dimensional aggregates map to rdf List with no internal structure and type of element not specified
#
def map_from_express( mapinput )
puts ' '
puts 'EXPRESS to OWL Structural Mapping V0.5'
puts ' '
######### Mapping Configuration Starts Here ##############
# Set the base of the URI (i.e. the namespace) for OWL constructs created during the mapping
uri_base = 'http://www.reeper.org'
# Add RDFS andor Dublin Core basic annotations
# Set to true if any annotation_list elements use Dublin Core (dc: or dcterms:)
include_dublin_core = false
annotation_list = Array.new
# rdfs:comment must be position 0 as definition assignment hardcoded there
#annotation_list[0] = ['rdfs:comment', nil]
#annotation_list[1] = ['owl:versionInfo', '1']
#annotation_list[2] = ['dc:creator', 'David Price, TopQuadrant Limited']
#annotation_list[3] = ['dcterms:created','2010-10-22']
#annotation_list[4] = ['dc:source', '{ iso standard 10303 part(214) version(2) object(1) automotive-design-schema(1) }']
# Read definitions from csv file if found
definition_hash = Hash.new
if FileTest.exist?('definitions.csv')
require 'csv'
puts '-- Definitions CSV File Found'
CSV.open('definitions.csv', 'r') do |row|
definition_hash[row[0].downcase] = row[1]
end
end
# set to class name (e.g. 'TOP-THING') to make all created OWL Classes subclasses of a topmost class
top_class = 'AP233-ARM-THING'
# add common string attributes to use OWL Thing as domain rather than schema classes
thing_attributes = []
#thing_attributes.push 'id'
#thing_attributes.push 'name'
#thing_attributes.push 'description'
# datatypes for simple and aggregates of simple type
datatype_hash = Hash.new
datatype_hash["INTEGER"] = 'http://www.w3.org/2001/XMLSchema#integer'
datatype_hash["REAL"] = 'http://www.w3.org/2001/XMLSchema#float'
datatype_hash["NUMBER"] = 'http://www.w3.org/2001/XMLSchema#float'
datatype_hash["BINARY"] = 'http://www.w3.org/2001/XMLSchema#hexBinary'
datatype_hash["BOOLEAN"] = 'http://www.w3.org/2001/XMLSchema#boolean'
datatype_hash["LOGICAL"] = 'http://www.w3.org/2001/XMLSchema#boolean'
datatype_hash["STRING"] = 'http://www.w3.org/2001/XMLSchema#string'
# Write the property_type_hash for inclusion in other scripts or not
post_processed_schema = false
post_processed_schema_file_name = 'postprocessed_schema.rb'
post_processed_schema_file = File.new(post_processed_schema_file_name,'w') if post_processed_schema
######### Mapping Configuration Ends Here ##############
# Template covering the start of the output file
overall_start_template = %{
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dcterms="http://purl.org/dc/terms/"
<% end %>
}
# Template covering the output file contents for each schema start
schema_start_template = %{xmlns="<%= uri_base %>/<%= schema.name %>#"
xml:base="<%= uri_base %>/<%= schema.name %>#" >
<% annotation_list.each do |i| %><% if i[1] != nil and i[1] != '' %><<%= i[0] %> rdf:datatype="http://www.w3.org/2001/XMLSchema#string"><%= i[1] %><%= i[0] %>><% end %>
<% end %>
<% if include_dublin_core %>
<% end %>
<% if top_class != nil %>
<% end %>
}
# Template covering the output file contents for each entity type start or start of type = type that is a select
entity_start_template = %{
<% annotation_list.each do |i| %><% if i[1] != nil and i[1] != '' %><<%= i[0] %> rdf:datatype="http://www.w3.org/2001/XMLSchema#string"><%= i[1] %><%= i[0] %>><% end %>
<% end %>
}
# Template covering the output file contents for each entity type end or end of type = type that is a select
entity_end_template = %{
<% if top_class != nil %>
<% end %>
}
# Template covering the output file contents for end of type = type that is a select
class_end_template = %{}
# Template covering the output file contents for each select type start
select_start_template = %{
<% annotation_list.each do |i| %><% if i[1] != nil and i[1] != '' %><<%= i[0] %> rdf:datatype="http://www.w3.org/2001/XMLSchema#string"><%= i[1] %><%= i[0] %>><% end %>
<% end %>
}
# Template covering the output file contents for each select type end
select_end_template = %{<% if top_class != nil %>
<% end %>
}
# Template covering the supertype(s) for each entity type and type = type that is a select
supertype_template = %{
}
# Template covering OWL collections of class contents
class_collection_template = %{
<% item_name_list.each do |name| %>
<% end %>
}
# Template covering OWL collections of RDFS datatypes
datatype_collection_template = %{
<% type_name_list.each do |name| %>
<% end %>
}
# Template covering abstract entity types
abstract_entity_template = %{
}
# Template covering the output file contents for each defined type of builtin datatype
type_builtin_template = %{
}
# Template covering the mappings to rdf list
rdflist_template = %{
}
# Template covering the output file contents for each attribute that is an aggregate
attribute_aggregate_template = %{}
# Template covering the output file contents for each attribute that is an aggregate of select of entity
attribute_aggregate_entity_select_template = %{}
# Template covering the output file contents for each attribute that is a select of entity
attribute_entity_select_template = %{}
# Template covering the output file contents for each attribute
attribute_template = %{}
# Template covering the output file contents for each attribute that is builtin datatype
attribute_builtin_template = %{
<% if owl_property_domain != nil %>
<% end %>
<% annotation_list.each do |i| %><% if i[1] != nil and i[1] != '' %><<%= i[0] %> rdf:datatype="http://www.w3.org/2001/XMLSchema#string"><%= i[1] %><%= i[0] %>><% end %>
<% end %>
<% if owl_super_property_name != nil %>
<% end %>
}
# Template covering the output file contents for each attribute that is type that is builtin datatype
attribute_typebuiltin_template = %{
<% if owl_property_domain != nil %>
<% end %>
<% annotation_list.each do |i| %><% if i[1] != nil and i[1] != '' %><<%= i[0] %> rdf:datatype="http://www.w3.org/2001/XMLSchema#string"><%= i[1] %><%= i[0] %>><% end %>
<% end %>
}
# Template covering the output file contents for each attribute that is entity or select type
attribute_entity_template = %{
<% annotation_list.each do |i| %><% if i[1] != nil and i[1] != '' %><<%= i[0] %> rdf:datatype="http://www.w3.org/2001/XMLSchema#string"><%= i[1] %><%= i[0] %>><% end %>
<% end %>
}
# Template covering the output file contents for each attribute that is entity or select type
inverse_entity_template = %{
<% annotation_list.each do |i| %><% if i[1] != nil and i[1] != '' %><<%= i[0] %> rdf:datatype="http://www.w3.org/2001/XMLSchema#string"><%= i[1] %><%= i[0] %>><% end %>
<% end %>
}
# Template covering the output file contents for each attribute that is a redeclaration and reference to an entity or select type
attribute_redeclare_entity_template = %{
<% annotation_list.each do |i| %><% if i[1] != nil and i[1] != '' %><<%= i[0] %> rdf:datatype="http://www.w3.org/2001/XMLSchema#string"><%= i[1] %><%= i[0] %>><% end %>
<% end %>
}
# Template covering the output file contents for each attribute that is enum datatype
class_enum_template = %{
<% enumitem_name_list.each do |name| %>
<% end %>
}
# Template covering the output file contents for each attribute that is enum datatype
attribute_enum_template = %{
<% enumitem_name_list.each do |name| %>
<%= name %>
<% if enumitem_name_list[enumitem_name_list.size-1] != name %>
<% end %>
<% if enumitem_name_list[enumitem_name_list.size-1] == name %>
<% end %>
<% end %>
<% (1..enumitem_name_list.size-1).each do %>
<% end %>
<% annotation_list.each do |i| %><% if i[1] != nil and i[1] != '' %><<%= i[0] %> rdf:datatype="http://www.w3.org/2001/XMLSchema#string"><%= i[1] %><%= i[0] %>><% end %>
<% end %>
}
# Template covering min cardinality
min_cardinality_template = %{
<%= min_cardinality %>
}
# Template covering max cardinality
max_cardinality_template = %{
<%= max_cardinality %>
}
# Template covering cardinality
cardinality_template = %{
<%= min_cardinality %>
}
# Template covering the output file contents for each schema end
disjoint_template = %{
}
# Template covering the output file contents for each schema end
schema_end_template = %{}
# Template covering the end of the output file
overall_end_template = %{ }
def post_process_entity(entity, post_processed_schema_file, datatype_hash)
attribute_list = entity.attributes_all_array.find_all{ |a| a.kind_of? EXPSM::Explicit}
for attribute in attribute_list
express_attribute_domain = nil
if !attribute.isBuiltin
express_attribute_domain = NamedType.find_by_name( attribute.domain )
end
p28_property_name = entity.name.capitalize + '.' + attribute.name.capitalize
property_quoted = false
property_list = false
property_type = '"' + attribute.domain + '"'
if attribute.isBuiltin
property_type = '"' + datatype_hash[attribute.domain] + '"'
end
if attribute.isBuiltin and attribute.domain == 'STRING'
property_quoted = true
end
if (!attribute.redeclare_entity and express_attribute_domain.instance_of? EXPSM::Type and express_attribute_domain.isBuiltin and express_attribute_domain == 'STRING')
property_quoted = true
property_type = '"' + datatype_hash[express_attribute_domain.domain] + '"'
end
if ( attribute.isBuiltin and attribute.instance_of? EXPSM::ExplicitAggregate and attribute.rank == 1 and attribute.dimensions[0].aggrtype = 'LIST')
property_list = true
property_type = '"' + datatype_hash[attribute.domain] + '"'
end
if (express_attribute_domain.instance_of? EXPSM::Type and express_attribute_domain.isBuiltin and attribute.instance_of? EXPSM::ExplicitAggregate and attribute.rank == 1 and attribute.dimensions[0].aggrtype = 'LIST')
property_list = true
property_type = '"' + datatype_hash[express_attribute_domain.domain] + '"'
end
property_type = property_type.gsub('http://www.w3.org/2001/XMLSchema#','xsd:')
post_processed_schema_file.puts 'property_range_hash["' + p28_property_name + '"] = [' + property_quoted.to_s + ',' + property_list.to_s + ',' + property_type.to_s + ']'
end
end
# A recursive function to return complete set of items, following nested selects, for a select that are not selects themselves
def get_all_selections( item_list )
select_items = item_list.find_all{ |a| a.kind_of? EXPSM::TypeSelect}
if select_items.size == 0
return item_list
end
temp_item_list = item_list
for select in select_items
temp_item_list.delete( select )
temp_item_list = temp_item_list + select.selectitems_array
end
final_list = get_all_selections( temp_item_list )
end
# A recursive function to return the ultimate underlying type of a type
def is_utlimate_type_builtin( the_type )
return true if the_type.isBuiltin
base_type = NamedType.find_by_name( the_type.domain )
case
when (base_type.instance_of? EXPSM::TypeSelect or base_type.instance_of? EXPSM::Entity)
return false
when (base_type.kind_of? EXPSM::Type and base_type.isBuiltin)
return true
else
return is_utlimate_type_builtin( base_type )
end
end
# Set up list of schemas to process, input may be a repository containing schemas or a single schema
if mapinput.kind_of? EXPSM::Repository
schema_list = mapinput.schemas
elsif mapinput.kind_of? EXPSM::SchemaDefinition
schema_list = [mapinput]
else
puts "ERROR : map_from_express input no Repository instance or Schema instance"
exit
end
for schema in schema_list
type_mapped_list = []
entity_mapped_list = []
explicit_mapped_list = []
inverse_mapped_list = []
thing_attr_mapped_list = []
superexpression_mapped_list = []
list_mapped_attr_list = []
list_mapped_type_list = []
type_union_mapped_list = []
mixed_select_list = []
all_explicit_list = []
all_derived_list = []
all_inverse_list = []
all_superexpression_list = []
# Set up separate file for each schema
filename = schema.name.to_s + ".owl"
file = File.new(filename, "w")
# Evaluate and write file start template
res = ERB.new(overall_start_template)
t = res.result(binding)
file.puts t
# Evaluate and write schema start template
res = ERB.new(schema_start_template)
t = res.result(binding)
file.puts t
select_list = schema.contents.find_all{ |e| e.kind_of? EXPSM::TypeSelect }
entity_list = schema.contents.find_all{ |e| e.kind_of? EXPSM::Entity }
defined_type_list = schema.contents.find_all{ |e| e.kind_of? EXPSM::Type }
enum_type_list = schema.contents.find_all{ |e| e.kind_of? EXPSM::TypeEnum }
defined_type_not_builtin_list = defined_type_list.find_all{ |e| !e.isBuiltin }
defined_type_builtin_list = defined_type_list.find_all{ |e| e.isBuiltin }
# Handle enumeration type maps to RDFS Datatype string
for type_enum in enum_type_list
type_mapped_list.push type_enum
owl_class_name = type_enum.name
enumitem_name_list = type_enum.items.scan(/\w+/)
res = ERB.new(class_enum_template)
t = res.result(binding)
file.puts t
end
# Handle defined type maps to RDFS Datatype
for type_builtin in defined_type_builtin_list
# Handle defined type maps to RDFS Datatype
if !type_builtin.instance_of? EXPSM::TypeAggregate
type_mapped_list.push type_builtin
datatype_name = type_builtin.name
superdatatype_name = datatype_hash[type_builtin.domain]
res = ERB.new(type_builtin_template)
t = res.result(binding)
file.puts t
# Handle defined type maps to RDF List
else
list_mapped_type_list.push type_builtin
type_mapped_list.push type_builtin
list_name = type_builtin.name
superlist_name = "http://www.w3.org/1999/02/22-rdf-syntax-ns#List"
res = ERB.new(rdflist_template)
t = res.result(binding)
file.puts t
end
end
for type_not_builtin in defined_type_not_builtin_list
type_domain = NamedType.find_by_name( type_not_builtin.domain )
type_is_builtin = is_utlimate_type_builtin( type_not_builtin )
case
# Handle simple defined type refining simple defined type of builtin map to RDFS Datatype
when (!type_not_builtin.instance_of? EXPSM::TypeAggregate and type_is_builtin and !type_domain.instance_of? EXPSM::TypeAggregate)
type_mapped_list.push type_not_builtin
datatype_name = type_not_builtin.name
superdatatype_name = '#' + type_domain.name
res = ERB.new(type_builtin_template)
t = res.result(binding)
file.puts t
# Handle simple defined type of aggr defined type of builtin map to RDF List
when (!type_not_builtin.instance_of? EXPSM::TypeAggregate and type_domain.instance_of? EXPSM::TypeAggregate and type_is_builtin)
type_mapped_list.push type_not_builtin
list_mapped_type_list.push type_not_builtin
list_name = type_not_builtin.name
superlist_name = '#' + type_domain.name
res = ERB.new(rdflist_template)
t = res.result(binding)
file.puts t
# Handle aggr defined type of simple defined type of builtin map to RDF List
when (type_not_builtin.instance_of? EXPSM::TypeAggregate and type_domain.instance_of? EXPSM::Type and type_is_builtin)
type_mapped_list.push type_not_builtin
list_mapped_type_list.push type_not_builtin
list_name = type_not_builtin.name
superlist_name = "http://www.w3.org/1999/02/22-rdf-syntax-ns#List"
res = ERB.new(rdflist_template)
t = res.result(binding)
file.puts t
# Handle aggr of entity/select type map to RDF List
when (type_not_builtin.instance_of? EXPSM::TypeAggregate and (type_domain.instance_of? EXPSM::Entity or type_domain.instance_of? EXPSM::TypeSelect))
type_mapped_list.push type_not_builtin
list_mapped_type_list.push type_not_builtin
list_name = type_not_builtin.name
superlist_name = "http://www.w3.org/1999/02/22-rdf-syntax-ns#List"
res = ERB.new(rdflist_template)
t = res.result(binding)
file.puts t
# Handle defined type that are type = type that is a select
when (type_domain.kind_of? EXPSM::TypeSelect)
type_mapped_list.push type_not_builtin
superclass_name = type_not_builtin.domain
class_name = type_not_builtin.name
res = ERB.new(entity_start_template)
t = res.result(binding)
file.puts t
superclass_name = type_not_builtin.domain
res = ERB.new(supertype_template)
t = res.result(binding)
file.puts t
res = ERB.new(class_end_template)
t = res.result(binding)
file.puts t
else
puts 'ERROR : Not mapped = ' + type_not_builtin.name
end
end
# Handle EXPRESS SELECT Type mapping to OWL Class hierarchy and RDFS Datatypes
for select in select_list
item_name_list = select.selectitems.scan(/\w+/)
this_select_all_items = get_all_selections( select.selectitems_array )
this_select_type_items = this_select_all_items.find_all{ |a| a.kind_of? EXPSM::Type}
case
# Handle case of select items resolving to containing only items that are non-select Type
when this_select_type_items.size == this_select_all_items.size
type_mapped_list.push select
type_union_mapped_list.push select
type_name_list = item_name_list
type_name = select.name
res = ERB.new(datatype_collection_template)
t = res.result(binding)
file.puts t
# Handle case of select items resolving to containing no item that is a non-select Type
else
type_mapped_list.push select
res = ERB.new(select_start_template)
t = res.result(binding)
file.puts t
file.puts ''
res = ERB.new(class_collection_template)
t = res.result(binding)
file.puts t
file.puts ''
res = ERB.new(select_end_template)
t = res.result(binding)
file.puts t
if (this_select_type_items.size != 0 and this_select_type_items.size != this_select_all_items.size)
mixed_select_list.push select
end
end
end
# Handle EXPRESS Entity mappings to OWL Class hierarchy
for entity in entity_list
if definition_hash[entity.name.downcase] != nil
annotation_list[0] = ['rdfs:comment', definition_hash[entity.name.downcase]]
else
annotation_list[0] = ['rdfs:comment', nil]
end
entity_mapped_list.push entity
class_name = entity.name
res = ERB.new(entity_start_template)
t = res.result(binding)
file.puts t
for supertype in entity.supertypes_array
superclass_name = supertype.name
res = ERB.new(supertype_template)
t = res.result(binding)
file.puts t
end
res = ERB.new(entity_end_template)
t = res.result(binding)
file.puts t
# Post-process the entity
post_process_entity(entity, post_processed_schema_file, datatype_hash) if post_processed_schema
if entity.superexpression != nil
all_superexpression_list.push entity
# Handle simple case of one ONEOF in supertype expression mapped to disjoint between listed subclasses
case
# when (entity.superexpression.include?('ONEOF') and !entity.superexpression.include?('ANDOR') and !entity.superexpression.include?('TOTAL_OVER') and !entity.superexpression.include?('AND') and !entity.superexpression.include?('ABSTRACT'))
when (entity.superexpression.include?('ONEOF'))
superexpression_mapped_list.push entity
tempexpression = entity.superexpression
if entity.superexpression.index('ONEOF') != 0
puts 'WARNING: ' + entity.name + ' supertype mapping may be incomplete, only ONEOFs processed'
end
while (tempexpression.include?('ONEOF'))
posoneof = tempexpression.index('ONEOF')
tempexpression = tempexpression[posoneof + 5,tempexpression.length - 5]
posclose = tempexpression.index(')')
oneof_name_list = tempexpression[0,posclose].scan(/\w+/)
while oneof_name_list.size != 0
first_class_name = oneof_name_list[0]
oneof_name_list.delete(first_class_name)
for disjoint_class_name in oneof_name_list
res = ERB.new(disjoint_template)
t = res.result(binding)
file.puts t
end
end
end
else
end
end
end
# Handle mapping common string attributes to OWL DatatypeProperties of OWL Thing
for thing_attribute in thing_attributes
owl_property_name = thing_attribute
owl_property_range = 'http://www.w3.org/2001/XMLSchema#string'
owl_property_domain = nil
owl_super_property_name = nil
res = ERB.new(attribute_builtin_template)
t = res.result(binding)
file.puts t
end
# Handle EXPRESS attributes on an entity-by-entity basis
for entity in entity_list
class_name = entity.name
attribute_list = entity.attributes.find_all{ |a| a.kind_of? EXPSM::Explicit and !thing_attributes.include?(a.name)}
thing_attr_list = entity.attributes.find_all{ |a| a.kind_of? EXPSM::Explicit and thing_attributes.include?(a.name)}
inverse_list = entity.attributes.find_all{ |a| a.kind_of? EXPSM::Inverse and !thing_attributes.include?(a.name)}
thing_attr_mapped_list = thing_attr_mapped_list + thing_attr_list
all_explicit_list = all_explicit_list + entity.attributes.find_all{ |a| a.kind_of? EXPSM::Explicit}
all_derived_list = all_derived_list + entity.attributes.find_all{ |a| a.kind_of? EXPSM::Derived}
all_inverse_list = all_inverse_list + inverse_list
# Handle EXPRESS inverse attribute mapping to OWL inverse property
for attribute in inverse_list
if attribute.reverseAttr != []
inverse_mapped_list.push attribute
owl_property_range = attribute.domain
owl_property_name = entity.name + '.' + attribute.name
owl_property_domain = entity.name
owl_inverted_property_name = attribute.reverseEntity.name + '.' + attribute.reverseAttr.name
res = ERB.new(inverse_entity_template)
t = res.result(binding)
file.puts t
end
end
# Handle EXPRESS explicit attribute mapping to OWL property
for attribute in attribute_list
express_attribute_domain = nil
type_is_builtin = false
if !attribute.isBuiltin
express_attribute_domain = NamedType.find_by_name( attribute.domain )
if express_attribute_domain.instance_of? EXPSM::Type
type_is_builtin = is_utlimate_type_builtin( express_attribute_domain )
end
end
case
# Handle EXPRESS explicit attributes of LIST of built-in simple type, including redeclaration
when (attribute.isBuiltin and attribute.instance_of? EXPSM::ExplicitAggregate and attribute.rank == 1 and attribute.dimensions[0].aggrtype = 'LIST')
explicit_mapped_list.push attribute
list_mapped_attr_list.push attribute
list_name = entity.name + '.' + attribute.name + '-' + attribute.domain.to_s + '-List'
superlist_name = "http://www.w3.org/1999/02/22-rdf-syntax-ns#List"
res = ERB.new(rdflist_template)
t = res.result(binding)
file.puts t
owl_property_name = entity.name + '.' + attribute.name
owl_property_domain = entity.name
owl_property_range = list_name
res = ERB.new(attribute_entity_template)
t = res.result(binding)
file.puts t
# Handle EXPRESS explicit attributes of ARRAY of built-in simple type, including redeclaration
when (attribute.isBuiltin and attribute.instance_of? EXPSM::ExplicitAggregate and attribute.rank == 1 and attribute.dimensions[0].aggrtype = 'ARRAY')
explicit_mapped_list.push attribute
list_mapped_attr_list.push attribute
list_name = entity.name + '.' + attribute.name + '-' + attribute.domain.to_s + '-Array'
superlist_name = "http://www.w3.org/1999/02/22-rdf-syntax-ns#List"
res = ERB.new(rdflist_template)
t = res.result(binding)
file.puts t
owl_property_name = entity.name + '.' + attribute.name
owl_property_domain = entity.name
owl_property_range = list_name
res = ERB.new(attribute_entity_template)
t = res.result(binding)
file.puts t
# Handle EXPRESS explicit attributes of LIST of TYPE that is built-in simple type, including redeclaration
when (express_attribute_domain.instance_of? EXPSM::Type and type_is_builtin and attribute.instance_of? EXPSM::ExplicitAggregate and attribute.rank == 1 and attribute.dimensions[0].aggrtype = 'LIST')
explicit_mapped_list.push attribute
list_mapped_attr_list.push attribute
list_name = entity.name + '.' + attribute.name + '-' + attribute.domain.to_s + '-List'
superlist_name = "http://www.w3.org/1999/02/22-rdf-syntax-ns#List"
res = ERB.new(rdflist_template)
t = res.result(binding)
file.puts t
owl_property_name = entity.name + '.' + attribute.name
owl_property_domain = entity.name
owl_property_range = list_name
res = ERB.new(attribute_entity_template)
t = res.result(binding)
file.puts t
# Handle EXPRESS explicit attributes of ARRAY of TYPE that is built-in simple type, including redeclaration
when (express_attribute_domain.instance_of? EXPSM::Type and type_is_builtin and attribute.instance_of? EXPSM::ExplicitAggregate and attribute.rank == 1 and attribute.dimensions[0].aggrtype = 'ARRAY')
explicit_mapped_list.push attribute
list_mapped_attr_list.push attribute
list_name = entity.name + '.' + attribute.name + '-' + attribute.domain.to_s + '-Array'
superlist_name = "http://www.w3.org/1999/02/22-rdf-syntax-ns#List"
res = ERB.new(rdflist_template)
t = res.result(binding)
file.puts t
owl_property_name = entity.name + '.' + attribute.name
owl_property_domain = entity.name
owl_property_range = list_name
res = ERB.new(attribute_entity_template)
t = res.result(binding)
file.puts t
# Handle EXPRESS explicit attributes of built-in simple type, including redeclaration
when (attribute.isBuiltin)
explicit_mapped_list.push attribute
owl_property_range = datatype_hash[attribute.domain]
owl_property_name = entity.name + '.' + attribute.name
owl_property_domain = entity.name
owl_super_property_name = nil
if attribute.redeclare_entity != nil
if attribute.redeclare_oldname == nil
owl_super_property_name = attribute.redeclare_entity + '.' + attribute.name
else
owl_super_property_name = attribute.redeclare_entity + '.' + attribute.redeclare_oldname
end
end
res = ERB.new(attribute_builtin_template)
t = res.result(binding)
file.puts t
# Handle EXPRESS explicit attribute, not redeclaration, refers to Type that is Type = builtin datatype
when (!attribute.redeclare_entity and express_attribute_domain.instance_of? EXPSM::Type and type_is_builtin)
explicit_mapped_list.push attribute
owl_property_range = attribute.domain
owl_property_name = entity.name + '.' + attribute.name
owl_property_domain = entity.name
res = ERB.new(attribute_typebuiltin_template)
t = res.result(binding)
file.puts t
# Handle EXPRESS explicit attributes of enum type, ignoring redeclarations
when (express_attribute_domain.kind_of? EXPSM::TypeEnum)
explicit_mapped_list.push attribute
owl_property_name = entity.name + '.' + attribute.name
owl_property_domain = entity.name
owl_property_range = attribute.domain
res = ERB.new(attribute_entity_template)
# if !type_mapped_list.include?(express_attribute_domain)
# type_mapped_list.push express_attribute_domain
# end
# enumitem_name_list = express_attribute_domain.items.scan(/\w+/)
# res = ERB.new(attribute_enum_template)
t = res.result(binding)
file.puts t
if attribute.redeclare_entity
puts 'WARNING: ' + entity.name + ' ' + attribute.name + ' Attribute redeclaration for Enumerations not mapped'
end
# Handle EXPRESS explicit attribute, not redeclaration, and only refer to EXPRESS Select or Entity
when (!attribute.redeclare_entity and (express_attribute_domain.kind_of? EXPSM::Entity or express_attribute_domain.kind_of? EXPSM::TypeSelect))
explicit_mapped_list.push attribute
owl_property_range = attribute.domain
owl_property_name = entity.name + '.' + attribute.name
owl_property_domain = entity.name
res = ERB.new(attribute_entity_template)
t = res.result(binding)
file.puts t
# Handle EXPRESS explicit attribute, redeclaration, and only refer to EXPRESS Select or Entity
when (attribute.redeclare_entity and (express_attribute_domain.kind_of? EXPSM::Entity or express_attribute_domain.kind_of? EXPSM::TypeSelect))
explicit_mapped_list.push attribute
owl_property_range = attribute.domain
owl_property_name = entity.name + '.' + attribute.name
if attribute.redeclare_oldname == nil
owl_super_property_name = attribute.redeclare_entity + '.' + attribute.name
else
owl_super_property_name = attribute.redeclare_entity + '.' + attribute.redeclare_oldname
end
owl_property_domain = entity.name
res = ERB.new(attribute_redeclare_entity_template)
t = res.result(binding)
file.puts t
# Handle EXPRESS explicit attribute of EXPRESS Type = A Type name that is a Select
when (express_attribute_domain.kind_of? EXPSM::Type and NamedType.find_by_name( express_attribute_domain.domain ).kind_of? EXPSM::TypeSelect)
explicit_mapped_list.push attribute
owl_property_range = attribute.domain
owl_property_name = entity.name + '.' + attribute.name
owl_property_domain = entity.name
res = ERB.new(attribute_entity_template)
t = res.result(binding)
file.puts t
# Handle EXPRESS explicit attribute, redeclaration, and only refer to EXPRESS Type = A Type name that is a Select
when (attribute.redeclare_entity and (express_attribute_domain.kind_of? EXPSM::Type and NamedType.find_by_name( express_attribute_domain.domain ).kind_of? EXPSM::TypeSelect))
explicit_mapped_list.push attribute
owl_property_range = attribute.domain
owl_property_name = entity.name + '.' + attribute.name
if attribute.redeclare_oldname == nil
owl_super_property_name = attribute.redeclare_entity + '.' + attribute.name
else
owl_super_property_name = attribute.redeclare_entity + '.' + attribute.redeclare_oldname
end
owl_property_domain = entity.name
res = ERB.new(attribute_redeclare_entity_template)
t = res.result(binding)
file.puts t
else
puts 'WARNING: ' + entity.name + ' ' + attribute.name + ' Attribute type not yet mapped'
end
min_cardinality = 1
max_cardinality = 1
if attribute.isOptional == true
min_cardinality = 0
end
if (attribute.instance_of? EXPSM::ExplicitAggregate and attribute.rank == 1 and attribute.dimensions[0].aggrtype != 'LIST' and attribute.dimensions[0].aggrtype != 'ARRAY')
if attribute.isOptional == false
min_cardinality = attribute.dimensions[0].lower.to_i
end
if attribute.dimensions[0].upper == '?'
max_cardinality = -1
else
max_cardinality = attribute.dimensions[0].upper.to_i
end
if attribute.rank > 1
puts 'WARNING: ' + owl_property_name + ' n-dimensional aggregate attribute cardinalities not mapped '
max_cardinality = -1
end
end
if min_cardinality == max_cardinality
res = ERB.new(cardinality_template)
t = res.result(binding)
file.puts t
else
res = ERB.new(min_cardinality_template)
t = res.result(binding)
file.puts t
if max_cardinality != -1
res = ERB.new(max_cardinality_template)
t = res.result(binding)
file.puts t
end
end
if (attribute.redeclare_entity and !(express_attribute_domain.kind_of? EXPSM::Entity or express_attribute_domain.kind_of? EXPSM::TypeSelect))
if (attribute.redeclare_entity and !(express_attribute_domain.kind_of? EXPSM::Type and NamedType.find_by_name( express_attribute_domain.domain ).kind_of? EXPSM::TypeSelect))
if (attribute.redeclare_entity and !attribute.isBuiltin)
puts 'WARNING: ' + entity.name + ' ' + attribute.name + ' Attribute redeclaration may need hand editing'
end
end
end
end
end
res = ERB.new(schema_end_template)
t = res.result(binding)
file.puts t
puts ' '
puts 'Schema Mapping Summary for : ' + schema.name
all_type_list = schema.contents.find_all{ |e| e.kind_of? EXPSM::DefinedType }
puts ' ENTITYs mapped = ' + entity_mapped_list.size.to_s + ' of ' + entity_list.size.to_s
puts ' - ' + superexpression_mapped_list.size.to_s + ' of ' + all_superexpression_list.size.to_s + ' ENTITY SUPERTYPE expressions mapped (only simple ONEOF supported)'
for t in all_superexpression_list - superexpression_mapped_list
puts ' Not mapped: ' + t.name
end
puts ' - ' + inverse_mapped_list.size.to_s + ' of ' + all_inverse_list.size.to_s + ' inverse attributes mapped (inverse of inherited not supported)'
notmapped_list = all_inverse_list - inverse_mapped_list
for t in notmapped_list
puts ' Not mapped: ' + t.entity.name + '.' + t.name
end
puts ' - ' + thing_attr_mapped_list.size.to_s + ' of ' + all_explicit_list.size.to_s + ' explicit attributes mapped with owl:Thing as domain (configurable)'
puts ' - ' + explicit_mapped_list.size.to_s + ' of ' + all_explicit_list.size.to_s + ' explicit attributes mapped'
for t in list_mapped_attr_list
puts ' rdf:List mapped: ' + t.name
end
notmapped_list = all_explicit_list - explicit_mapped_list - thing_attr_mapped_list
for t in notmapped_list
puts ' Not mapped: ' + t.entity.name + '.' + t.name
end
puts ' - ' + all_derived_list.size.to_s + ' derived attributes not mapped, not supported'
puts ' TYPEs mapped = ' + type_mapped_list.size.to_s + ' of ' + all_type_list.size.to_s
for t in list_mapped_type_list
puts ' rdf:List mapped: ' + t.name
end
for t in mixed_select_list
puts ' Select of entity & type Class mapped: ' + t.name
end
for t in type_union_mapped_list
puts ' Select RDFS Datatype owl:unionOf mapped: ' + t.name
end
notmapped_list = all_type_list - type_mapped_list
for t in notmapped_list
puts ' Not mapped: ' + t.name
end
puts ' '
puts 'Wrote post-processed schema to file: ' + post_processed_schema_file_name if post_processed_schema
end
res = ERB.new(overall_end_template)
t = res.result(binding)
file.puts t
post_processed_schema_file.close if post_processed_schema
end