require 'date' module AMEE module Data class Category < AMEE::Data::Object def initialize(data = {}) @children = data ? data[:children] : [] @items = data ? data[:items] : [] @pager = data ? data[:pager] : nil @itemdef = data ? data[:itemdef] : nil super end attr_reader :children attr_reader :items attr_reader :pager attr_reader :itemdef def self.from_json(json) # Parse json doc = JSON.parse(json) data = {} data[:uid] = doc['dataCategory']['uid'] data[:created] = DateTime.parse(doc['dataCategory']['created']) data[:modified] = DateTime.parse(doc['dataCategory']['modified']) data[:name] = doc['dataCategory']['name'] data[:path] = doc['path'] data[:children] = [] data[:pager] = AMEE::Pager.from_json(doc['children']['pager']) itemdef=doc['dataCategory']['itemDefinition'] data[:itemdef] = itemdef ? itemdef['uid'] : nil doc['children']['dataCategories'].each do |child| category_data = {} category_data[:name] = child['name'] category_data[:path] = child['path'] category_data[:uid] = child['uid'] data[:children] << category_data end data[:items] = [] if doc['children']['dataItems']['rows'] doc['children']['dataItems']['rows'].each do |item| item_data = {} item.each_pair do |key, value| item_data[key.to_sym] = value end data[:items] << item_data end end # Create object Category.new(data) rescue raise AMEE::BadData.new("Couldn't load DataCategory from JSON data. Check that your URL is correct.\n#{json}") end def self.from_xml(xml) # Parse XML doc = REXML::Document.new(xml) data = {} data[:uid] = REXML::XPath.first(doc, "/Resources/DataCategoryResource/DataCategory/@uid").to_s data[:created] = DateTime.parse(REXML::XPath.first(doc, "/Resources/DataCategoryResource/DataCategory/@created").to_s) data[:modified] = DateTime.parse(REXML::XPath.first(doc, "/Resources/DataCategoryResource/DataCategory/@modified").to_s) data[:name] = REXML::XPath.first(doc, '/Resources/DataCategoryResource/DataCategory/?ame').text data[:path] = REXML::XPath.first(doc, '/Resources/DataCategoryResource//?ath').text || "" data[:pager] = AMEE::Pager.from_xml(REXML::XPath.first(doc, '//Pager')) itemdefattrib=REXML::XPath.first(doc, '/Resources/DataCategoryResource//ItemDefinition/@uid') data[:itemdef] = itemdefattrib ? itemdefattrib.to_s : nil data[:children] = [] REXML::XPath.each(doc, '/Resources/DataCategoryResource//Children/DataCategories/DataCategory') do |child| category_data = {} category_data[:name] = (child.elements['Name'] || child.elements['name']).text category_data[:path] = (child.elements['Path'] || child.elements['path']).text category_data[:uid] = child.attributes['uid'].to_s data[:children] << category_data end data[:items] = [] REXML::XPath.each(doc, '/Resources/DataCategoryResource//Children/DataItems/DataItem') do |item| item_data = {} item_data[:uid] = item.attributes['uid'].to_s item.elements.each do |element| item_data[element.name.to_sym] = element.text end if item_data[:path].nil? item_data[:path] = item_data[:uid] end data[:items] << item_data end # Create object Category.new(data) rescue raise AMEE::BadData.new("Couldn't load DataCategory from XML data. Check that your URL is correct.\n#{xml}") end def self.get(connection, path, orig_options = {}) unless orig_options.is_a?(Hash) raise AMEE::ArgumentError.new("Third argument must be a hash of options!") end # Convert to AMEE options options = orig_options.clone if orig_options[:items_per_page] options[:itemsPerPage] = orig_options[:items_per_page] else options[:itemsPerPage] = 10 end # Load data from path response = connection.get(path, options).body # Parse data from response if response.is_json? cat = Category.from_json(response) else cat = Category.from_xml(response) end # Store connection in object for future use cat.connection = connection # Done return cat rescue raise AMEE::BadData.new("Couldn't load DataCategory. Check that your URL is correct.\n#{response}") end def self.root(connection) self.get(connection, '/data') end def child(child_path) AMEE::Data::Category.get(connection, "#{full_path}/#{child_path}") end def drill AMEE::Data::DrillDown.get(connection, "#{full_path}/drill") end def item(options) # Search fields - from most specific to least specific item = items.find{ |x| (x[:uid] && x[:uid] == options[:uid]) || (x[:name] && x[:name] == options[:name]) || (x[:path] && x[:path] == options[:path]) || (x[:label] && x[:label] == options[:label]) } # Pass through some options new_opts = {} new_opts[:format] = options[:format] if options[:format] item ? AMEE::Data::Item.get(connection, "#{full_path}/#{item[:path]}", new_opts) : nil end def self.create(category, options = {}) connection = category.connection path = category.full_path # Do we want to automatically fetch the item afterwards? get_item = options.delete(:get_item) get_item = true if get_item.nil? # Store format if set format = options[:format] unless options.is_a?(Hash) raise AMEE::ArgumentError.new("Third argument must be a hash of options!") end # Send data to path options[:newObjectType] = "DC" response = connection.post(path, options) if response['Location'] location = response['Location'].match("http://.*?(/.*)")[1] else category = Category.parse(connection, response.body) location = category.full_path end if get_item == true get_options = {} get_options[:format] = format if format return AMEE::Data::Category.get(connection, location, get_options) else return location end rescue raise AMEE::BadData.new("Couldn't create DataCategory. Check that your information is correct.\n#{response}") end def self.delete(connection, path) connection.delete(path) rescue raise AMEE::BadData.new("Couldn't delete DataCategory. Check that your information is correct.") end def self.update(connection, path, options = {}) # Do we want to automatically fetch the item afterwards? get_item = options.delete(:get_item) get_item = true if get_item.nil? # Go response = connection.put(path, options) if get_item if response.body.empty? return Category.get(connection, path) else return Category.parse(connection, response.body) end end rescue raise AMEE::BadData.new("Couldn't update Data Category. Check that your information is correct.") end end end end