scorm2004-manifest 0.1.0
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.
- data/.document +5 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +36 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +94 -0
- data/Rakefile +39 -0
- data/VERSION +1 -0
- data/lib/scorm2004/manifest/adlseq_map_info.rb +17 -0
- data/lib/scorm2004/manifest/adlseq_objective.rb +14 -0
- data/lib/scorm2004/manifest/adlseq_objectives.rb +11 -0
- data/lib/scorm2004/manifest/attributes.rb +147 -0
- data/lib/scorm2004/manifest/children.rb +83 -0
- data/lib/scorm2004/manifest/completion_threshold.rb +13 -0
- data/lib/scorm2004/manifest/condition_rule.rb +12 -0
- data/lib/scorm2004/manifest/constrained_choice_considerations.rb +12 -0
- data/lib/scorm2004/manifest/control_mode.rb +16 -0
- data/lib/scorm2004/manifest/custom_error.rb +15 -0
- data/lib/scorm2004/manifest/data.rb +11 -0
- data/lib/scorm2004/manifest/data_from_lms.rb +21 -0
- data/lib/scorm2004/manifest/delivery_controls.rb +13 -0
- data/lib/scorm2004/manifest/dependency.rb +21 -0
- data/lib/scorm2004/manifest/error.rb +5 -0
- data/lib/scorm2004/manifest/file.rb +16 -0
- data/lib/scorm2004/manifest/hide_lmsui.rb +21 -0
- data/lib/scorm2004/manifest/href.rb +24 -0
- data/lib/scorm2004/manifest/item.rb +36 -0
- data/lib/scorm2004/manifest/limit_conditions.rb +12 -0
- data/lib/scorm2004/manifest/manifest.rb +26 -0
- data/lib/scorm2004/manifest/map.rb +13 -0
- data/lib/scorm2004/manifest/map_info.rb +15 -0
- data/lib/scorm2004/manifest/min_normalized_measure.rb +18 -0
- data/lib/scorm2004/manifest/navigation_interface.rb +10 -0
- data/lib/scorm2004/manifest/objective.rb +16 -0
- data/lib/scorm2004/manifest/objectives.rb +12 -0
- data/lib/scorm2004/manifest/organization.rb +20 -0
- data/lib/scorm2004/manifest/organizations.rb +24 -0
- data/lib/scorm2004/manifest/presentation.rb +10 -0
- data/lib/scorm2004/manifest/primary_objective.rb +24 -0
- data/lib/scorm2004/manifest/randomization_controls.rb +16 -0
- data/lib/scorm2004/manifest/resource.rb +18 -0
- data/lib/scorm2004/manifest/resources.rb +12 -0
- data/lib/scorm2004/manifest/rollup_action.rb +13 -0
- data/lib/scorm2004/manifest/rollup_condition.rb +24 -0
- data/lib/scorm2004/manifest/rollup_conditions.rb +14 -0
- data/lib/scorm2004/manifest/rollup_considerations.rb +17 -0
- data/lib/scorm2004/manifest/rollup_rule.rb +19 -0
- data/lib/scorm2004/manifest/rollup_rules.rb +16 -0
- data/lib/scorm2004/manifest/rule_action.rb +31 -0
- data/lib/scorm2004/manifest/rule_condition.rb +41 -0
- data/lib/scorm2004/manifest/rule_conditions.rb +14 -0
- data/lib/scorm2004/manifest/schema.rb +18 -0
- data/lib/scorm2004/manifest/schemaversion.rb +18 -0
- data/lib/scorm2004/manifest/sequencing.rb +24 -0
- data/lib/scorm2004/manifest/sequencing_collection.rb +11 -0
- data/lib/scorm2004/manifest/sequencing_rules.rb +13 -0
- data/lib/scorm2004/manifest/text_node.rb +11 -0
- data/lib/scorm2004/manifest/time_limit_action.rb +24 -0
- data/lib/scorm2004/manifest/title.rb +16 -0
- data/lib/scorm2004/manifest/visitor_pattern.rb +31 -0
- data/lib/scorm2004/manifest/xml_base.rb +38 -0
- data/lib/scorm2004/manifest.rb +76 -0
- data/lib/scorm2004-manifest.rb +1 -0
- data/test/functional_test.rb +45 -0
- data/test/helper.rb +18 -0
- data/test/mbce_test.rb +66 -0
- data/test/msce_test.rb +55 -0
- data/test/scorm2004/manifest/adlseq_map_info_test.rb +47 -0
- data/test/scorm2004/manifest/adlseq_objective_test.rb +44 -0
- data/test/scorm2004/manifest/adlseq_objectives_test.rb +29 -0
- data/test/scorm2004/manifest/any_uri_token_test.rb +40 -0
- data/test/scorm2004/manifest/attributes_test.rb +224 -0
- data/test/scorm2004/manifest/children_test.rb +330 -0
- data/test/scorm2004/manifest/completion_threshold_test.rb +80 -0
- data/test/scorm2004/manifest/condition_rule_test.rb +40 -0
- data/test/scorm2004/manifest/constrained_choice_considerations_test.rb +25 -0
- data/test/scorm2004/manifest/control_mode_test.rb +41 -0
- data/test/scorm2004/manifest/custom_error_test.rb +43 -0
- data/test/scorm2004/manifest/data_from_lms_test.rb +47 -0
- data/test/scorm2004/manifest/data_test.rb +31 -0
- data/test/scorm2004/manifest/delivery_controls_test.rb +27 -0
- data/test/scorm2004/manifest/dependency_test.rb +53 -0
- data/test/scorm2004/manifest/duration_attribute_test.rb +59 -0
- data/test/scorm2004/manifest/file_test.rb +40 -0
- data/test/scorm2004/manifest/hide_lmsui_test.rb +40 -0
- data/test/scorm2004/manifest/href_test.rb +43 -0
- data/test/scorm2004/manifest/item_test.rb +86 -0
- data/test/scorm2004/manifest/limit_conditions_test.rb +34 -0
- data/test/scorm2004/manifest/manifest_test.rb +152 -0
- data/test/scorm2004/manifest/map_info_test.rb +41 -0
- data/test/scorm2004/manifest/map_test.rb +32 -0
- data/test/scorm2004/manifest/min_normalized_measure_test.rb +28 -0
- data/test/scorm2004/manifest/navigation_interface_test.rb +29 -0
- data/test/scorm2004/manifest/non_negative_integer_attribute_test.rb +64 -0
- data/test/scorm2004/manifest/objective_test.rb +45 -0
- data/test/scorm2004/manifest/objectives_test.rb +37 -0
- data/test/scorm2004/manifest/organization_test.rb +115 -0
- data/test/scorm2004/manifest/organizations_test.rb +68 -0
- data/test/scorm2004/manifest/partial_manifest.rb +23 -0
- data/test/scorm2004/manifest/partial_manifest_test.rb +44 -0
- data/test/scorm2004/manifest/presentation_test.rb +26 -0
- data/test/scorm2004/manifest/primary_objective_test.rb +65 -0
- data/test/scorm2004/manifest/randomization_controls_test.rb +71 -0
- data/test/scorm2004/manifest/resource_test.rb +96 -0
- data/test/scorm2004/manifest/resources_test.rb +41 -0
- data/test/scorm2004/manifest/rollup_action_test.rb +33 -0
- data/test/scorm2004/manifest/rollup_condition_test.rb +42 -0
- data/test/scorm2004/manifest/rollup_conditions_test.rb +53 -0
- data/test/scorm2004/manifest/rollup_considerations_test.rb +42 -0
- data/test/scorm2004/manifest/rollup_rule_test.rb +87 -0
- data/test/scorm2004/manifest/rollup_rules_test.rb +60 -0
- data/test/scorm2004/manifest/rule_action_test.rb +79 -0
- data/test/scorm2004/manifest/rule_condition_test.rb +70 -0
- data/test/scorm2004/manifest/rule_conditions_test.rb +37 -0
- data/test/scorm2004/manifest/schema_test.rb +29 -0
- data/test/scorm2004/manifest/schemaversion_test.rb +29 -0
- data/test/scorm2004/manifest/sequencing_collection_test.rb +31 -0
- data/test/scorm2004/manifest/sequencing_rules_test.rb +36 -0
- data/test/scorm2004/manifest/sequencing_test.rb +42 -0
- data/test/scorm2004/manifest/string_attribute_test.rb +68 -0
- data/test/scorm2004/manifest/text_node_test.rb +37 -0
- data/test/scorm2004/manifest/time_limit_action_test.rb +51 -0
- data/test/scorm2004/manifest/title_test.rb +59 -0
- data/test/scorm2004/manifest/token_attribute_test.rb +53 -0
- data/test/scorm2004/manifest/visitor_pattern_test.rb +85 -0
- data/test/scorm2004/manifest/xml_base_test.rb +125 -0
- data/test/scorm2004/manifest_test.rb +33 -0
- data/test/scorm2004_test.rb +9 -0
- data/test/sece_test.rb +53 -0
- metadata +260 -0
data/.document
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
activesupport (3.2.2)
|
5
|
+
i18n (~> 0.6)
|
6
|
+
multi_json (~> 1.0)
|
7
|
+
git (1.2.5)
|
8
|
+
i18n (0.6.0)
|
9
|
+
jeweler (1.8.3)
|
10
|
+
bundler (~> 1.0)
|
11
|
+
git (>= 1.2.5)
|
12
|
+
rake
|
13
|
+
rdoc
|
14
|
+
json (1.6.5)
|
15
|
+
metaclass (0.0.1)
|
16
|
+
mocha (0.10.5)
|
17
|
+
metaclass (~> 0.0.1)
|
18
|
+
multi_json (1.1.0)
|
19
|
+
nokogiri (1.5.2)
|
20
|
+
rake (0.9.2.2)
|
21
|
+
rdoc (3.12)
|
22
|
+
json (~> 1.4)
|
23
|
+
shoulda-context (1.0.0)
|
24
|
+
yard (0.7.5)
|
25
|
+
|
26
|
+
PLATFORMS
|
27
|
+
ruby
|
28
|
+
|
29
|
+
DEPENDENCIES
|
30
|
+
activesupport
|
31
|
+
bundler (~> 1.1.0)
|
32
|
+
jeweler (~> 1.8.3)
|
33
|
+
mocha (~> 0.10.4)
|
34
|
+
nokogiri
|
35
|
+
shoulda-context (~> 1.0)
|
36
|
+
yard (~> 0.7)
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Takahiro Noda
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
= scorm2004-manifest
|
2
|
+
|
3
|
+
* https://github.com/tnoda/scorm2004-manifest
|
4
|
+
|
5
|
+
== Description
|
6
|
+
|
7
|
+
+scorm2004-manifest+ is a Ruby gem that provides a manifest file parser for SCORM 2004 4th edition. It parses and validates the manifest file according to SCORM 2004 4th Edition Content Aggregation Model (CAM) Version 1.1. After parsing and validating, it builds an object tree that captures XML's hierarchical structure.
|
8
|
+
|
9
|
+
== Installation
|
10
|
+
|
11
|
+
To install scorm2004-manifest, use the following command:
|
12
|
+
|
13
|
+
$ gem install scorm2004-manifest
|
14
|
+
|
15
|
+
== Requirements
|
16
|
+
|
17
|
+
* ruby 1.9.3
|
18
|
+
* nokogiri
|
19
|
+
* activesupport
|
20
|
+
|
21
|
+
|
22
|
+
== Synopsis
|
23
|
+
|
24
|
+
require 'scorm2004-manifest'
|
25
|
+
|
26
|
+
# Parse a manifest file
|
27
|
+
manifest = Scorm2004::Manifest(open('imsmanifest.xml'))
|
28
|
+
|
29
|
+
# Traverse an object tree
|
30
|
+
manifest.identifier # => "LMSTestPackage_CM-01"
|
31
|
+
manifest.version # => "1.1.1"
|
32
|
+
organizations = manifest.organizations
|
33
|
+
organization = organizations.organizations[0]
|
34
|
+
organization.identifier # => "CM-01"
|
35
|
+
organization.title.content # => "LMS Test Content Package CM-01 "
|
36
|
+
item_0 = organization.items[0]
|
37
|
+
item_0.title.content # => "Activity 1"
|
38
|
+
item_0.identifier # => "activity_1"
|
39
|
+
item_0.identifierref # => "SEQ01"
|
40
|
+
item_0.parameters # => "?tc=CM-01&act=1"
|
41
|
+
item_0.sequencing.limit_conditions.attempt_absolute_duration_limit
|
42
|
+
# => "P5Y6M4DT12H30M58S"
|
43
|
+
item_0.presentation.navigation_interface.hide_lmsuis.map(&:content)
|
44
|
+
# => ["continue", "previous", "suspendAll"]
|
45
|
+
# ...
|
46
|
+
|
47
|
+
For every XML element in a manifest file, XML attributes and
|
48
|
+
child elements defined in Content Aggregation Model can be
|
49
|
+
accessed using accessor methods whose names are underscored.
|
50
|
+
Namespace prefixes are omitted from the accessor methods,
|
51
|
+
except for either +adlseq_objectives+, +adlseq_objective+,
|
52
|
+
or +adlseq_map_info+.
|
53
|
+
If an element may have multiple child elements,
|
54
|
+
the accessor method for the child elements will be pluralized.
|
55
|
+
For example, <organizations> element has one or more
|
56
|
+
<organization> elements.
|
57
|
+
|
58
|
+
# <organizations> can be accessed using the organizations
|
59
|
+
# method of the manifest object.
|
60
|
+
organizations = manifest.organizations
|
61
|
+
|
62
|
+
# The <organization> collection of the <organizations>
|
63
|
+
# element can be accessed using the organizations method
|
64
|
+
# of the organizations object. To get the first
|
65
|
+
# <organization> of the <organizations>, use the
|
66
|
+
# following expression.
|
67
|
+
organization_0 = organizations.organizations[0]
|
68
|
+
|
69
|
+
|
70
|
+
== Documentation
|
71
|
+
|
72
|
+
To generate scorm2004-manifest's document set, use the following command:
|
73
|
+
|
74
|
+
$ git clone git://github.com/tnoda/scorm2004-manifest.git
|
75
|
+
$ cd scorm2004-manifest
|
76
|
+
$ rake yard
|
77
|
+
|
78
|
+
The document set will be generated under the +doc+ directory.
|
79
|
+
|
80
|
+
|
81
|
+
== Contributing to scorm2004-manifest
|
82
|
+
|
83
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
84
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
85
|
+
* Fork the project.
|
86
|
+
* Start a feature/bugfix branch.
|
87
|
+
* Commit and push until you are happy with your contribution.
|
88
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
89
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
90
|
+
|
91
|
+
|
92
|
+
== Copyright
|
93
|
+
|
94
|
+
Copyright (c) 2012 Takahiro Noda. See LICENSE.txt for further details.
|
data/Rakefile
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
+
gem.name = "scorm2004-manifest"
|
18
|
+
gem.homepage = "https://github.com/tnoda/scorm2004-manifest"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = %Q{A manifest file parser/validator for SCORM 2004 4th Edition}
|
21
|
+
gem.description = <<EOS
|
22
|
+
scorm2004-manifest is a Ruby gem that provides a manifest file parser for SCORM 2004 4th edition. It parses and validates the manifest file according to SCORM 2004 4th Edition Content Aggregation Model (CAM) Version 1.1. After parsing and validating, it builds an object tree that captures XML's hierarchical structure.
|
23
|
+
EOS
|
24
|
+
gem.email = "takahiro.noda+rubygems@gmail.com"
|
25
|
+
gem.authors = ["Takahiro Noda"]
|
26
|
+
end
|
27
|
+
Jeweler::RubygemsDotOrgTasks.new
|
28
|
+
|
29
|
+
require 'rake/testtask'
|
30
|
+
Rake::TestTask.new(:test) do |test|
|
31
|
+
test.libs << 'lib' << 'test'
|
32
|
+
test.pattern = 'test/**/*_test.rb'
|
33
|
+
test.verbose = true
|
34
|
+
end
|
35
|
+
|
36
|
+
task :default => :test
|
37
|
+
|
38
|
+
require 'yard'
|
39
|
+
YARD::Rake::YardocTask.new
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Scorm2004
|
2
|
+
module Manifest
|
3
|
+
class AdlseqMapInfo
|
4
|
+
include VisitorPattern
|
5
|
+
include CustomError
|
6
|
+
include Attributes
|
7
|
+
|
8
|
+
attribute :any_uri, 'targetObjectiveID'
|
9
|
+
|
10
|
+
SLOTS = %w( RawScore MinScore MaxScore CompletionStatus ProgressMeasure )
|
11
|
+
%w( read write ).product(SLOTS).map(&:join).each do |attr|
|
12
|
+
default_value = /^read/ =~ attr ? true : false
|
13
|
+
attribute :boolean, attr, default: default_value
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Scorm2004
|
2
|
+
module Manifest
|
3
|
+
class AdlseqObjective
|
4
|
+
include VisitorPattern
|
5
|
+
include CustomError
|
6
|
+
include Children
|
7
|
+
include Attributes
|
8
|
+
|
9
|
+
attribute :any_uri, 'objectiveID'
|
10
|
+
|
11
|
+
has_one_or_more 'adlseq:mapInfo', visitor: :adlseq_map_info
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
module Scorm2004
|
2
|
+
module Manifest
|
3
|
+
module Attributes
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def replace_and_collapse_whitespaces(string)
|
11
|
+
string.gsub(/\s+/, ' ').gsub(/^ | $/, '')
|
12
|
+
end
|
13
|
+
|
14
|
+
def xs_id?(str)
|
15
|
+
(/\s|^\d+$/ =~ str).nil?
|
16
|
+
end
|
17
|
+
|
18
|
+
def xs_non_negative_integer?(string)
|
19
|
+
/^\+?\d+$/ =~ string
|
20
|
+
end
|
21
|
+
|
22
|
+
def xs_duration?(string)
|
23
|
+
/^(\+|-)?P(((\d+Y)?(\d+M)?(\d+D)?(T(\d+H)?(\d+M)?(\d+(\.\d+)?S)?)?)|(\d+W))$/ =~ string
|
24
|
+
end
|
25
|
+
|
26
|
+
module ClassMethods
|
27
|
+
def attributes
|
28
|
+
@attributes ||= []
|
29
|
+
end
|
30
|
+
|
31
|
+
def attribute(type, name, options = {})
|
32
|
+
base = basename(name)
|
33
|
+
attributes << base
|
34
|
+
define_method("raw_#{base}") do
|
35
|
+
el.at("./@#{name}").try(:content) || options[:default].try(:to_s)
|
36
|
+
end
|
37
|
+
send("#{type}_attribute", name, options)
|
38
|
+
attr_reader base
|
39
|
+
end
|
40
|
+
|
41
|
+
def boolean_attribute(name, options)
|
42
|
+
base = basename(name)
|
43
|
+
define_method("check_#{base}".intern) do
|
44
|
+
raw = send("raw_#{base}")
|
45
|
+
error("No #{name} attribute.") if raw.nil?
|
46
|
+
unless %( true false 1 0 ).include?(raw)
|
47
|
+
error("Non xs:boolean value for the #{name}: #{raw}")
|
48
|
+
end
|
49
|
+
instance_variable_set("@#{base}".intern, %( true 1 ).include?(raw))
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def string_attribute(name, options)
|
54
|
+
base = basename(name)
|
55
|
+
define_method("check_#{base}".intern) do
|
56
|
+
raw = send("raw_#{base}")
|
57
|
+
error("No #{name} attribute.") unless options[:allow_nil] || raw
|
58
|
+
if options[:spm] && raw.length > options[:spm]
|
59
|
+
error("The length of #{name} exceeds the SPM of #{options[:spm]} characters.")
|
60
|
+
end
|
61
|
+
instance_variable_set("@#{base}".intern, raw)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def id_attribute(name, options)
|
66
|
+
base = basename(name)
|
67
|
+
define_method("check_#{base}".intern) do
|
68
|
+
raw = send("raw_#{base}")
|
69
|
+
error("No #{name} attribute.") unless options[:allow_nil] || raw
|
70
|
+
error("Non xs:ID value for the #{name} attribute: #{raw}") unless xs_id?(raw)
|
71
|
+
instance_variable_set("@#{base}".intern, raw)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
alias :idref_attribute :id_attribute
|
75
|
+
|
76
|
+
def decimal_attribute(name, options)
|
77
|
+
base = basename(name)
|
78
|
+
define_method("check_#{base}".intern) do
|
79
|
+
raw = send("raw_#{base}".intern)
|
80
|
+
return if options[:allow_nil] && raw.nil?
|
81
|
+
error("No #{name} attribute.") if raw.nil?
|
82
|
+
if options[:range] && !options[:range].include?(Float(raw))
|
83
|
+
error("The decimal attribute, #{name}, out of range (#{options[:range]}): #{raw}")
|
84
|
+
end
|
85
|
+
instance_variable_set("@#{base}".intern, Float(raw))
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def non_negative_integer_attribute(name, options)
|
90
|
+
base = basename(name)
|
91
|
+
define_method("check_#{base}".intern) do
|
92
|
+
raw = send("raw_#{base}".intern)
|
93
|
+
return if options[:allow_nil] && raw.nil?
|
94
|
+
error("No #{name} attribute.") if raw.nil?
|
95
|
+
unless xs_non_negative_integer?(raw)
|
96
|
+
error("Non xs:nonNegativeInteger value for #{name}: #{raw}")
|
97
|
+
end
|
98
|
+
instance_variable_set("@#{base}".intern, Integer(raw, 10))
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def duration_attribute(name, options)
|
103
|
+
base = basename(name)
|
104
|
+
define_method("check_#{base}".intern) do
|
105
|
+
raw = send("raw_#{base}".intern)
|
106
|
+
return if options[:allow_nil] && raw.nil?
|
107
|
+
error("No #{name} attribute.") if raw.nil?
|
108
|
+
error("Non xs:duration value for #{name}: #{raw}") unless xs_duration?(raw)
|
109
|
+
instance_variable_set("@#{base}".intern, raw)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def token_attribute(name, options)
|
114
|
+
base = basename(name)
|
115
|
+
define_method("check_#{base}".intern) do
|
116
|
+
raw = send("raw_#{base}".intern)
|
117
|
+
error("No #{name} attribute.") if raw.nil?
|
118
|
+
raw = replace_and_collapse_whitespaces(raw)
|
119
|
+
error("Invalid #{name}: #{raw}") unless options[:vocabulary].include?(raw)
|
120
|
+
instance_variable_set("@#{base}".intern, raw)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def any_uri_attribute(name, options)
|
125
|
+
base = basename(name)
|
126
|
+
define_method("check_#{base}".intern) do
|
127
|
+
raw = send("raw_#{base}".intern)
|
128
|
+
return if options[:allow_nil] && raw.nil?
|
129
|
+
error("No #{name} attribute.") if raw.nil?
|
130
|
+
begin
|
131
|
+
uri = URI(raw)
|
132
|
+
rescue URI::InvalidURIError => e
|
133
|
+
error(e)
|
134
|
+
end
|
135
|
+
instance_variable_set("@#{base}".intern, uri.to_s)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
private
|
140
|
+
|
141
|
+
def basename(name)
|
142
|
+
name.split(':').last.underscore.intern
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module Scorm2004
|
2
|
+
module Manifest
|
3
|
+
module Children
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def at(xpath)
|
11
|
+
xpath = './' + xpath unless /^\.\// =~ xpath
|
12
|
+
el.at(xpath, NS)
|
13
|
+
end
|
14
|
+
|
15
|
+
def search(xpath)
|
16
|
+
xpath = './' + xpath unless /^\.\// =~ xpath
|
17
|
+
el.search(xpath, NS)
|
18
|
+
end
|
19
|
+
|
20
|
+
def create_visitor(name)
|
21
|
+
send("#{name}_visitor".intern)
|
22
|
+
end
|
23
|
+
|
24
|
+
module ClassMethods
|
25
|
+
def children
|
26
|
+
@children ||= []
|
27
|
+
end
|
28
|
+
|
29
|
+
def has_one(xpath, options = {})
|
30
|
+
name = options[:name].try(:to_s) || guess_child_name(xpath, options)
|
31
|
+
children << name.intern
|
32
|
+
attr_reader name.intern
|
33
|
+
visitor_name = options[:visitor].try(:to_s) || name
|
34
|
+
define_method("visit_#{name}".intern) do
|
35
|
+
error("Two <#{xpath}> elements found.") if search(xpath).size > 1
|
36
|
+
error("<#{xpath}> not found.") unless options[:allow_nil] || at(xpath)
|
37
|
+
if at(xpath)
|
38
|
+
instance_variable_set("@#{name}".intern, at(xpath).accept(create_visitor(visitor_name)))
|
39
|
+
end
|
40
|
+
end
|
41
|
+
define_visitor(visitor_name)
|
42
|
+
end
|
43
|
+
alias :has_one_and_only_one :has_one
|
44
|
+
|
45
|
+
def has_zero_or_one(xpath, options = {})
|
46
|
+
has_one(xpath, options.merge( { :allow_nil => true } ))
|
47
|
+
end
|
48
|
+
|
49
|
+
def has_many(xpath, options = {})
|
50
|
+
name = options[:name].try(:to_s) || guess_child_name(xpath, options)
|
51
|
+
children << name.pluralize.intern
|
52
|
+
attr_reader name.pluralize.intern
|
53
|
+
visitor_name = options[:visitor].try(:to_s) || name
|
54
|
+
define_method("visit_#{name.pluralize}".intern) do
|
55
|
+
unless options[:allow_nil] || search(xpath).size > 0
|
56
|
+
error("<#{xpath}> not found.")
|
57
|
+
end
|
58
|
+
instance_variable_set("@#{name.pluralize}".intern, search(xpath).map { |child|
|
59
|
+
child.accept(create_visitor(visitor_name))
|
60
|
+
} )
|
61
|
+
end
|
62
|
+
define_visitor(visitor_name)
|
63
|
+
end
|
64
|
+
alias :has_one_or_more :has_many
|
65
|
+
|
66
|
+
def has_zero_or_more(xpath, options = {})
|
67
|
+
has_many(xpath, options.merge( { :allow_nil => true} ))
|
68
|
+
end
|
69
|
+
|
70
|
+
def guess_child_name(xpath, options)
|
71
|
+
xpath.split(%r{[/:]}).last.underscore
|
72
|
+
end
|
73
|
+
|
74
|
+
def define_visitor(name)
|
75
|
+
define_method("#{name}_visitor".intern) do
|
76
|
+
options = respond_to?(:base) ? { :base => base } : {}
|
77
|
+
"Scorm2004::Manifest::#{name.camelize}".constantize.new(options)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Scorm2004
|
2
|
+
module Manifest
|
3
|
+
class CompletionThreshold
|
4
|
+
include VisitorPattern
|
5
|
+
include CustomError
|
6
|
+
include Attributes
|
7
|
+
|
8
|
+
attribute :boolean, 'completedByMeasure', default: false
|
9
|
+
attribute :decimal, 'minProgressMeasure', default: 1.0, range: 0.0..1.0
|
10
|
+
attribute :decimal, 'progressWeight', default: 1.0, range: 0.0..1.0
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Scorm2004
|
2
|
+
module Manifest
|
3
|
+
class ConstrainedChoiceConsiderations
|
4
|
+
include VisitorPattern
|
5
|
+
include CustomError
|
6
|
+
include Attributes
|
7
|
+
|
8
|
+
attribute :boolean, 'preventActivation', default: false
|
9
|
+
attribute :boolean, 'constrainChoice', default: false
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Scorm2004
|
2
|
+
module Manifest
|
3
|
+
class ControlMode
|
4
|
+
include VisitorPattern
|
5
|
+
include CustomError
|
6
|
+
include Attributes
|
7
|
+
|
8
|
+
attribute :boolean, 'choice', default: true
|
9
|
+
attribute :boolean, 'choiceExit', default: true
|
10
|
+
attribute :boolean, 'flow', default: false
|
11
|
+
attribute :boolean, 'forwardOnly', default: false
|
12
|
+
attribute :boolean, 'useCurrentAttemptObjectiveInfo', default: true
|
13
|
+
attribute :boolean, 'useCurrentAttemptProgressInfo', default: true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Scorm2004
|
2
|
+
module Manifest
|
3
|
+
module CustomError
|
4
|
+
def self.included(base)
|
5
|
+
base.class_eval do
|
6
|
+
const_set('Error', Class.new(Scorm2004::Manifest::Error))
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def error(message)
|
11
|
+
raise("#{self.class}::Error".constantize, [message, el.try(:to_s)].compact.join("\n"))
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Scorm2004
|
2
|
+
module Manifest
|
3
|
+
class DataFromLms
|
4
|
+
include VisitorPattern
|
5
|
+
include CustomError
|
6
|
+
include TextNode
|
7
|
+
|
8
|
+
def self.spm
|
9
|
+
4000
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def do_visit
|
15
|
+
if content.length > self.class.spm
|
16
|
+
error("<adlcp:dataFromLMS> exceeds the SPM of #{self.class.spm}: #{content}")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Scorm2004
|
2
|
+
module Manifest
|
3
|
+
class DeliveryControls
|
4
|
+
include VisitorPattern
|
5
|
+
include CustomError
|
6
|
+
include Attributes
|
7
|
+
|
8
|
+
attribute :boolean, 'tracked', default: true
|
9
|
+
attribute :boolean, 'completionSetByContent', default: false
|
10
|
+
attribute :boolean, 'objectiveSetByContent', default: false
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Scorm2004
|
2
|
+
module Manifest
|
3
|
+
class Dependency
|
4
|
+
include VisitorPattern
|
5
|
+
include CustomError
|
6
|
+
include Attributes
|
7
|
+
|
8
|
+
attribute :string, 'identifierref'
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def do_visit
|
13
|
+
error('Referenced <resource> not found:') unless referenced_resource
|
14
|
+
end
|
15
|
+
|
16
|
+
def referenced_resource
|
17
|
+
el.at("/imscp:manifest/imscp:resources/imscp:resource[@identifier='#{identifierref}']", NS)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|