saxon-rb 0.4.0-java → 0.7.2-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +429 -42
  3. data/.ruby-version +1 -1
  4. data/.yardopts +1 -0
  5. data/Gemfile +2 -2
  6. data/README.md +358 -10
  7. data/Rakefile +237 -7
  8. data/docs/templates/plugin.rb +73 -0
  9. data/lib/net/sf/saxon/Saxon-HE/{9.9.1-5/Saxon-HE-9.9.1-5.jar → 9.9.1-6/Saxon-HE-9.9.1-6.jar} +0 -0
  10. data/lib/saxon-rb.rb +0 -0
  11. data/lib/{saxon_jars.rb → saxon-rb_jars.rb} +2 -2
  12. data/lib/saxon.rb +13 -0
  13. data/lib/saxon/axis_iterator.rb +8 -1
  14. data/lib/saxon/configuration.rb +16 -13
  15. data/lib/saxon/document_builder.rb +216 -5
  16. data/lib/saxon/feature_flags.rb +11 -0
  17. data/lib/saxon/feature_flags/errors.rb +8 -0
  18. data/lib/saxon/feature_flags/helpers.rb +15 -0
  19. data/lib/saxon/feature_flags/version.rb +100 -0
  20. data/lib/saxon/item_type.rb +129 -89
  21. data/lib/saxon/item_type/lexical_string_conversion.rb +214 -59
  22. data/lib/saxon/item_type/value_to_ruby.rb +25 -0
  23. data/lib/saxon/loader.rb +6 -1
  24. data/lib/saxon/nokogiri.rb +78 -0
  25. data/lib/saxon/occurrence_indicator.rb +32 -3
  26. data/lib/saxon/processor.rb +50 -5
  27. data/lib/saxon/qname.rb +37 -2
  28. data/lib/saxon/s9api.rb +5 -0
  29. data/lib/saxon/sequence_type.rb +131 -0
  30. data/lib/saxon/serializer.rb +3 -137
  31. data/lib/saxon/serializer/destination.rb +80 -0
  32. data/lib/saxon/serializer/object.rb +93 -0
  33. data/lib/saxon/serializer/output_properties.rb +83 -0
  34. data/lib/saxon/source.rb +207 -71
  35. data/lib/saxon/version.rb +7 -1
  36. data/lib/saxon/version/library.rb +89 -0
  37. data/lib/saxon/xdm.rb +7 -0
  38. data/lib/saxon/xdm/array.rb +16 -0
  39. data/lib/saxon/xdm/atomic_value.rb +10 -2
  40. data/lib/saxon/xdm/empty_sequence.rb +13 -0
  41. data/lib/saxon/xdm/external_object.rb +1 -0
  42. data/lib/saxon/xdm/function_item.rb +1 -0
  43. data/lib/saxon/xdm/item.rb +7 -0
  44. data/lib/saxon/xdm/map.rb +38 -0
  45. data/lib/saxon/xdm/node.rb +50 -1
  46. data/lib/saxon/xdm/sequence_like.rb +15 -0
  47. data/lib/saxon/xdm/value.rb +21 -5
  48. data/lib/saxon/xpath.rb +9 -0
  49. data/lib/saxon/xpath/compiler.rb +37 -2
  50. data/lib/saxon/xpath/executable.rb +53 -28
  51. data/lib/saxon/xpath/static_context.rb +25 -40
  52. data/lib/saxon/xpath/variable_declaration.rb +16 -49
  53. data/lib/saxon/xslt.rb +12 -0
  54. data/lib/saxon/xslt/compiler.rb +75 -6
  55. data/lib/saxon/xslt/evaluation_context.rb +30 -4
  56. data/lib/saxon/xslt/executable.rb +206 -29
  57. data/lib/saxon/xslt/invocation.rb +97 -0
  58. data/saxon-rb.gemspec +3 -3
  59. metadata +22 -10
  60. data/saxon.gemspec +0 -30
