lib/json/ld/api.rb in json-ld-2.1.2 vs lib/json/ld/api.rb in json-ld-2.1.3

- old
+ new

@@ -67,14 +67,16 @@ # The callback of the loader to be used to retrieve remote documents and contexts. If specified, it must be used to retrieve remote documents and contexts; otherwise, if not specified, the processor's built-in loader must be used. See {documentLoader} for the method signature. # @option options [String, #read, Hash, Array, JSON::LD::Context] :expandContext # A context that is used to initialize the active context when expanding a document. # @option options [Boolean, String, RDF::URI] :flatten # If set to a value that is not `false`, the JSON-LD processor must modify the output of the Compaction Algorithm or the Expansion Algorithm by coalescing all properties associated with each subject via the Flattening Algorithm. The value of `flatten must` be either an _IRI_ value representing the name of the graph to flatten, or `true`. If the value is `true`, then the first graph encountered in the input document is selected and flattened. - # @option options [String] :processingMode ("json-ld-1.1") + # @option options [String] :processingMode # Processing mode, json-ld-1.0 or json-ld-1.1. Also can have other values: # # * json-ld-1.1-expand-frame – special frame expansion mode. + # + # If `processingMode` is not specified, a mode of `json-ld-1.0` or `json-ld-1.1` is set, the context used for `expansion` or `compaction`. # @option options [Boolean] :rename_bnodes (true) # Rename bnodes as part of expansion, or keep them the same. # @option options [Boolean] :unique_bnodes (false) # Use unique bnode identifiers, defaults to using the identifier which the node was originally initialized with (if any). # @option options [Boolean] :simple_compact_iris (false) @@ -86,14 +88,12 @@ # @raise [JsonLdError] def initialize(input, context, options = {}, &block) @options = { compactArrays: true, rename_bnodes: true, - processingMode: "json-ld-1.1", documentLoader: self.class.method(:documentLoader) } - @options[:validate] = %w(json-ld-1.0 json-ld-1.1).include?(@options[:processingMode]) @options = @options.merge(options) @namer = options[:unique_bnodes] ? BlankNodeUniqer.new : (@options[:rename_bnodes] ? BlankNodeNamer.new("b") : BlankNodeMapper.new) # For context via Link header context_ref = nil @@ -133,10 +133,14 @@ # If not provided, first use context from document, or from a Link header context ||= (@value['@context'] if @value.is_a?(Hash)) || context_ref @context = Context.parse(context || {}, @options) + # If not set explicitly, the context figures out the processing mode + @options[:processingMode] ||= @context.processingMode + @options[:validate] ||= %w(json-ld-1.0 json-ld-1.1).include?(@options[:processingMode]) + if block_given? case block.arity when 0, -1 then instance_eval(&block) else block.call(self) end @@ -205,11 +209,11 @@ # 1) Perform the Expansion Algorithm on the JSON-LD input. # This removes any existing context to allow the given context to be cleanly applied. expanded_input = options[:expanded] ? input : API.expand(input, options) API.new(expanded_input, context, options) do - log_debug(".compact") {"expanded input: #{expanded.to_json(JSON_STATE) rescue 'malformed json'}"} + log_debug(".compact") {"expanded input: #{expanded_input.to_json(JSON_STATE) rescue 'malformed json'}"} result = compact(value) # xxx) Add the given context to the output ctx = self.context.serialize if result.is_a?(Array) @@ -296,10 +300,11 @@ # @option options [Boolean] :requireAll (true) # A flag specifying that all properties present in the input frame must either have a default value or be present in the JSON-LD input for the frame to match. # @option options [Boolean] :omitDefault (false) # a flag specifying that properties that are missing from the JSON-LD input should be omitted from the output. # @option options [Boolean] :expanded Input is already expanded + # @option options [Boolean] :pruneBlankNodeIdentifiers (true) removes blank node identifiers that are only used once. # @yield jsonld # @yieldparam [Hash] jsonld # The framed JSON-LD document # @yieldreturn [Object] returned object # @return [Object, Hash] @@ -307,17 +312,18 @@ # @raise [InvalidFrame] # @see http://json-ld.org/spec/latest/json-ld-api/#framing-algorithm def self.frame(input, frame, options = {}) result = nil options = { - base: input.is_a?(String) ? input : '', - compactArrays: true, - embed: '@last', - explicit: false, - requireAll: true, - omitDefault: false, - documentLoader: method(:documentLoader) + base: (input if input.is_a?(String)), + compactArrays: true, + embed: '@last', + explicit: false, + requireAll: true, + omitDefault: false, + pruneBlankNodeIdentifiers: true, + documentLoader: method(:documentLoader) }.merge!(options) framing_state = { graphMap: {}, graphStack: [], @@ -363,22 +369,27 @@ framing_state[:subjects] = framing_state[:graphMap][framing_state[:graph]] result = [] frame(framing_state, framing_state[:subjects].keys.sort, (expanded_frame.first || {}), options.merge(parent: result)) - + + # Count blank node identifiers used in the document, if pruning + bnodes_to_clear = if options[:pruneBlankNodeIdentifiers] + count_blank_node_identifiers(result).collect {|k, v| k if v == 1}.compact + end + # Initalize context from frame @context = @context.parse(frame['@context']) # Compact result compacted = compact(result) compacted = [compacted] unless compacted.is_a?(Array) # Add the given context to the output kwgraph = context.compact_iri('@graph', quiet: true) result = context.serialize.merge({kwgraph => compacted}) log_debug(".frame") {"after compact: #{result.to_json(JSON_STATE) rescue 'malformed json'}"} - result = cleanup_preserve(result) + result = cleanup_preserve(result, bnodes_to_clear || []) end block_given? ? yield(result) : result end @@ -448,21 +459,23 @@ # @param [Array<RDF::Statement>] input # @param [Hash{Symbol => Object}] options # @option options (see #initialize) # @option options [Boolean] :useRdfType (false) # If set to `true`, the JSON-LD processor will treat `rdf:type` like a normal property instead of using `@type`. + # @option options [Boolean] :useNativeTypes (false) use native representations # @yield jsonld # @yieldparam [Hash] jsonld # The JSON-LD document in expanded form # @yieldreturn [Object] returned object # @return [Object, Hash] # If a block is given, the result of evaluating the block is returned, otherwise, the expanded JSON-LD document def self.fromRdf(input, options = {}, &block) useRdfType = options.fetch(:useRdfType, false) + useNativeTypes = options.fetch(:useNativeTypes, false) result = nil API.new(nil, nil, options) do |api| - result = api.from_statements(input, useRdfType: useRdfType) + result = api.from_statements(input, useRdfType: useRdfType, useNativeTypes: useNativeTypes) end block_given? ? yield(result) : result end