lib/amee/data_item_value.rb in amee-2.0.31 vs lib/amee/data_item_value.rb in amee-2.0.32
- old
+ new
@@ -1,6 +1,7 @@
module AMEE
+ Epoch=DateTime.parse(Time.at(0).xmlschema).utc
module Data
class ItemValue < AMEE::Data::Object
def initialize(data = {})
@value = data ? data[:value] : nil
@@ -32,21 +33,33 @@
def from_data?
@from_data
end
- def start_date
- @start_date
+ attr_accessor :start_date
+ attr_accessor :uid
+
+ def uid_path
+ # create a path which is safe for DIVHs by using the UID if one is avai
+ if uid
+ @path.split(/\//)[0..-2].push(uid).join('/')
+ else
+ @path
+ end
end
-
+
+ def full_uid_path
+ "/data#{uid_path}"
+ end
+
def self.from_json(json, path)
# Read JSON
- doc = JSON.parse(json)['itemValue']
+ doc = json.is_a?(String) ? JSON.parse(json)['itemValue'] : json
data = {}
data[:uid] = doc['uid']
- data[:created] = DateTime.parse(doc['created'])
- data[:modified] = DateTime.parse(doc['modified'])
+ data[:created] = DateTime.parse(doc['created']) rescue nil
+ data[:modified] = DateTime.parse(doc['modified']) rescue nil
data[:name] = doc['name']
data[:path] = path.gsub(/^\/data/, '')
data[:value] = doc['value']
data[:type] = doc['itemValueDefinition']['valueDefinition']['valueType']
data[:start_date] = DateTime.parse(doc['startDate']) rescue nil
@@ -56,26 +69,31 @@
raise AMEE::BadData.new("Couldn't load DataItemValue from JSON. Check that your URL is correct.\n#{json}")
end
def self.from_xml(xml, path)
# Read XML
- doc = REXML::Document.new(xml)
+ doc = xml.is_a?(String) ? REXML::Document.new(xml) : xml
data = {}
- data[:uid] = REXML::XPath.first(doc, "/Resources/DataItemValueResource/ItemValue/@uid").to_s
- data[:created] = DateTime.parse(REXML::XPath.first(doc, "/Resources/DataItemValueResource/ItemValue/@Created").to_s)
- data[:modified] = DateTime.parse(REXML::XPath.first(doc, "/Resources/DataItemValueResource/ItemValue/@Modified").to_s)
- data[:name] = REXML::XPath.first(doc, '/Resources/DataItemValueResource/ItemValue/Name').text
- data[:path] = path.gsub(/^\/data/, '')
- data[:value] = REXML::XPath.first(doc, '/Resources/DataItemValueResource/ItemValue/Value').text
- data[:type] = REXML::XPath.first(doc, '/Resources/DataItemValueResource/ItemValue/ItemValueDefinition/ValueDefinition/ValueType').text
- data[:from_profile] = REXML::XPath.first(doc, '/Resources/DataItemValueResource/ItemValue/ItemValueDefinition/FromProfile').text == "true" ? true : false
- data[:from_data] = REXML::XPath.first(doc, '/Resources/DataItemValueResource/ItemValue/ItemValueDefinition/FromData').text == "true" ? true : false
- data[:start_date] = DateTime.parse(REXML::XPath.first(doc, "/Resources/DataItemValueResource/ItemValue/StartDate").text) rescue nil
- # Create object
- ItemValue.new(data)
- rescue
- raise AMEE::BadData.new("Couldn't load DataItemValue from XML. Check that your URL is correct.\n#{xml}")
+ if REXML::XPath.match(doc,"descendant-or-self::ItemValue").length>1
+ raise AMEE::BadData.new("Couldn't load DataItemValue from XML. This is an item value history.\n#{xml}")
+ end
+ begin
+ data[:uid] = REXML::XPath.first(doc, "descendant-or-self::ItemValue/@uid").to_s
+ data[:created] = DateTime.parse(REXML::XPath.first(doc, "descendant-or-self::ItemValue/@Created").to_s) rescue nil
+ data[:modified] = DateTime.parse(REXML::XPath.first(doc, "descendant-or-self::ItemValue/@Modified").to_s) rescue nil
+ data[:name] = REXML::XPath.first(doc, 'descendant-or-self::ItemValue/Name').text
+ data[:path] = path.gsub(/^\/data/, '')
+ data[:value] = REXML::XPath.first(doc, 'descendant-or-self::ItemValue/Value').text
+ data[:type] = REXML::XPath.first(doc, 'descendant-or-self::ItemValue/ItemValueDefinition/ValueDefinition/ValueType').text
+ data[:from_profile] = false
+ data[:from_data] = true
+ data[:start_date] = DateTime.parse(REXML::XPath.first(doc, "descendant-or-self::ItemValue/StartDate").text) rescue nil
+ # Create object
+ ItemValue.new(data)
+ rescue
+ raise AMEE::BadData.new("Couldn't load DataItemValue from XML. Check that your URL is correct.\n#{xml}")
+ end
end
def self.get(connection, path)
# Load data from path
response = connection.get(path).body
@@ -87,13 +105,38 @@
rescue
raise AMEE::BadData.new("Couldn't load DataItemValue. Check that your URL is correct.")
end
def save!
- response = @connection.put(full_path, :value => value).body
+ if start_date
+ ItemValue.update(connection,full_uid_path,:value=>value,
+ :start_date=>start_date,:get_item=>false)
+ else
+ ItemValue.update(connection,full_uid_path,:value=>value,:get_item=>false)
+ end
end
+ def delete!
+ raise AMEE::BadData.new("Cannot delete initial value for time series") if start_date==AMEE::Epoch
+ ItemValue.delete @connection,full_uid_path
+ end
+
+ def create!
+ data_item_path=path.split(/\//)[0..-2].join('/')
+ data_item=AMEE::Data::Item.new
+ data_item.path=data_item_path
+ data_item.connection=connection
+ data_item.connection or raise "No connection to AMEE available"
+ if start_date
+ ItemValue.create(data_item,:start_date=>start_date,
+ @path.split(/\//).pop.to_sym => value,:get_item=>false)
+ else
+ ItemValue.create(data_item,
+ @path.split(/\//).pop.to_sym => value,:get_item=>false)
+ end
+ end
+
def self.parse(connection, response, path)
if response.is_json?
value = ItemValue.from_json(response, path)
else
value = ItemValue.from_xml(response, path)
@@ -105,27 +148,28 @@
rescue
raise AMEE::BadData.new("Couldn't load DataItemValue. Check that your URL is correct.\n#{response}")
end
def self.create(data_item, options = {})
+
# 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
+
# Set startDate
if (options[:start_date])
options[:startDate] = options[:start_date].xmlschema
options.delete(:start_date)
end
-
+
response = data_item.connection.post(data_item.full_path, options)
location = response['Location'].match("http://.*?(/.*)")[1]
-
if get_item == true
get_options = {}
get_options[:format] = format if format
return AMEE::Data::ItemValue.get(data_item.connection, location)
else
@@ -137,10 +181,15 @@
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?
+ # Set startDate
+ if (options[:start_date])
+ options[:startDate] = options[:start_date].xmlschema if options[:start_date]!=Epoch
+ options.delete(:start_date)
+ end
# Go
response = connection.put(path, options)
if get_item
if response.body.empty?
return AMEE::Data::ItemValue.get(connection, path)
@@ -153,14 +202,15 @@
end
def update(options = {})
AMEE::Data::ItemValue.update(connection, full_path, options)
end
-
+
+
def self.delete(connection, path)
connection.delete(path)
- rescue
- raise AMEE::BadData.new("Couldn't delete DataItemValue. Check that your information is correct.")
+ rescue
+ raise AMEE::BadData.new("Couldn't delete DataItemValue. Check that your information is correct.")
end
end
end
end