@@ -36,8 +36,13 @@ class TermDefinition
3636 # @return [String] Type mapping
3737 attr_accessor :type_mapping
3838
39- # @return ['@index', '@language', '@index', '@set', '@type', '@id'] Container mapping
40- attr_accessor :container_mapping
39+ # Base container mapping, without @set
40+ # @return ['@index', '@language', '@index', '@type', '@id'] Container mapping
41+ attr_reader :container_mapping
42+
43+ # If container mapping was defined along with @set
44+ # @return [Boolean]
45+ attr_reader :as_set
4146
4247 # @return [String] Term used for nest properties
4348 attr_accessor :nest
@@ -81,15 +86,24 @@ def initialize(term,
8186 nest : nil ,
8287 simple : false ,
8388 context : nil )
84- @term = term
85- @id = id . to_s if id
86- @type_mapping = type_mapping . to_s if type_mapping
87- @container_mapping = container_mapping if container_mapping
88- @language_mapping = language_mapping if language_mapping
89- @reverse_property = reverse_property if reverse_property
90- @nest = nest if nest
91- @simple = simple if simple
92- @context = context if context
89+ @term = term
90+ @id = id . to_s if id
91+ @type_mapping = type_mapping . to_s if type_mapping
92+ self . container_mapping = container_mapping if container_mapping
93+ @language_mapping = language_mapping if language_mapping
94+ @reverse_property = reverse_property if reverse_property
95+ @nest = nest if nest
96+ @simple = simple if simple
97+ @context = context if context
98+ end
99+
100+ # Set container mapping, from an array which may include @set
101+ def container_mapping = ( mapping )
102+ mapping = Array ( mapping )
103+ if @as_set = mapping . include? ( '@set' )
104+ mapping -= %w( @set )
105+ end
106+ @container_mapping = mapping . first
93107 end
94108
95109 ##
@@ -109,6 +123,7 @@ def to_context_definition(context)
109123
110124 if language_mapping . nil? &&
111125 container_mapping . nil? &&
126+ !as_set &&
112127 type_mapping . nil? &&
113128 reverse_property . nil? &&
114129 self . context . nil? &&
@@ -125,7 +140,10 @@ def to_context_definition(context)
125140 context . compact_iri ( type_mapping , vocab : true )
126141 end
127142 end
128- defn [ '@container' ] = container_mapping if container_mapping
143+
144+ cm = [ container_mapping , ( '@set' if as_set ) ] . compact
145+ cm = cm . first if cm . length == 1
146+ defn [ '@container' ] = cm unless cm . empty?
129147 # Language set as false to be output as null
130148 defn [ '@language' ] = ( language_mapping ? language_mapping : nil ) unless language_mapping . nil?
131149 defn [ '@context' ] = self . context unless self . context . nil?
@@ -143,6 +161,9 @@ def to_rb
143161 %w( id type_mapping container_mapping language_mapping reverse_property nest simple context ) . each do |acc |
144162 v = instance_variable_get ( "@#{ acc } " . to_sym )
145163 v = v . to_s if v . is_a? ( RDF ::Term )
164+ if acc == 'container_mapping' && as_set
165+ v = v ? [ v , '@set' ] : '@set'
166+ end
146167 defn << "#{ acc } : #{ v . inspect } " if v
147168 end
148169 defn . join ( ', ' ) + ")"
@@ -154,6 +175,7 @@ def inspect
154175 v << "term=#{ @term } "
155176 v << "rev" if reverse_property
156177 v << "container=#{ container_mapping } " if container_mapping
178+ v << "as_set=#{ as_set . inspect } "
157179 v << "lang=#{ language_mapping . inspect } " unless language_mapping . nil?
158180 v << "type=#{ type_mapping } " unless type_mapping . nil?
159181 v << "nest=#{ nest . inspect } " unless nest . nil?
@@ -607,7 +629,7 @@ def create_term_definition(local_context, term, defined)
607629 container = value [ '@container' ]
608630 raise JsonLdError ::InvalidReverseProperty ,
609631 "unknown mapping for '@container' to #{ container . inspect } on term #{ term . inspect } " unless
610- [ '@set' , '@index' ] . include? ( container )
632+ container . is_a? ( String ) && [ '@set' , '@index' ] . include? ( container )
611633 definition . container_mapping = check_container ( container , local_context , defined , term )
612634 end
613635 definition . reverse_property = true
@@ -848,6 +870,17 @@ def container(term)
848870 term && term . container_mapping
849871 end
850872
873+ ##
874+ # Should values be represented as a set?
875+ #
876+ # @param [Term, #to_s] term in unexpanded form
877+ # @return [Boolean]
878+ def as_array? ( term )
879+ return true if %w( @graph @list ) . include? ( term )
880+ term = find_definition ( term )
881+ term && ( term . as_set || term . container_mapping == '@list' )
882+ end
883+
851884 ##
852885 # Retrieve content of a term
853886 #
@@ -1447,7 +1480,7 @@ def inverse_context
14471480 a . length == b . length ? ( a <=> b ) : ( a . length <=> b . length )
14481481 end . each do |term |
14491482 next unless td = term_definitions [ term ]
1450- container = td . container_mapping || '@ none'
1483+ container = td . container_mapping || ( td . as_set ? '@set' : '@ none')
14511484 container_map = result [ td . id . to_s ] ||= { }
14521485 tl_map = container_map [ container ] ||= { '@language' => { } , '@type' => { } }
14531486 type_map = tl_map [ '@type' ]
@@ -1564,8 +1597,23 @@ def languages
15641597 # Ensure @container mapping is appropriate
15651598 # The result is the original container definition. For IRI containers, this is necessary to be able to determine the @type mapping for string values
15661599 def check_container ( container , local_context , defined , term )
1567- case container
1568- when '@set' , '@list' , '@language' , '@index' , nil
1600+ if container . is_a? ( Array ) && processingMode < 'json-ld-1.1'
1601+ raise JsonLdError ::InvalidContainerMapping ,
1602+ "'@container' on term #{ term . inspect } must be a string: #{ container . inspect } "
1603+ end
1604+
1605+ val = Array ( container )
1606+ val -= %w( @set ) if has_set = val . include? ( '@set' )
1607+
1608+ raise JsonLdError ::InvalidContainerMapping ,
1609+ "'@container' has more than one value other than @set" if val . length > 1
1610+
1611+ case val . first
1612+ when '@list'
1613+ raise JsonLdError ::InvalidContainerMapping ,
1614+ "'@container' on term #{ term . inspect } cannot be both @list and @set" if has_set
1615+ # Okay
1616+ when '@language' , '@index' , nil
15691617 # Okay
15701618 when '@type' , '@id' , nil
15711619 raise JsonLdError ::InvalidContainerMapping ,
@@ -1575,7 +1623,7 @@ def check_container(container, local_context, defined, term)
15751623 raise JsonLdError ::InvalidContainerMapping ,
15761624 "unknown mapping for '@container' to #{ container . inspect } on term #{ term . inspect } "
15771625 end
1578- container
1626+ Array ( container )
15791627 end
15801628 end
15811629end
0 commit comments