@@ -0,0 +1,131 @@
1
+ require_relative './item_type'
2
+ require_relative './occurrence_indicator'
3
+
4
+ module Saxon
5
+ # Represents a type definition for an XDM Sequence: an {ItemType} plus an
6
+ # {OccurrenceIndicator} as a restriction on the cardinality (length) of the
7
+ # sequence. Used most often to define variables in XPath or XSLT, plus in
8
+ # extension function definition.
9
+ class SequenceType
10
+ class << self
11
+ # Generate a {SequenceType} from a type declaration string (see
12
+ # {.from_type_decl}), or some combination of type name/Ruby class (see
13
+ # {ItemType.get_type}), and an {OccurrenceIndicator} or symbol referencing
14
+ # an OccurenceIndicator (one of +:zero_or_more+, +:one_or_more+,
15
+ # +:zero_or_one+, or +:one+)
16
+ #
17
+ # @return [Saxon::SequenceType] the resulting SequenceType
18
+ def create(type_name, occurrence_indicator = nil)
19
+ case type_name
20
+ when SequenceType
21
+ return type_name
22
+ when S9API::SequenceType
23
+ return new(type_name)
24
+ else
25
+ check_for_complete_decl!(type_name, occurrence_indicator)
26
+ return from_type_decl(type_name) if type_name.is_a?(String) && occurrence_indicator.nil?
27
+ item_type = ItemType.get_type(type_name)
28
+ occurrence_indicator = OccurrenceIndicator.get_indicator(occurrence_indicator)
29
+ new(item_type, occurrence_indicator)
30
+ end
31
+ end
32
+
33
+ # Generate a {SequenceType} from a declaration string following the rules
34
+ # of parameter and function +as=+ declarations in XSLT, like
35
+ # <tt><xsl:variable ... as="xs:string+"/></tt>
36
+ #
37
+ # @param type_decl [String] the declaration string
38
+ # @return [Saxon::SequenceType] the resulting SequenceType
39
+ def from_type_decl(type_decl)
40
+ occurence_char = type_decl[-1]
41
+ occurence = case occurence_char
42
+ when '?'
43
+ new(ItemType.get_type(type_decl[0..-2]), OccurrenceIndicator.zero_or_one)
44
+ when '+'
45
+ new(ItemType.get_type(type_decl[0..-2]), OccurrenceIndicator.one_or_more)
46
+ when '*'
47
+ new(ItemType.get_type(type_decl[0..-2]), OccurrenceIndicator.zero_or_more)
48
+ else
49
+ new(ItemType.get_type(type_decl), OccurrenceIndicator.one)
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ def check_for_complete_decl!(type_name, occurrence_indicator)
56
+ return true if occurrence_indicator.nil?
57
+ if type_name_is_complete_decl?(type_name)
58
+ raise ArgumentError, "Cannot pass a complete type declaration (#{type_name}) and an OccurrenceIndicator"
59
+ end
60
+ end
61
+
62
+ def type_name_is_complete_decl?(type_name)
63
+ !!(type_name.is_a?(String) && type_name.match(/[+*?]$/))
64
+ end
65
+ end
66
+
67
+ # @overload initialize(item_type, occurrence_indicator)
68
+ # creates new instance using item type and occurrence indicator
69
+ # @param item_type [Saxon::ItemType] the sequence's item type
70
+ # @param occurrence_indicator [net.sf.saxon.s9api.OccurrenceIndicator] the
71
+ # occurrence indicator (cardinality) of the sequence
72
+ # @overload initialize(s9_sequence_type)
73
+ # create a new instance by wrapping one of Saxon's underlying Java
74
+ # +SequenceType+s
75
+ # @param s9_sequence_type [net.sf.saxon.s9api.SequenceType]
76
+ # @return [Saxon::SequenceType] the new SequenceType
77
+ def initialize(item_type, occurrence_indicator = nil)
78
+ if occurrence_indicator.nil? && !item_type.is_a?(S9API::SequenceType)
79
+ raise ArgumentError, "Expected a Java s9api.SequenceType when handed a single argument, but got a #{item_type.class}"
80
+ end
81
+
82
+ if occurrence_indicator.nil?
83
+ @s9_sequence_type = item_type
84
+ else
85
+ @item_type = item_type
86
+ @occurrence_indicator = occurrence_indicator
87
+ end
88
+ end
89
+
90
+ # @return [Saxon::ItemType] the type's ItemType
91
+ def item_type
92
+ @item_type ||= Saxon::ItemType.get_type(s9_sequence_type.getItemType)
93
+ end
94
+
95
+ # @return [net.sf.saxon.s9api.OccurrenceIndicator] the type's OccurrenceIndicator
96
+ def occurrence_indicator
97
+ @occurrence_indicator ||= s9_sequence_type.getOccurrenceIndicator
98
+ end
99
+
100
+ # @return [net.sf.saxon.s9api.SequenceType] the underlying Saxon SequenceType
101
+ def to_java
102
+ s9_sequence_type
103
+ end
104
+
105
+ # Compare equal with another SequenceType
106
+ # @param other [Saxon::SequenceType]
107
+ # @return [Boolean] the result of comparing +self+ and +other+
108
+ def ==(other)
109
+ return false if other.class != self.class
110
+ item_type == other.item_type && occurrence_indicator == other.occurrence_indicator
111
+ end
112
+ alias_method :eql?, :==
113
+
114
+ # Generated hash code for use as keys in Hashes
115
+ def hash
116
+ @hash ||= item_type.hash ^ occurrence_indicator.hash
117
+ end
118
+
119
+ private
120
+
121
+ def s9_sequence_type
122
+ @s9_sequence_type ||= S9API::SequenceType.makeSequenceType(item_type.to_java, occurrence_indicator.to_java)
123
+ end
124
+ end
125
+
126
+ # Convenience wrapper for {SequenceType.create}
127
+ # @see SequenceType.create
128
+ def self.SequenceType(*args)
129
+ SequenceType.create(*args)
130
+ end
131
+ end
@@ -1,143 +1,9 @@
1
- require 'saxon/s9api'
2
- require 'stringio'
1
+ require_relative './serializer/destination.rb'
2
+ require_relative './serializer/object.rb'
3
3
 
