sdl-ng 0.1.1 → 0.1.2
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 +4 -4
- data/.simplecov +7 -0
- data/bin/process_service_descriptions +35 -15
- data/lib/sdl/base/default_uri_mapper.rb +7 -3
- data/lib/sdl/base/fact.rb +4 -0
- data/lib/sdl/base/type.rb +6 -0
- data/lib/sdl/exporters.rb +0 -1
- data/lib/sdl/exporters/xml_mapping.rb +0 -4
- data/lib/sdl/exporters/xsd_schema_exporter.rb +16 -3
- data/lib/sdl/ng/version.rb +1 -1
- data/lib/sdl/receivers/service_receiver.rb +2 -0
- data/lib/sdl/receivers/type_instance_receiver.rb +31 -26
- data/lib/sdl/receivers/type_receiver.rb +4 -0
- data/lib/sdl/translations/en.yml +3 -1
- data/lib/sdl/types/sdl_description.rb +3 -1
- data/lib/sdl/util/documentation.rb +1 -1
- data/lib/sdl/util/nokogiri.rb +22 -17
- data/sdl-ng.gemspec +2 -1
- data/spec/bin_spec.rb +5 -6
- data/spec/documentation_spec.rb +13 -5
- data/spec/exporter_spec.rb +82 -0
- data/spec/fact_type_instance_definition_spec.rb +153 -3
- data/spec/nokogiri_spec.rb +54 -0
- data/spec/property_definitions_spec.rb +3 -1
- data/spec/service_compendium_spec.rb +1 -1
- data/spec/service_definition_spec.rb +33 -11
- data/spec/shared_test_compendium.rb +28 -0
- data/spec/shared_test_html.html +12 -0
- data/spec/shared_test_html.rb +11 -0
- data/spec/simple_types_spec.rb +55 -0
- data/spec/spec_helper.rb +6 -1
- data/spec/uri_mapping_spec.rb +76 -61
- metadata +28 -4
- data/lib/sdl/exporters/markdown_service_exporter.rb +0 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f05cf34193d34c129b79bf12f395678350f6366f
|
4
|
+
data.tar.gz: 5c06d5f6a525dd22c71d4cf298918f176c089602
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e60d8d666defcd7ccad82082db948c7b8d0f22743fd653d84aeed0376e9ccee9b1668d11838a827a79eb368df7eee574c78b1be9117fe2d39b33623cd80bb390
|
7
|
+
data.tar.gz: b7afec5669d7987b787ec2d161eeb210bf138f7a7cd641963cdbc3b09753be25bbbe0332784e43546cfcb5d328018c3e021c706a45b41cf1980be2ffdfc67f3d
|
data/.simplecov
ADDED
@@ -1,4 +1,25 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
require 'optparse'
|
3
|
+
|
4
|
+
profile = false
|
5
|
+
mock = false
|
6
|
+
OptionParser.new do |opts|
|
7
|
+
opts.banner = 'Usage: process_service_descriptions [-p]'
|
8
|
+
|
9
|
+
opts.on('-p', '--profile', 'Enable profiling') do |p|
|
10
|
+
profile = true
|
11
|
+
end
|
12
|
+
|
13
|
+
opts.on('-m', '--mock', 'Mock HTTP request') do |m|
|
14
|
+
mock = true
|
15
|
+
end
|
16
|
+
end.parse
|
17
|
+
|
18
|
+
if profile
|
19
|
+
require 'ruby-prof'
|
20
|
+
|
21
|
+
RubyProf.start
|
22
|
+
end
|
2
23
|
|
3
24
|
gem 'sdl-ng'
|
4
25
|
|
@@ -6,6 +27,14 @@ require 'sdl'
|
|
6
27
|
require 'active_support'
|
7
28
|
require 'i18n'
|
8
29
|
|
30
|
+
if mock
|
31
|
+
SDL::Util::NokogiriUtils.module_eval do
|
32
|
+
def fetch_from_url(url, *search)
|
33
|
+
[]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
9
38
|
# Make the translations for fact classes, instances, etc. known to the I18n framework
|
10
39
|
I18n.load_path << File.join(Dir.pwd, 'translations', 'en.yml')
|
11
40
|
|
@@ -30,11 +59,10 @@ end
|
|
30
59
|
|
31
60
|
puts "Loaded Service Compendium with #{compendium.services.count} services. Generating output"
|
32
61
|
|
33
|
-
%w[xml rdf
|
62
|
+
%w[xml rdf].each do |directory| FileUtils.mkdir_p File.join(Dir.pwd, 'output', directory) end
|
34
63
|
|
35
64
|
schema_exporter = SDL::Exporters::XSDSchemaExporter.new(compendium)
|
36
65
|
service_exporter = SDL::Exporters::XMLServiceExporter.new(compendium)
|
37
|
-
markdown_exporter = SDL::Exporters::MarkdownServiceExporter.new(compendium)
|
38
66
|
rdf_exporter = SDL::Exporters::RDFExporter.new(compendium)
|
39
67
|
|
40
68
|
schema_dir = Dir.pwd + '/output/xml/schema.xsd'
|
@@ -43,26 +71,14 @@ File.open(schema_dir, 'w') {|f|
|
|
43
71
|
puts "Written Service Compendium XSD schema into #{schema_dir}"
|
44
72
|
}
|
45
73
|
|
46
|
-
# Load XSD
|
47
|
-
xsd = Nokogiri::XML::Schema(File.read(Dir.pwd + '/output/xml/schema.xsd'))
|
48
|
-
|
49
74
|
compendium.services.each do |name, service|
|
50
75
|
xml_output_file = Dir.pwd + "/output/xml/#{name}.xml"
|
51
76
|
service_exporter.export_service_to_file service, xml_output_file
|
52
77
|
puts "Wrote XML export of service '#{name}' to #{xml_output_file}"
|
53
78
|
|
54
|
-
puts "Validating XML export against schema"
|
55
|
-
xsd.validate(Nokogiri::XML(File.read(Dir.pwd + "/output/xml/#{name}.xml"))).each do |error|
|
56
|
-
puts error.message
|
57
|
-
end
|
58
|
-
|
59
79
|
rdf_output_file = Dir.pwd + "/output/rdf/#{name}.rdf"
|
60
80
|
rdf_exporter.export_service_to_file service, rdf_output_file
|
61
81
|
puts "Wrote RDF export of service '#{name}' to #{rdf_output_file}"
|
62
|
-
|
63
|
-
markdown_output_file = Dir.pwd + "/output/markdown/#{name}.md"
|
64
|
-
markdown_exporter.export_service_to_file service, markdown_output_file
|
65
|
-
puts "Wrote Markdown export of service '#{name}' to #{markdown_output_file}"
|
66
82
|
end
|
67
83
|
|
68
84
|
all_needed_translations = {
|
@@ -99,4 +115,8 @@ File.open(translations_output_file, 'w') do |f|
|
|
99
115
|
puts "Wrote resulting translations file to #{translations_output_file}."
|
100
116
|
end
|
101
117
|
|
102
|
-
puts 'Finished'
|
118
|
+
puts 'Finished'
|
119
|
+
|
120
|
+
if profile
|
121
|
+
RubyProf::CallTreePrinter.new(RubyProf.stop).print(File.new('profile.kcachegrind', 'w'), {})
|
122
|
+
end
|
@@ -8,10 +8,14 @@ module SDL::Base
|
|
8
8
|
case object
|
9
9
|
when Type.class
|
10
10
|
"#{DEFAULT_BASE_URI}/types/#{object.local_name}"
|
11
|
-
when Type
|
12
|
-
object.class.uri + '/' + object.hash.to_s
|
13
11
|
when Fact
|
14
|
-
"#{object.service.uri}/#{object.class.local_name.underscore}
|
12
|
+
"#{object.service.uri}/#{object.class.local_name.underscore}/#{object.parent_index}"
|
13
|
+
when Type
|
14
|
+
if object.identifier
|
15
|
+
"#{object.class.uri}/#{object.identifier.to_s}"
|
16
|
+
else
|
17
|
+
"#{object.parent.uri}/#{object.class.local_name}/#{object.parent_index}"
|
18
|
+
end
|
15
19
|
when Service
|
16
20
|
"#{DEFAULT_BASE_URI}/services/#{object.symbolic_name}"
|
17
21
|
else
|
data/lib/sdl/base/fact.rb
CHANGED
data/lib/sdl/base/type.rb
CHANGED
data/lib/sdl/exporters.rb
CHANGED
@@ -17,10 +17,23 @@ class SDL::Exporters::XSDSchemaExporter < SDL::Exporters::SchemaExporter
|
|
17
17
|
def export_schema_xml
|
18
18
|
Nokogiri::XML::Builder.new do |xml|
|
19
19
|
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
|
20
|
-
xml['ns'].element :name => '
|
21
|
-
document(xml, I18n.t('sdl.xml.
|
20
|
+
xml['ns'].element :name => 'services' do
|
21
|
+
document(xml, I18n.t('sdl.xml.services_root'))
|
22
22
|
xml['ns'].complexType do
|
23
|
-
xml['ns'].
|
23
|
+
xml['ns'].sequence do
|
24
|
+
xml['ns'].element :name=> 'service', :type => 'Service', :minOccurs => 0, :maxOccurs => :unbounded
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
xml['ns'].element :name => 'service', :type => 'Service' do
|
30
|
+
document(xml, I18n.t('sdl.xml.service_root'))
|
31
|
+
end
|
32
|
+
|
33
|
+
xml['ns'].complexType :name => 'Service' do
|
34
|
+
document(xml, I18n.t('sdl.xml.service_class'))
|
35
|
+
xml['ns'].sequence do
|
36
|
+
xml['ns'].choice :maxOccurs => :unbounded do
|
24
37
|
@compendium.fact_classes.each do |fact_class|
|
25
38
|
xml['ns'].element :name => fact_class.xsd_element_name, :type => fact_class.xsd_type_name do
|
26
39
|
document(xml, fact_class.documentation)
|
data/lib/sdl/ng/version.rb
CHANGED
@@ -6,12 +6,12 @@ class SDL::Receivers::TypeInstanceReceiver < SDL::Receivers::Receiver
|
|
6
6
|
##
|
7
7
|
# When initialized for a fact or type instance, the receiver creates singleton methods on itself for all
|
8
8
|
# properties.
|
9
|
-
def initialize(
|
9
|
+
def initialize(type_instance, compendium)
|
10
10
|
super(compendium)
|
11
11
|
|
12
|
-
@instance =
|
12
|
+
@instance = type_instance
|
13
13
|
|
14
|
-
|
14
|
+
type_instance.class.properties(true).each do |property|
|
15
15
|
if property.single?
|
16
16
|
# Single valued properties are set by their name
|
17
17
|
define_singleton_method property.name do |value = nil, &block|
|
@@ -20,39 +20,44 @@ class SDL::Receivers::TypeInstanceReceiver < SDL::Receivers::Receiver
|
|
20
20
|
end
|
21
21
|
|
22
22
|
begin
|
23
|
-
|
23
|
+
type_instance.send "#{property.name}=", value
|
24
24
|
rescue RuntimeError => e
|
25
25
|
raise RuntimeError, "Cannot set property '#{property.name}' of Type #{@instance.class.name}: #{e}", e.backtrace
|
26
26
|
end
|
27
27
|
end
|
28
28
|
else
|
29
|
-
# Multi-valued properties are added to by their singular name
|
29
|
+
# Multi-valued properties are added to by their singular name, e.g. 'browsers' is set by invoking 'browser'
|
30
30
|
define_singleton_method property.name.singularize do |*property_values, &block|
|
31
|
-
existing_list =
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
predefined_value = compendium.type_instances[property.type][property_values[0]]
|
39
|
-
|
40
|
-
raise "Could not find instance :#{property_values[0]} in predefined #{property.type.name} types" unless predefined_value
|
41
|
-
|
42
|
-
existing_list << compendium.type_instances[property.type][property_values[0]]
|
43
|
-
# Or better: it could already be an instance of the type - e.g. when using the implemented #method_mssing
|
44
|
-
elsif property_values[0].is_a? property.type
|
45
|
-
existing_list << property_values[0]
|
46
|
-
end
|
47
|
-
else
|
48
|
-
new_list_item = property.type.new
|
31
|
+
existing_list = type_instance.send "#{property.name}"
|
32
|
+
|
33
|
+
# If there is just one parameter for a multi-valued property setter
|
34
|
+
if property_values.length == 1
|
35
|
+
# It could be a symbol, which would resolve to a predefined type instance of the same name
|
36
|
+
if property_values[0].is_a?(Symbol)
|
37
|
+
predefined_value = compendium.type_instances[property.type][property_values[0]]
|
49
38
|
|
50
|
-
|
39
|
+
raise "Could not find instance :#{property_values[0]} in predefined #{property.type.name} types" unless predefined_value
|
51
40
|
|
52
|
-
|
41
|
+
existing_list << compendium.type_instances[property.type][property_values[0]]
|
42
|
+
# Or better: it could already be an instance of the type - e.g. when using the implemented #method_mssing
|
43
|
+
elsif property_values[0].is_a? property.type
|
44
|
+
existing_list << property_values[0]
|
53
45
|
|
54
|
-
existing_list
|
46
|
+
property_values[0].parent_index = existing_list.count - 1 unless property_values[0].identifier
|
47
|
+
else
|
48
|
+
raise "Type #{property_values[0].class} of list item '#{property_values}' is incompatible with list type #{property.type}."
|
55
49
|
end
|
50
|
+
else
|
51
|
+
new_list_item = property.type.new
|
52
|
+
|
53
|
+
set_value(property.type, new_list_item, *property_values)
|
54
|
+
|
55
|
+
SDL::Receivers::TypeInstanceReceiver.new(new_list_item, @compendium).instance_exec(&block) unless block.nil?
|
56
|
+
|
57
|
+
existing_list << new_list_item
|
58
|
+
|
59
|
+
new_list_item.parent = type_instance
|
60
|
+
new_list_item.parent_index = existing_list.count - 1
|
56
61
|
end
|
57
62
|
end
|
58
63
|
end
|
@@ -67,6 +67,8 @@ class SDL::Receivers::TypeReceiver < SDL::Receivers::Receiver
|
|
67
67
|
private
|
68
68
|
##
|
69
69
|
# Adds accessors to set the property to the target class.
|
70
|
+
#
|
71
|
+
# These accessors set the instance variable to the given value and set the parent of the value to self.
|
70
72
|
def add_property(sym, type, multi)
|
71
73
|
unless multi
|
72
74
|
@klass.class_eval do
|
@@ -78,6 +80,8 @@ class SDL::Receivers::TypeReceiver < SDL::Receivers::Receiver
|
|
78
80
|
instance_variable_set "@#{sym}".to_s, type.new(value)
|
79
81
|
else
|
80
82
|
instance_variable_set "@#{sym}".to_s, value
|
83
|
+
|
84
|
+
value.parent = self
|
81
85
|
end
|
82
86
|
end
|
83
87
|
end
|
data/lib/sdl/translations/en.yml
CHANGED
@@ -7,5 +7,7 @@ en:
|
|
7
7
|
annotation: An arbitrary annotation to be displayed for the description consumer.
|
8
8
|
documentation: The documentation of this type or fact instance.
|
9
9
|
identifier: An identifier for a type instance. Two instances are the same, if they share the same identifier.
|
10
|
-
|
10
|
+
services_root: A list of services.
|
11
|
+
service_root: The root element of a service.
|
12
|
+
service_class: A service. It contains an arbitrary number of facts.
|
11
13
|
typebase: The base type of all SDL types and facts. Contains annotations and documentation.
|
@@ -20,8 +20,10 @@ class SDL::Types::SDLDescription < SDL::Types::SDLSimpleType
|
|
20
20
|
@raw_value.to_s
|
21
21
|
when NilClass
|
22
22
|
''
|
23
|
+
when String
|
24
|
+
@value
|
23
25
|
else
|
24
|
-
"Cannot convert #{@raw_value.class} to HTML. Please extend SDLDescription#to_html"
|
26
|
+
raise "Cannot convert #{@raw_value.class} to HTML. Please extend SDLDescription#to_html"
|
25
27
|
end
|
26
28
|
end
|
27
29
|
end
|
@@ -85,7 +85,7 @@ module SDL::Base
|
|
85
85
|
def documentation_key
|
86
86
|
# Search class and ancestors, if any defines a documentation key
|
87
87
|
@holder.ancestors.each do |ancestor|
|
88
|
-
break if ancestor.eql?
|
88
|
+
break if ancestor.eql?(SDL::Base::Type) || ancestor.eql?(SDL::Types::SDLType)
|
89
89
|
|
90
90
|
key = "sdl.property.#{SDL::Util::Documentation.walk_the_class_name(ancestor)}.#{@name}"
|
91
91
|
|
data/lib/sdl/util/nokogiri.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'nokogiri'
|
2
|
+
require 'socket'
|
2
3
|
require 'open-uri'
|
3
4
|
|
4
5
|
module SDL
|
@@ -7,30 +8,34 @@ module SDL
|
|
7
8
|
##
|
8
9
|
# Fetches an Nokogiri::XML::NodeSet from the webpage at url by performing *search
|
9
10
|
#
|
10
|
-
# Additionally it converts all relative href URLs to absolute URLs and adds a 'target' attribute to all
|
11
|
-
# links, so that they open in a new browser window and not the current broker.
|
12
11
|
def fetch_from_url(url, *search)
|
13
12
|
begin
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
fetch_from_io open(url), url, *search
|
14
|
+
rescue SocketError => e
|
15
|
+
[]
|
16
|
+
end
|
17
|
+
end
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
rescue URI::InvalidURIError
|
22
|
-
next
|
23
|
-
end
|
19
|
+
def fetch_from_io(io, base_url, *search)
|
20
|
+
process_result Nokogiri::HTML(io).search(*search), base_url
|
21
|
+
end
|
24
22
|
|
25
|
-
|
26
|
-
|
27
|
-
|
23
|
+
# It converts all relative href URLs to absolute URLs and adds a 'target' attribute to all
|
24
|
+
# links, so that they open in a new browser window and not the current broker.
|
25
|
+
def process_result(result, base_url)
|
26
|
+
result.search('//body//@href').each do |attribute|
|
27
|
+
begin
|
28
|
+
attribute.content = URI.join(base_url, attribute.value.gsub(/\s/, '')).to_s
|
29
|
+
rescue URI::InvalidURIError
|
30
|
+
next
|
28
31
|
end
|
29
32
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
+
if attribute.parent.name.eql? 'a'
|
34
|
+
attribute.parent['target'] = '_new'
|
35
|
+
end
|
33
36
|
end
|
37
|
+
|
38
|
+
result
|
34
39
|
end
|
35
40
|
end
|
36
41
|
end
|
data/sdl-ng.gemspec
CHANGED
@@ -22,7 +22,8 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.add_runtime_dependency 'activesupport', '~> 4.0'
|
23
23
|
spec.add_runtime_dependency 'nokogiri', '~> 1.6'
|
24
24
|
spec.add_runtime_dependency 'verbs', '~> 2.1'
|
25
|
-
spec.add_runtime_dependency '
|
25
|
+
spec.add_runtime_dependency 'rdf', '~> 1.1'
|
26
|
+
spec.add_runtime_dependency 'rdf-rdfxml', '~> 1.1'
|
26
27
|
|
27
28
|
spec.add_development_dependency 'yard', '~> 0.8.7.3'
|
28
29
|
spec.add_development_dependency 'yard-redcarpet-ext', '~> 0.0.3'
|
data/spec/bin_spec.rb
CHANGED
@@ -1,14 +1,13 @@
|
|
1
|
-
require_relative '../lib/sdl'
|
2
1
|
require_relative 'spec_helper'
|
3
2
|
|
4
3
|
require 'rspec'
|
5
4
|
|
6
5
|
describe 'The process_service_descriptions binary script' do
|
7
6
|
it 'can be executed' do
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
Dir.chdir(File.join(__dir__, '..', 'examples')) do
|
8
|
+
expect {
|
9
|
+
load File.join(__dir__, '..', 'bin', 'process_service_descriptions')
|
10
|
+
}.not_to raise_exception
|
11
|
+
end
|
13
12
|
end
|
14
13
|
end
|