sdl-ng 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|