module PIM::Services::ItemService

Constants

GET_ITEM_LOAD_OPTIONS

Allowed load options

NOCACHE_ITEM_LOAD_OPTIONS

If one of the specified load options contains one of the options below, writing into cache needs to be disabled.

Public Instance Methods

__get_item(primary_key, **named_arguments, &loader) click to toggle source

Helper method to either get the item from the cache or load it

# File services.rb, line 3236
def __get_item primary_key, **named_arguments, &loader

  return nil if PIM.is_empty?(primary_key)

  # Restrict to valid load options and convert to 'camelized' keys
  load_options = named_arguments.map { |k,v| [PIM::Utils.camelize(k), v] }.filter { |k,v| GET_ITEM_LOAD_OPTIONS.include?(k) }.to_h

  # Get cache for type
  type = named_arguments[:type]
  data_module = PIM.active_module
  if data_module.has_option?(:enable_get_item_cache)

    # Use type dependent fiber-local cache
    item_cache = data_module.item_cache(type: type)

  else

    # Check if a cache argument was specified and actually is a LRUCache
    item_cache = named_arguments[:cache] || named_arguments[:item_cache]
    item_cache = nil unless item_cache.is_a?(PIM::LRUCache)

  end

  # Don't use cache if 'no_cache' option was specified
  item_cache = nil if (named_arguments[:no_cache] == true)

  # New option: "ensure_include_attributes"
  # - Will check the "cache" first to see if those attribute are available and then return that item
  # - Otherwise retrieve the item using "default_exclude: true, include_attributes: ensure_include_attributes"!

  # 'Pop' out ensure-include-attributes and check cache, if no other options were set
  ensure_include_attributes = load_options.delete('ensureIncludeAttributes')
  if not PIM::Utils.is_empty?(ensure_include_attributes) and PIM::Utils.is_empty?(load_options) and not item_cache.nil?

    item = item_cache[primary_key]

    # Item must exist and each 'ensureIncludeAttributes' must exist, i.e. must not be null
    # FIXME: This currently only works for JSON or JAVA formats!
    if not item.nil?

      if type == :json
        return item if ensure_include_attributes.all? { |a| item.include?(a.to_s) }
      elsif type == :java
        return item if ensure_include_attributes.all? { |a| !PIM::Utils.get_value(item, a.to_s).nil? }
      end
      item = nil

    end

    # Matching item was not found, so use the equivalent load-options
    load_options = { defaultExclude: true, includeAttributes: ensure_include_attributes }

  end

  # Only use cache if no load options were set
  load_options = nil if load_options.empty?
  item_cache = nil unless load_options.nil?

  # Check cache - unless 'reload' is specified
  if not named_arguments[:reload] and item_cache and item_cache.include?(primary_key)
    return item_cache[primary_key]
  end

  writingToCacheDisabled = item_cache.nil?

  # Don't write into cache if load_options contains one of NOCACHE_ITEM_LOAD_OPTIONS
  unless load_options.nil? || writingToCacheDisabled
    writingToCacheDisabled = !(load_options.keys.detect { |key| NOCACHE_ITEM_LOAD_OPTIONS.include?(key.to_s)}.nil?)
    PIM.log_info "Disabled writing to item_cache because load_options '#{load_options}' contains one of '#{NOCACHE_ITEM_LOAD_OPTIONS}'"
  end

  item = loader.call(load_options)

  item_cache[primary_key] = item unless writingToCacheDisabled

  return item
end
__service_load_options(load_options) click to toggle source
# File services.rb, line 3315
def __service_load_options load_options

  # Set attribute includes and excludes, if specified in data model option
  include_attributes = PIM.active_module.get_data_model_opt(:get_item_include_attributes, [])
  exclude_attributes = PIM.active_module.get_data_model_opt(:get_item_exclude_attributes, [])
  default_exclude = PIM.active_module.has_data_model_opt?(:get_item_default_exclude)

  unless include_attributes.empty? and exclude_attributes.empty? and !default_exclude
    load_options ||= {}
    load_options['includeAttributes'] =  PIM.stringified_value(include_attributes) unless include_attributes.empty?
    load_options['excludeAttributes'] =  PIM.stringified_value(exclude_attributes) unless exclude_attributes.empty?
    load_options['defaultExclude'] = default_exclude if default_exclude
  end

  load_options

