Class: WAB::Impl::Data

Inherits:
Data
  • Object
show all
Defined in:
lib/wab/impl/data.rb

Overview

The class representing the cananical data structure in WAB. Typically the Data instances are factory created by the Shell and will most likely not be instance of this class but rather a class that is a duck-type of this class (has the same methods and behavior).

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(value, repair, check = true) ⇒ Data

This method should not be called directly. New instances should be created by using a Shell#data method.

Creates a new Data instance with the initial value provided. The value must be a Hash or Array. The members of the Hash or Array must be nil, boolean, String, Integer, Float, BigDecimal, Array, Hash, Time, WAB::UUID, or the Ruby URI::HTTP.

value

initial value

repair

flag indicating invalid value should be repaired if possible



46
47
48
49
50
51
52
53
# File 'lib/wab/impl/data.rb', line 46

def initialize(value, repair, check=true)
  if repair
    value = fix(value)
  elsif check
    validate(value)
  end
  @root = value
end

Instance Attribute Details

#rootObject (readonly) Also known as: native

Returns the value of attribute root.



14
15
16
# File 'lib/wab/impl/data.rb', line 14

def root
  @root
end

Class Method Details

.detect_string(s) ⇒ Object



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/wab/impl/data.rb', line 16

def self.detect_string(s)
  if WAB::Utils.uuid_format?(s)
    WAB::UUID.new(s)
  elsif WAB::Utils.wab_time_format?(s)
    begin
      DateTime.parse(s).to_time
    rescue
      s
    end
  elsif s.downcase.start_with?('http://')
    begin
      URI(s)
    rescue
      s
    end
  else
    s
  end
end

Instance Method Details

#deep_dupObject

Make a deep copy of the Data instance.



138
139
140
141
142
143
# File 'lib/wab/impl/data.rb', line 138

def deep_dup()
  # avoid validation by using a empty Hash for the intial value.
  c = self.class.new({}, false)
  c.instance_variable_set(:@root, deep_dup_value(@root))
  c
end

#detectObject

Detects and converts strings to Ruby objects following the rules:

Time

“2017-01-05T15:04:33.123456789Z”, zulu only

UUID

“b0ca922d-372e-41f4-8fea-47d880188ba3”

URI

opo.technology/sample”, HTTP only



154
155
156
157
# File 'lib/wab/impl/data.rb', line 154

def detect()
  return detect_hash(@root) if @root.is_a?(Hash)
  detect_array(@root) if @root.is_a?(Array)
end

#each(&block) ⇒ Object

Each child of the Data instance is provided as an argument to a block when the each method is called.



125
126
127
# File 'lib/wab/impl/data.rb', line 125

def each(&block)
  each_node([], @root, block)
end

#each_leaf(&block) ⇒ Object

Each leaf of the Data instance is provided as an argument to a block when the each method is called. A leaf is a primitive that has no children and will be nil, a Boolean, String, Numberic, Time, WAB::UUID, or URI.



133
134
135
# File 'lib/wab/impl/data.rb', line 133

def each_leaf(&block)
  each_leaf_node([], @root, block)
end

#get(path) ⇒ Object

Gets the Data element or value identified by the path where the path elements are separated by the ‘.’ character. The path can also be a array of path node identifiers. For example, child.grandchild is the same as [‘child’, ‘grandchild’].



90
91
92
93
94
95
# File 'lib/wab/impl/data.rb', line 90

def get(path)
  node = Utils.get_node(@root, path)

  return node unless node.is_a?(Hash) || node.is_a?(Array)
  Data.new(node, false, false)
end

#has?(path) ⇒ Boolean

Returns true if the Data element or value identified by the path exists where the path elements are separated by the ‘.’ character. The path can also be a array of path node identifiers. For example, child.grandchild is the same as [‘child’, ‘grandchild’].

Returns:

  • (Boolean)


63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/wab/impl/data.rb', line 63

def has?(path)
  return (@root.is_a?(Hash) && @root.has_key?(path)) if path.is_a?(Symbol)

  path = path.to_s.split('.') unless path.is_a?(Array)
  node = @root
  path.each { |key|
    if node.is_a?(Hash)
      key = key.to_sym
      return false unless node.has_key?(key)
      node = node[key]
    elsif node.is_a?(Array)
      i = key.to_i
      return false if 0 == i && '0' != key && 0 != key
      len = node.length
      return false unless -len <= i && i < len
      node = node[i]
    else
      return false
    end
  }
  true
end

#json(indent = 0) ⇒ Object

Encode the data as a JSON string.



146
147
148
# File 'lib/wab/impl/data.rb', line 146

def json(indent=0)
  Oj.dump(@root, mode: :wab, indent: indent)
end

#set(path, value, repair = false) ⇒ Object

Sets the node value identified by the path where the path elements are separated by the ‘.’ character. The path can also be a array of path node identifiers. For example, child.grandchild is the same as [‘child’, ‘grandchild’]. The value must be one of the allowed data values described in the initialize method.

For arrays, the behavior is similar to an Array#[] with the exception of a negative index less than the negative length in which case the value is prepended (Array#unshift).

path

path to location to be set

value

value to set

repair

flag indicating invalid value should be repaired if possible

Raises:



110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/wab/impl/data.rb', line 110

def set(path, value, repair=false)
  raise WAB::Error, 'path can not be empty.' if path.empty?
  if value.is_a?(WAB::Data)
    value = value.native
  elsif repair
    value = fix_value(value)
  else
    validate_value(value)
  end
  node = @root
  Utils.set_value(node, path, value)
end