4
4
  module Saxon
5
5
  # Serialize XDM objects.
6
- class Serializer
7
- # Manage access to the serialization properties of this serializer, with
8
- # hash-like access.
9
- #
10
- # Properties can be set explicitly through this API, or via XSLT or XQuery
11
- # serialization options like `<xsl:output>`.
12
- #
13
- # Properties set explicitly here will override properties set through the
14
- # document like `<xsl:output>`.
15
- class OutputProperties
16
- # @api private
17
- # Provides mapping between symbols and the underlying Saxon property
18
- # instances
19
- def self.output_properties
20
- @output_properties ||= Hash[
21
- Saxon::S9API::Serializer::Property.values.map { |property|
22
- qname = property.getQName
23
- key = [
24
- qname.getPrefix,
25
- qname.getLocalName.tr('-', '_')
26
- ].reject { |str| str == '' }.join('_').to_sym
27
- [key, property]
28
- }
29
- ]
30
- end
31
-
32
- attr_reader :s9_serializer
33
-
34
- # @api private
35
- def initialize(s9_serializer)
36
- @s9_serializer = s9_serializer
37
- end
38
-
39
- # @param [Symbol, Saxon::S9API::Serializer::Property] property The property to fetch
40
- def [](property)
41
- s9_serializer.getOutputProperty(resolved_property(property))
42
- end
43
-
44
- # @param [Symbol, Saxon::S9API::Serializer::Property] property The property to set
45
- # @param [String] value The string value of the property
46
- def []=(property, value)
47
- s9_serializer.setOutputProperty(resolved_property(property), value)
48
- end
49
-
50
- # @overload fetch(property)
51
- # @param [Symbol, Saxon::S9API::Serializer::Property] property The property to fetch
52
- # @overload fetch(property, default)
53
- # @param property [Symbol, Saxon::S9API::Serializer::Property] The property to fetch
54
- # @param default [Object] The value to return if the property is unset
55
- def fetch(property, default = nil)
56
- explicit_value = self[property]
57
- if explicit_value.nil? && !default.nil?
58
- default
59
- else
60
- explicit_value
61
- end
62
- end
63
-
64
- private
65
- def resolved_property(property_key)
66
- case property_key
67
- when Symbol
68
- self.class.output_properties.fetch(property_key)
69
- else
70
- property_key
71
- end
72
- end
73
- end
74
-
75
- attr_reader :s9_serializer
76
- private :s9_serializer
77
-
78
- # @api private
79
- def initialize(s9_serializer)
80
- @s9_serializer = s9_serializer
81
- end
82
-
83
- # @return [Saxon::Serializer::OutputProperties] hash-like access to the Output Properties
84
- def output_property
85
- @output_property ||= OutputProperties.new(s9_serializer)
86
- end
87
-
88
- # @overload serialize(xdm_value, io)
89
- # Serialize an XdmValue to an IO
90
- # @param [Saxon::XdmValue] xdm_value The XdmValue to serialize
91
- # @param [File, IO] io The IO to serialize to
92
- # @return [nil]
93
- # @overload serialize(xdm_value, path)
94
- # Serialize an XdmValue to file <tt>path</tt>
95
- # @param [Saxon::XdmValue] xdm_value The XdmValue to serialize
96
- # @param [String, Pathname] path The path of the file to serialize to
97
- # @return [nil]
98
- # @overload serialize(xdm_value)
99
- # Serialize an XdmValue to a String
100
- # @param [Saxon::XdmValue] xdm_value The XdmValue to serialize
101
- # @return [String] The serialized XdmValue
102
- def serialize(xdm_value, io_or_path = nil)
103
- case io_or_path
104
- when nil
105
- serialize_to_string(xdm_value)
106
- when String, Pathname
107
- serialize_to_file(xdm_value, io_or_path)
108
- else
109
- serialize_to_io(xdm_value, io_or_path)
110
- end
111
- end
112
-
113
- # @return [Saxon::S9API::Serializer] The underlying Saxon Serializer object
114
- def to_java
115
- s9_serializer
116
- end
117
-
118
- private
119
-
120
- def serialize_to_io(xdm_value, io)
121
- s9_serializer.setOutputStream(io.to_outputstream)
122
- s9_serializer.serializeXdmValue(xdm_value.to_java)
123
- nil
124
- end
125
-
126
- def serialize_to_string(xdm_value)
127
- str_encoding = output_property.fetch(:encoding, Encoding.default_internal || Encoding.default_external)
128
- StringIO.open { |io|
129
- io.binmode
130
- serialize_to_io(xdm_value, io)
131
- io.string.force_encoding(str_encoding)
132
- }
133
- end
134
-
135
- def serialize_to_file(xdm_value, path)
136
- file = Java::JavaIO::File.new(path)
137
- s9_serializer.setOutputFile(file)
138
- s9_serializer.serializeXdmValue(xdm_value.to_java)
139
- nil
140
- end
6
+ module Serializer
141
7
  end