end
convert_item_to_json(java_item) click to toggle source

Converts an item in the “Java” form to the “JSON” form.

# File services.rb, line 3337
def convert_item_to_json java_item
  __item_service.convertItemToJson(java_item)
end
convert_item_to_xml(java_item) click to toggle source

Converts an item in the “Java” form to the “XML” form.

# File services.rb, line 3344
def convert_item_to_xml java_item
  __item_service.convertItemToXml(java_item).to_io
end
convert_items_to_xml(java_items) click to toggle source

Converts an array of items in the “Java” form to the “XML” form.

# File services.rb, line 3351
def convert_items_to_xml java_items
  __item_service.convertItemsToXml(java_items).to_io
end
delete_item_hierarchy(root_primary_key, name) click to toggle source

Delete the specified hierarchy. Returns true, if the hierarchy was deleted, false if it did not exist

# File services.rb, line 3516
def delete_item_hierarchy root_primary_key, name
  __item_service.deleteItemHierarchy(root_primary_key.to_s, name.to_s)
end
delete_item_status_values(primary_key, *keys) click to toggle source
# File services.rb, line 3424
def delete_item_status_values primary_key, *keys
  keys = PIM.stringified_array(keys.compact)
  __item_service.deleteItemStatusValues(primary_key, *keys)
end
get_item_as_java(primary_key, **named_arguments) click to toggle source

Loads an item by primary key. This method will return the item in it’s “Java” form.

Parameters:

  • primary_key (String) : the primary key to load the item for.

  • named_arguments (Hash) : Named arguments which can contain :cache for “Item cache” or load options

Item cache:

  • Used to “cache” items on load so they don’t need to be loaded again.

  • Can be created by:

    item_cache = PIM::LRUCache.new(20)
    
  • Is not “type safe”, i.e. only use it for either “Java” or “Ruby” items!

NOTES:

  • If data model has option :enable_get_item_cache set to true, caching will be done automatically

  • Automatic caching is “type safe”, i.e. loading via ‘get_item_as_java’ caches a different object than ‘get_item_as_ruby’

  • Automatic caching can be turned off via :no_cache option (no_cache: true)

  • For ANY caching, an item can be explicitly reloaded using the :reload option (reload: true)

  • Automatic caching is ONLY enabled if no other load-options are specified!

Load Options:

  • checksum (String) : the checksum to load the item for e.g :checksum => “083bdf63cd943d6ea18b262e65fabc7859e2b54c”

  • retry_if_dirty (boolean) : it will reload the item until the validation_dirty flag is no longer true. e.g :retry_if_dirty => false

  • destination_id (long) : used to load the item with publication e.g :destination_id => ‘4904646493601792’

  • sub_destination (String) : used to load the item with publication

# File services.rb, line 3159
def get_item_as_java primary_key, **named_arguments
  __get_item(primary_key, **named_arguments, type: :java) do |load_options|

    java_item = __item_service.getItem(primary_key, __service_load_options(load_options))

    # Convert to "pseudo" Java item if Hash
    java_item =  __convert(java_item, to: Item)

    java_item

  end
end
get_item_as_json(primary_key, **named_arguments) click to toggle source

Same as ‘get_item_as_java’, but returns the item in its “JSON” form.

In the “JSON” form, the item is a Hash object and any system values are accessible via their appropriate “<name>__” form. Note that multiple values are also stored differently than in the “JAVA” form!

# File services.rb, line 3178
def get_item_as_json primary_key, **named_arguments
  __get_item(primary_key, **named_arguments, type: :json) do |load_options|

    json_item = __item_service.getItemAsJson(primary_key, __service_load_options(load_options))

    # No conversion necessary
    json_item

  end
end
get_item_as_ruby(primary_key, **named_arguments) click to toggle source

Same as ‘get_item_as_java’, but returns the item in its “Ruby” form.

In the “Ruby” form, the item is of the “category” class defined in the data model.

# File services.rb, line 3194
def get_item_as_ruby primary_key, **named_arguments
  __get_item(primary_key, **named_arguments, type: :ruby) do |load_options|

    json_item = get_item_as_json(primary_key, **(load_options || {}))

    # Convert to Ruby
    ruby_item = PIM::Item.from_json(json_item, load_options) if json_item

    ruby_item

  end
