sdl-ng 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +20 -0
- data/.rspec +2 -0
- data/.yard_redcarpet_ext +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +13 -0
- data/README.md +454 -0
- data/Rakefile +16 -0
- data/bin/process_service_descriptions +102 -0
- data/examples/services/google_drive_for_business.service.rb +50 -0
- data/examples/services/salesforce_sales_cloud.service.rb +51 -0
- data/examples/translations/en.yml +184 -0
- data/examples/vocabulary/base/base.sdl.rb +8 -0
- data/examples/vocabulary/base/location.sdl.rb +5 -0
- data/examples/vocabulary/crf/characteristics.sdl.rb +25 -0
- data/examples/vocabulary/crf/charging.sdl.rb +8 -0
- data/examples/vocabulary/crf/compliance.sdl.rb +35 -0
- data/examples/vocabulary/crf/delivery.sdl.rb +22 -0
- data/examples/vocabulary/crf/dynamics.sdl.rb +6 -0
- data/examples/vocabulary/crf/interop.sdl.rb +54 -0
- data/examples/vocabulary/crf/optimizing.sdl.rb +15 -0
- data/examples/vocabulary/crf/portability.sdl.rb +25 -0
- data/examples/vocabulary/crf/protection.sdl.rb +8 -0
- data/examples/vocabulary/crf/reliability.sdl.rb +1 -0
- data/examples/vocabulary/crf/reputation.sdl.rb +3 -0
- data/lib/sdl.rb +17 -0
- data/lib/sdl/base.rb +20 -0
- data/lib/sdl/base/fact.rb +11 -0
- data/lib/sdl/base/property.rb +34 -0
- data/lib/sdl/base/service.rb +13 -0
- data/lib/sdl/base/service_compendium.rb +130 -0
- data/lib/sdl/base/type.rb +66 -0
- data/lib/sdl/exporters.rb +9 -0
- data/lib/sdl/exporters/exporter.rb +19 -0
- data/lib/sdl/exporters/markdown_service_exporter.rb +5 -0
- data/lib/sdl/exporters/rdf_exporter.rb +34 -0
- data/lib/sdl/exporters/rdf_mapping.rb +48 -0
- data/lib/sdl/exporters/schema_exporter.rb +9 -0
- data/lib/sdl/exporters/service_exporter.rb +9 -0
- data/lib/sdl/exporters/xml_mapping.rb +51 -0
- data/lib/sdl/exporters/xml_service_exporter.rb +37 -0
- data/lib/sdl/exporters/xsd_schema_exporter.rb +94 -0
- data/lib/sdl/receivers.rb +22 -0
- data/lib/sdl/receivers/fact_receiver.rb +15 -0
- data/lib/sdl/receivers/service_receiver.rb +63 -0
- data/lib/sdl/receivers/type_instance_receiver.rb +86 -0
- data/lib/sdl/receivers/type_receiver.rb +87 -0
- data/lib/sdl/translations/en.yml +9 -0
- data/lib/sdl/types.rb +19 -0
- data/lib/sdl/types/sdl_datetime.rb +10 -0
- data/lib/sdl/types/sdl_default_type.rb +13 -0
- data/lib/sdl/types/sdl_description.rb +10 -0
- data/lib/sdl/types/sdl_duration.rb +12 -0
- data/lib/sdl/types/sdl_number.rb +10 -0
- data/lib/sdl/types/sdl_string.rb +10 -0
- data/lib/sdl/types/sdl_type.rb +31 -0
- data/lib/sdl/types/sdl_url.rb +12 -0
- data/lib/sdl/util.rb +4 -0
- data/lib/sdl/util/documentation.rb +80 -0
- data/lib/sdl/util/nokogiri.rb +28 -0
- data/lib/sdl/util/verbs.rb +3 -0
- data/lib/sdl/version.rb +3 -0
- data/sdl-ng.gemspec +34 -0
- data/spec/documentation_spec.rb +64 -0
- data/spec/fact_type_instance_definition_spec.rb +188 -0
- data/spec/property_definitions_spec.rb +44 -0
- data/spec/service_compendium_spec.rb +90 -0
- data/spec/service_definition_spec.rb +81 -0
- data/spec/shared_test_compendium.rb +65 -0
- data/spec/spec_helper.rb +10 -0
- metadata +291 -0
@@ -0,0 +1,9 @@
|
|
1
|
+
require_relative 'exporters/xml_mapping'
|
2
|
+
require_relative 'exporters/exporter'
|
3
|
+
require_relative 'exporters/schema_exporter'
|
4
|
+
require_relative 'exporters/service_exporter'
|
5
|
+
require_relative 'exporters/xsd_schema_exporter'
|
6
|
+
require_relative 'exporters/xml_service_exporter'
|
7
|
+
require_relative 'exporters/rdf_mapping'
|
8
|
+
require_relative 'exporters/rdf_exporter'
|
9
|
+
require_relative 'exporters/markdown_service_exporter'
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module SDL
|
2
|
+
module Exporters
|
3
|
+
class Exporter
|
4
|
+
attr :compendium
|
5
|
+
attr :options
|
6
|
+
|
7
|
+
def initialize(compendium, options = {})
|
8
|
+
@compendium = compendium
|
9
|
+
@options = options
|
10
|
+
end
|
11
|
+
|
12
|
+
def export_to_file(path, content)
|
13
|
+
File.open(path, 'w') do |f|
|
14
|
+
f.write(content)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'rdf'
|
2
|
+
require 'rdf/rdfxml'
|
3
|
+
|
4
|
+
module SDL
|
5
|
+
module Exporters
|
6
|
+
class RDFExporter < ServiceExporter
|
7
|
+
@@s = RDF::Vocabulary.new('http://www.open-service-compendium.org/')
|
8
|
+
|
9
|
+
def export_service(service)
|
10
|
+
graph = RDF::Graph.new
|
11
|
+
|
12
|
+
service.facts.each do |fact|
|
13
|
+
graph << [RDF::URI.new(service.uri), @@s["has_#{fact.class.local_name.underscore}"], RDF::URI.new(fact.uri)]
|
14
|
+
|
15
|
+
expand_properties(fact, graph)
|
16
|
+
end
|
17
|
+
|
18
|
+
graph.dump(:rdf)
|
19
|
+
end
|
20
|
+
|
21
|
+
def expand_properties(type_instance, graph)
|
22
|
+
type_instance.property_values.each do |property, value|
|
23
|
+
[value].flatten.each do |v|
|
24
|
+
graph << [RDF::URI.new(type_instance.uri), @@s["#{property.name.underscore}"], v.rdf_object] unless v.nil?
|
25
|
+
end
|
26
|
+
|
27
|
+
if property.type < SDL::Base::Type
|
28
|
+
[value].flatten.each do |v| expand_properties(v, graph) end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'rdf'
|
2
|
+
require 'active_support/inflector'
|
3
|
+
|
4
|
+
[String, Fixnum, Nokogiri::XML::Element].each do |klass|
|
5
|
+
klass.class_eval do
|
6
|
+
def rdf_object
|
7
|
+
RDF::Literal.new(self)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module SDL
|
13
|
+
module Base
|
14
|
+
class Fact
|
15
|
+
class << self
|
16
|
+
def uri
|
17
|
+
"http://www.open-service-compendium.org/types/#{@local_name}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def uri
|
22
|
+
"#{service.uri}/#{self.class.local_name.underscore}-#{hash}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class Type
|
27
|
+
class << self
|
28
|
+
def uri
|
29
|
+
"http://www.open-service-compendium.org/types/#{@local_name}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def uri
|
34
|
+
self.class.uri + '/' + hash.to_s
|
35
|
+
end
|
36
|
+
|
37
|
+
def rdf_object
|
38
|
+
RDF::URI.new(uri)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class Service
|
43
|
+
def uri
|
44
|
+
"http://www.open-service-compendium.org/services/#{@symbolic_name}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module SDL
|
2
|
+
module Base
|
3
|
+
class Property
|
4
|
+
def xsd_element_name
|
5
|
+
if multi?
|
6
|
+
@name.singularize
|
7
|
+
else
|
8
|
+
@name
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Type
|
14
|
+
class << self
|
15
|
+
def xsd_element_name
|
16
|
+
local_name.camelize(:lower)
|
17
|
+
end
|
18
|
+
|
19
|
+
def xsd_type_name
|
20
|
+
local_name
|
21
|
+
end
|
22
|
+
|
23
|
+
def xsd_type_qname
|
24
|
+
'sdl:' + xsd_type_name
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class Fact
|
30
|
+
class << self
|
31
|
+
def xsd_type_name
|
32
|
+
"#{local_name}Fact"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
module Types
|
39
|
+
module SDLType
|
40
|
+
module ClassMethods
|
41
|
+
def xml_type
|
42
|
+
if self < SDL::Base::Type
|
43
|
+
wrapped_type.xsd_type_name
|
44
|
+
else
|
45
|
+
'ns:string'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module SDL
|
2
|
+
module Exporters
|
3
|
+
class XMLServiceExporter < ServiceExporter
|
4
|
+
def export_service(service)
|
5
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
6
|
+
xml.service('xmlns' => 'http://www.open-service-compendium.org') do
|
7
|
+
service.facts.each do |fact|
|
8
|
+
xml.send(fact.class.xsd_element_name + '_') do
|
9
|
+
serialize_type_instance fact, xml
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
builder.to_xml
|
16
|
+
end
|
17
|
+
|
18
|
+
def serialize_type_instance(type_instance, xml)
|
19
|
+
type_instance.property_values.each do |property, value|
|
20
|
+
[value].flatten.each do |v|
|
21
|
+
if v.class < SDL::Base::Type
|
22
|
+
xml.send(property.xsd_element_name + '_', (!value.is_a?(Array) && value.identifier) ? {'identifier' => value.identifier.to_s} : {}) do
|
23
|
+
v.annotations.each do |annotation|
|
24
|
+
xml.annotation annotation
|
25
|
+
end
|
26
|
+
xml.documentation v.documentation if (!value.is_a?(Array) && value.identifier)
|
27
|
+
serialize_type_instance(v, xml)
|
28
|
+
end
|
29
|
+
else
|
30
|
+
xml.send(property.xsd_element_name + '_', v)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'active_support/inflector'
|
2
|
+
require 'nokogiri'
|
3
|
+
|
4
|
+
module SDL
|
5
|
+
module Exporters
|
6
|
+
##
|
7
|
+
# The XSD schema exporter creates an XML Schema Definition for consuming service descriptions using the XML provided
|
8
|
+
# by the XMLServiceExporter.
|
9
|
+
#
|
10
|
+
# The schema consists of the following main components:
|
11
|
+
# - The definition of the root node, i.e., a service. The service contains an arbitrary number of elements of
|
12
|
+
# service fact types.
|
13
|
+
# - The definition of service fact classes and SDL types
|
14
|
+
# - The definition of a type base, containing annotations and documentation
|
15
|
+
class XSDSchemaExporter < SchemaExporter
|
16
|
+
def export_schema
|
17
|
+
export_schema_xml.to_xml
|
18
|
+
end
|
19
|
+
|
20
|
+
def export_schema_xml
|
21
|
+
Nokogiri::XML::Builder.new do |xml|
|
22
|
+
xml['ns'].schema('xmlns' => 'http://www.open-service-compendium.org', 'targetNamespace' => 'http://www.open-service-compendium.org', 'xmlns:ns' => 'http://www.w3.org/2001/XMLSchema', 'elementFormDefault' => 'qualified') do
|
23
|
+
xml['ns'].element :name => 'service' do
|
24
|
+
document(xml, I18n.t('sdl.xml.service_root'))
|
25
|
+
xml['ns'].complexType do
|
26
|
+
xml['ns'].choice :maxOccurs => 'unbounded' do
|
27
|
+
@compendium.fact_classes.each do |fact_class|
|
28
|
+
xml['ns'].element :name => fact_class.xsd_element_name, :type => fact_class.xsd_type_name do
|
29
|
+
document(xml, fact_class.documentation)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
xml['ns'].complexType :name => 'SDLTypeBase' do
|
37
|
+
document(xml, I18n.t('sdl.xml.typebase'))
|
38
|
+
xml['ns'].choice do
|
39
|
+
xml['ns'].element :name => 'documentation', :minOccurs => 0, :maxOccurs => 'unbounded', :type => 'ns:string' do
|
40
|
+
document(xml, I18n.t('sdl.xml.documentation'))
|
41
|
+
end
|
42
|
+
xml['ns'].element :name => 'annotation', :minOccurs => 0, :maxOccurs => 'unbounded', :type => 'ns:string' do
|
43
|
+
document(xml, I18n.t('sdl.xml.annotation'))
|
44
|
+
end
|
45
|
+
end
|
46
|
+
xml['ns'].attribute :name => 'identifier' do
|
47
|
+
document(xml, I18n.t('sdl.xml.identifier'))
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
(@compendium.fact_classes + @compendium.types).each do |fact_class|
|
52
|
+
xml['ns'].complexType :name => fact_class.xsd_type_name do
|
53
|
+
document(xml, fact_class.documentation)
|
54
|
+
xml['ns'].complexContent do
|
55
|
+
xml['ns'].extension :base => fact_class.is_sub? ? fact_class.superclass.xsd_type_name : 'SDLTypeBase' do
|
56
|
+
unless fact_class.properties.empty?
|
57
|
+
xml['ns'].sequence do
|
58
|
+
fact_class.properties.each do |property|
|
59
|
+
extend_property(property, xml) do
|
60
|
+
document(xml, property.documentation)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Creates an xml element corresponding to the SDL property
|
74
|
+
def extend_property(property, xml)
|
75
|
+
if property.multi?
|
76
|
+
xml['ns'].element :name => property.name.singularize, :type => property.type.xml_type, :minOccurs => 0, :maxOccurs => 'unbounded' do
|
77
|
+
yield
|
78
|
+
end
|
79
|
+
else
|
80
|
+
xml['ns'].element :name => property.name, :type => property.type.xml_type, :minOccurs => 0 do
|
81
|
+
yield
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# Shortcut for adding an XSD documentation annotation
|
87
|
+
def document(xml, documentation)
|
88
|
+
xml['ns'].annotation do
|
89
|
+
xml['ns'].documentation documentation
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require_relative 'receivers/type_instance_receiver'
|
2
|
+
require_relative 'receivers/type_receiver'
|
3
|
+
require_relative 'receivers/fact_receiver'
|
4
|
+
require_relative 'receivers/service_receiver'
|
5
|
+
|
6
|
+
|
7
|
+
module SDL
|
8
|
+
module Receivers
|
9
|
+
#
|
10
|
+
def self.set_value(type_class, type_instance, *property_values, compendium)
|
11
|
+
property_values.zip(type_class.properties(true)).each do |value, property|
|
12
|
+
if(value.is_a?(Hash))
|
13
|
+
TypeInstanceReceiver.new(type_instance, compendium).send(value.keys.first.to_s, value.values.first)
|
14
|
+
else
|
15
|
+
raise "Specified value '#{value}' for non-existing property." unless property
|
16
|
+
|
17
|
+
TypeInstanceReceiver.new(type_instance, compendium).send(property.name, value)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'verbs'
|
2
|
+
|
3
|
+
require_relative '../base/service'
|
4
|
+
|
5
|
+
module SDL
|
6
|
+
module Receivers
|
7
|
+
class ServiceReceiver
|
8
|
+
include ActiveSupport::Inflector
|
9
|
+
|
10
|
+
attr :service
|
11
|
+
attr :compendium
|
12
|
+
|
13
|
+
def initialize(sym, compendium)
|
14
|
+
@service = SDL::Base::Service.new(sym.to_s)
|
15
|
+
@compendium = compendium
|
16
|
+
|
17
|
+
compendium.fact_classes.each do |fact_class|
|
18
|
+
define_singleton_method("is_#{fact_class.local_name.underscore.verb.conjugate(:tense => :past, :person => :third, :plurality => :singular, :aspect => :perfective)}") do |*args, &block|
|
19
|
+
add_fact fact_class, *args, &block
|
20
|
+
end
|
21
|
+
|
22
|
+
define_singleton_method("has_#{fact_class.local_name.underscore}") do |*args, &block|
|
23
|
+
add_fact fact_class, *args, &block
|
24
|
+
end
|
25
|
+
|
26
|
+
define_singleton_method("#{fact_class.local_name.underscore}") do |*args, &block|
|
27
|
+
add_fact fact_class, *args, &block
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
def add_fact(fact_class, *property_values, &block)
|
34
|
+
fact_instance = fact_class.new
|
35
|
+
fact_instance.service = @service
|
36
|
+
|
37
|
+
SDL::Receivers.set_value(fact_class, fact_instance, *property_values, @compendium)
|
38
|
+
|
39
|
+
if block_given?
|
40
|
+
SDL::Receivers::TypeInstanceReceiver.new(fact_instance, @compendium).instance_eval &block
|
41
|
+
end
|
42
|
+
|
43
|
+
@service.facts << fact_instance
|
44
|
+
end
|
45
|
+
|
46
|
+
##
|
47
|
+
# Catches calls to methods named similarily to possible predefined type instances
|
48
|
+
def method_missing(name, *args)
|
49
|
+
possible_type_instances = @compendium.type_instances.map{|k, v| v[name]}.select{|v| v != nil}
|
50
|
+
|
51
|
+
unless possible_type_instances.nil? || possible_type_instances.empty?
|
52
|
+
if possible_type_instances.length > 1
|
53
|
+
raise Exception.new("Multiple possibilities for #{name} in #{caller[0]}")
|
54
|
+
else
|
55
|
+
possible_type_instances[0]
|
56
|
+
end
|
57
|
+
else
|
58
|
+
raise Exception.new("I do not know what to do with '#{name}' in #{caller[0]}")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'active_support/inflector'
|
2
|
+
|
3
|
+
module SDL
|
4
|
+
module Receivers
|
5
|
+
##
|
6
|
+
# Receiver for setting the properties of Type instances
|
7
|
+
class TypeInstanceReceiver
|
8
|
+
attr_accessor :instance
|
9
|
+
|
10
|
+
attr_accessor :compendium
|
11
|
+
|
12
|
+
##
|
13
|
+
# When initialized for a fact or type instance, the receiver creates singleton methods on itself for all
|
14
|
+
# properties.
|
15
|
+
def initialize(instance, compendium)
|
16
|
+
@instance = instance
|
17
|
+
@compendium = compendium
|
18
|
+
|
19
|
+
instance.class.properties(true).each do |property|
|
20
|
+
if property.single?
|
21
|
+
# Single valued properties are set by their name
|
22
|
+
define_singleton_method property.name do |value = nil, &block|
|
23
|
+
if value.is_a? Symbol
|
24
|
+
value = compendium.type_instances[property.type][value] || raise("Could not find instance :#{value.to_s} in predefined #{property.type.name} types")
|
25
|
+
end
|
26
|
+
|
27
|
+
instance.send "#{property.name}=", value
|
28
|
+
end
|
29
|
+
else
|
30
|
+
# Multi-valued properties are added to by their singular name
|
31
|
+
define_singleton_method property.name.singularize do |*property_values, &block|
|
32
|
+
existing_list = instance.send "#{property.name}"
|
33
|
+
|
34
|
+
unless property_values.empty?
|
35
|
+
# If there is just one parameter for a multi-valued property setter
|
36
|
+
if property_values.length == 1
|
37
|
+
# It could be a symbol, which would resolve to a predefined type instance of the same name
|
38
|
+
if property_values[0].is_a?(Symbol)
|
39
|
+
predefined_value = compendium.type_instances[property.type][property_values[0]]
|
40
|
+
|
41
|
+
raise "Could not find instance :#{property_values[0]} in predefined #{property.type.name} types" unless predefined_value
|
42
|
+
|
43
|
+
existing_list << compendium.type_instances[property.type][property_values[0]]
|
44
|
+
# Or better: it could already be an instance of the type - e.g. when using the implemented #method_mssing
|
45
|
+
elsif property_values[0].is_a? property.type
|
46
|
+
existing_list << property_values[0]
|
47
|
+
end
|
48
|
+
else
|
49
|
+
new_list_item = property.type.new
|
50
|
+
|
51
|
+
SDL::Receivers.set_value(property.type, new_list_item, *property_values, @compendium)
|
52
|
+
|
53
|
+
self.class.new(new_list_item, @compendium).instance_exec(&block) unless block.nil?
|
54
|
+
|
55
|
+
existing_list << new_list_item
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def annotation(value)
|
64
|
+
@instance.annotations << value
|
65
|
+
end
|
66
|
+
|
67
|
+
##
|
68
|
+
# Catches calls to methods named similarily to possible predefined type instances
|
69
|
+
def method_missing(name, *args)
|
70
|
+
# Possible type instances are all types of properties of properties of this instance ...
|
71
|
+
possible_type_classes = @instance.class.properties.map(&:type).map(&:properties).flatten.map(&:type).select{|type| type.wrapped_type < SDL::Base::Type}
|
72
|
+
|
73
|
+
# ... and the types of multi-value instances
|
74
|
+
possible_type_classes.concat(@instance.class.properties.find_all{|p| p.multi?}.map(&:type))
|
75
|
+
|
76
|
+
possible_type_instances = @compendium.type_instances.select{|k, v| possible_type_classes.include?(k)}.map{|k, v| v[name]}.select{|v| v != nil}
|
77
|
+
|
78
|
+
unless possible_type_instances.nil? || possible_type_instances.empty?
|
79
|
+
possible_type_instances[0]
|
80
|
+
else
|
81
|
+
raise Exception.new("I do not know what to do with '#{name}' in #{caller[0]}")
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|