142
8
  end
143
9
 
@@ -0,0 +1,80 @@
1
+ require_relative '../s9api'
2
+ require_relative './output_properties'
3
+
4
+ module Saxon
5
+ module Serializer
6
+ # A Saxon Serializer to be used as a Destination for a transformation rather
7
+ # than being directly called with existing XDM objects
8
+ class Destination
9
+ include OutputProperties
10
+
11
+ attr_reader :s9_serializer, :invocation_lambda
12
+
13
+ # @api private
14
+ def initialize(s9_serializer, invocation_lambda, &block)
15
+ @s9_serializer, @invocation_lambda = s9_serializer, invocation_lambda
16
+ if block_given?
17
+ instance_exec(&block)
18
+ end
19
+ end
20
+
21
+ # @overload serialize(io)
22
+ # Serialize the transformation to an IO
23
+ # @param [File, IO] io The IO to serialize to
24
+ # @return [nil]
25
+ # @overload serialize(path)
26
+ # Serialize the transformation to file <tt>path</tt>
27
+ # @param [String, Pathname] path The path of the file to serialize to
28
+ # @return [nil]
29
+ # @overload serialize
30
+ # Serialize the transformation to a String
31
+ # @return [String] The serialized XdmValue
32
+ def serialize(io_or_path = nil)
33
+ case io_or_path
34
+ when nil
35
+ serialize_to_string
36
+ when String, Pathname
37
+ serialize_to_file(io_or_path)
38
+ else
39
+ serialize_to_io(io_or_path)
40
+ end
41
+ end
42
+
43
+ # @return [Saxon::S9API::Serializer] The underlying Saxon Serializer object
44
+ def to_java
45
+ s9_serializer
46
+ end
47
+
48
+ private
49
+
50
+ def run_transform!
51
+ invocation_lambda.call(self.to_java)
52
+ end
53
+
54
+ def serialize_to_string
55
+ str_encoding = output_property.fetch(:encoding, Encoding.default_internal || Encoding.default_external)
56
+ StringIO.open { |io|
57
+ io.binmode
58
+ set_output_io(io)
59
+ run_transform!
60
+ io.string.force_encoding(str_encoding)
61
+ }
62
+ end
63
+
64
+ def serialize_to_io(io)
65
+ set_output_io(io)
66
+ run_transform!
67
+ end
68
+
69
+ def set_output_io(io)
70
+ s9_serializer.setOutputStream(io.to_outputstream)
71
+ end
72
+
73
+ def serialize_to_file(path)
74
+ file = Java::JavaIO::File.new(path.to_s)
75
+ s9_serializer.setOutputFile(file)
76
+ run_transform!
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,93 @@
1
+ require_relative '../s9api'
2
+ require_relative './output_properties'
3
+ require 'stringio'
4
+
5
+ module Saxon
6
+ module Serializer
7
+ # A Saxon Serializer to be used directly with XDM Values rather than being
8
+ # called as a Destination for a transformation.
9
+ class Object
10
+ # Create a serializer from the passed in +Processor+. When called with a
11
+ # block, the block will be executed via instance-exec so that output
12
+ # properties can be set, e.g.
13
+ #
14
+ # Serializer::Object.create(processor) {
15
+ # output_property[:indent] = 'yes'
16
+ # }
17
+ #
18
+ # @param processor [Saxon::Processor] the processor to create this
19
+ # +Serializer::Object+ from
20
+ # @yield the passed block bound via instance-exec to the new serializer
21
+ def self.create(processor, &block)
22
+ new(processor.to_java.newSerializer, &block)
23
+ end
24
+
25
+ include OutputProperties
26
+
27
+ attr_reader :s9_serializer
28
+ private :s9_serializer
29
+
30
+ # @api private
31
+ def initialize(s9_serializer, &block)
32
+ @s9_serializer = s9_serializer
33
+ if block_given?
34
+ instance_exec(&block)
35
+ end
36
+ end
37
+
38
+ # @overload serialize(xdm_value, io)
39
+ # Serialize an XdmValue to an IO
40
+ # @param [Saxon::XdmValue] xdm_value The XdmValue to serialize
41
+ # @param [File, IO] io The IO to serialize to
42
+ # @return [nil]
43
+ # @overload serialize(xdm_value, path)
44
+ # Serialize an XdmValue to file <tt>path</tt>
45
+ # @param [Saxon::XdmValue] xdm_value The XdmValue to serialize
46
+ # @param [String, Pathname] path The path of the file to serialize to
47
+ # @return [nil]
48
+ # @overload serialize(xdm_value)
49
+ # Serialize an XdmValue to a String
50
+ # @param [Saxon::XdmValue] xdm_value The XdmValue to serialize
51
+ # @return [String] The serialized XdmValue
52
+ def serialize(xdm_value, io_or_path = nil)
53
+ case io_or_path
54
+ when nil
55
+ serialize_to_string(xdm_value)
56
+ when String, Pathname
57
+ serialize_to_file(xdm_value, io_or_path)
58
+ else
59
+ serialize_to_io(xdm_value, io_or_path)
60
+ end
61
+ end
62
+
63
+ # @return [Saxon::S9API::Serializer] The underlying Saxon Serializer object
64
+ def to_java
65
+ s9_serializer
66
+ end
67
+
68
+ private
69
+
70
+ def serialize_to_io(xdm_value, io)
71
+ s9_serializer.setOutputStream(io.to_outputstream)
72
+ s9_serializer.serializeXdmValue(xdm_value.to_java)
73
+ nil
74
+ end
75
+
76
+ def serialize_to_string(xdm_value)
77
+ str_encoding = output_property.fetch(:encoding, Encoding.default_internal || Encoding.default_external)
78
+ StringIO.open { |io|
79
+ io.binmode
80
+ serialize_to_io(xdm_value, io)
81
+ io.string.force_encoding(str_encoding)
82
+ }
83
+ end
84
+
85
+ def serialize_to_file(xdm_value, path)
86
+ file = Java::JavaIO::File.new(path.to_s)
87
+ s9_serializer.setOutputFile(file)
88
+ s9_serializer.serializeXdmValue(xdm_value.to_java)
89
+ nil
90
+ end
91
+ end
92
+ end
93
+ end