end
get_item_as_xml(primary_key, **named_arguments) click to toggle source

Same as ‘get_item_as_java’, but returns the item in its “XML” form.

In the “XML” form, the item is a Ruby IO object and thus the properties cannot be accessed or set at all!

# File services.rb, line 3212
def get_item_as_xml primary_key, **named_arguments
  __get_item(primary_key, **named_arguments, type: :xml) do |load_options|

    xml_item = __item_service.getItemAsXml(primary_key, __service_load_options(load_options))

    # Return Ruby IO object from Java InputStream
    xml_item = xml_item.nil? ? nil : xml_item.to_io

    xml_item

  end
end
get_item_attribute_histories(primary_key, newest_first: true) click to toggle source

Returns a list of item attribute histories, each one containing the actual attribute changes. Specified ‘newest_first’ as ‘false’ to “reverse” the order of the entries.

E.g.

attribute_histories = get_item_attribute_histories('123')
attribute_histories.each do |attribute_history|
  user = attribute_history.updated_by
  date = attribute_history.updated_at
  checksum = attribute_history.checksum
  history_entries = attribute_history.history_entries
  history_entries.each do |history_entry|

    old_value = history_entry.old_value # Can be of Ruby class Number, Time, String or Nil
    new_value = history_entry.new_value # Can be of Ruby class Number, Time, String or Nil

  end
end

FIXME: Make method work in external Ruby, i.e. define ‘ItemAttributeHistory’ and ‘ItemAttributeHistoryEntry’ classes etc.!

# File services.rb, line 3406
def get_item_attribute_histories primary_key, newest_first: true
  __item_service.loadAllItemAttributeHistories(primary_key, newest_first)
end
get_item_event_history(primary_key, newest_first:, event_type: __item_service.loadAllItemEvents(primary_key, newest_first, event_type)) click to toggle source

Load the item event history for the specified primary key.

By default, the list of events is sorted from oldest to newest. To change, set the option ‘newest_first: true’. Also, to limit to specific event types, set the option ‘event_type: <EVENT_TYPE>’

# File services.rb, line 3231
def get_item_event_history primary_key, newest_first:, event_type:
  __item_service.loadAllItemEvents(primary_key, newest_first, event_type)
end
get_item_hierarchies(root_primary_key) click to toggle source

Returns all hierarchies with the specified root item

# File services.rb, line 3442
def get_item_hierarchies root_primary_key
  __convert(__item_service.getItemHierarchies(root_primary_key), to: ItemHierarchy, array: true, force: true)
end
get_item_hierarchy(root_primary_key, name, create: false) click to toggle source

Retrieve the named hiearchy for a root item. If not found, returns nil or a new, empty hierarchy, if create is true

# File services.rb, line 3432
def get_item_hierarchy root_primary_key, name, create: false
  item_hierarchy = __convert(__item_service.getItemHierarchy(root_primary_key, name.to_s), to: ItemHierarchy, force: true)
  if item_hierarchy.nil? and create
    item_hierarchy = ItemHierarchy.new(root_primary_key: root_primary_key, name: name)
  end
  item_hierarchy
end
get_item_status_value(primary_key, key) click to toggle source
# File services.rb, line 3410
def get_item_status_value primary_key, key
  __item_service.getItemStatusValue(primary_key, key.to_s)
end
get_item_status_values(primary_key, *keys) click to toggle source
# File services.rb, line 3414
def get_item_status_values primary_key, *keys
  keys = PIM.stringified_array(keys.compact)
  __item_service.getItemStatusValues(primary_key, *keys)
end
get_items_referenced_by_item_hierarchies(*item_primary_keys, format: :json, hierarchy_names: nil, load_queried_items: false, cache: true, max_number_of_items: 20) click to toggle source

Returns all items included in item hierarchies which include any of the specified items. Restricts to hierarchy names, unless nil. Specify the format in which the items should be returned. Valid values are either :json or :java. If load_queried_items is false, the items specified in item_primary_keys are excluded from the result. In max_number_of_items specify a maximum number of items. Use this to limit the result. Returns a list of items in either json or java format. Note that the returned items are also cached! This way, the method can be used to “preload” items for the validation.

# File services.rb, line 3480
def get_items_referenced_by_item_hierarchies *item_primary_keys, format: :json, hierarchy_names: nil, load_queried_items: false, cache: true, max_number_of_items: 20

  # Load items from service
  hierarchy_names = PIM::Utils.stringified_non_empty_set(hierarchy_names) unless hierarchy_names.nil?
  items = case PIM::Utils.to_sym(format)
    when :java then
      __convert(__item_service.getItemsReferencedByItemHierarchies(item_primary_keys, hierarchy_names, load_queried_items, max_number_of_items), to: Item, array: true)
    when :json then
      __item_service.getItemsReferencedByItemHierarchiesAsJson(item_primary_keys, hierarchy_names, load_queried_items, max_number_of_items)
    when nil then "Format must not be nil"
    else raise "Unknown format '#{format}'"
  end

  # Cache items, if necessary
  if cache and not PIM.is_empty?(items)
    data_module = PIM.active_module
    item_cache = data_module.item_cache(type: format)
    items.each do |item|
      primary_key = PIM::Utils.get_value(item, :primaryKey__)
      item_cache[primary_key] = item
    end
  end

  items

end
get_primary_keys_referenced_by_item_hierarchies(*item_primary_keys, hierarchy_names: nil) click to toggle source

Returns all item primary keys included in item hierarchies which include any of the specified items. Restricts to hierarchy names, unless nil.

# File services.rb, line 3468
def get_primary_keys_referenced_by_item_hierarchies *item_primary_keys, hierarchy_names: nil
  __item_service.getPrimaryKeysReferencedByItemHierarchies(item_primary_keys, hierarchy_names)
end
get_referenced_item_hierarchies(*item_primary_keys, hierarchy_names: nil) click to toggle source

Returns all item hierarchies which include any of the specified items. Restricts to hierarchy names, unless nil.

# File services.rb, line 3461
def get_referenced_item_hierarchies *item_primary_keys, hierarchy_names: nil
  __convert(__item_service.getReferencedItemHierarchies(item_primary_keys, hierarchy_names), to: ItemHierarchy, array: true, force: true)
end
has_any_item_hierarchy(root_primary_key) click to toggle source

Returns true, if at least one hierarchy exists for the specified root item, false otherwise

# File services.rb, line 3454
def has_any_item_hierarchy root_primary_key
  __item_service.hasAnyItemHierarchy(root_primary_key)
end
has_item_hierarchy(root_primary_key, name) click to toggle source

Returns true, if the named hierarchy for a root item exists, false otherwise

# File services.rb, line 3448
def has_item_hierarchy root_primary_key, name
  __item_service.hasItemHierarchy(root_primary_key, name.to_s)
end
save_item_hierarchy(item_hierarchy) click to toggle source

Explicitly save the specified hierarchy.

# File services.rb, line 3509
def save_item_hierarchy item_hierarchy
  __convert(__item_service.saveItemHierarchy(PIM.as_json(item_hierarchy)), to: ItemHierarchy, force: true)
end
search_items(keyword: nil, tag: nil, **opts) click to toggle source

Search items by keyword or tag.

keyword:

  • a string keyword, e.g. gln:4565564

opts:

  • count : The maximum number of items per page (default: 20)

  • sort : A list of fields to sort by (default: none)

  • direction : The appropriate directions of the sort fields (default: none)

  • cursor : A cursor string, as returned in the result object of this method (default: empty)

  • fields : The list of fields to return (default: all fields)

# File services.rb, line 3367
def search_items keyword: nil, tag: nil, **opts

  query_params = {}
  query_params[:keyword] = keyword
  query_params[:tags] = tag
  query_params[:count] = opts[:count]
  query_params[:sort] = opts[:sort]
  query_params[:direction] = opts[:direction]
  query_params[:cursor] = opts[:cursor]
  query_params[:fields] = opts[:fields]
  query_params = PIM.stringified_value(query_params)

  search_result = __convert(__item_search_service.searchItems(query_params), to: ItemSearchResult)

  return search_result

end
update_item_status_values(primary_key, status_values) click to toggle source
# File services.rb, line 3419
def update_item_status_values primary_key, status_values
  status_values = PIM.stringified_hash(status_values)
  __item_service.updateItemStatusValues(primary_key, status_values)
end