Class: Gloo::Objs::Json

Inherits:
Core::Obj show all
Defined in:
lib/gloo/objs/web/json.rb

Constant Summary collapse

KEYWORD =
'json'.freeze
KEYWORD_SHORT =
'json'.freeze

Constants inherited from Core::Baseo

Core::Baseo::NOT_IMPLEMENTED_ERR

Instance Attribute Summary

Attributes inherited from Core::Obj

#children, #parent, #value

Attributes inherited from Core::Baseo

#name

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Core::Obj

#add_child, #add_children_on_create?, #add_default_children, can_create?, #can_receive_message?, #child_count, #child_index, #contains_child?, #delete_children, #dispatch, #display_value, #find_add_child, #find_child, #find_child_resolve_alias, #find_child_value, help, inherited, #initialize, #is_alias?, #is_container?, #is_function?, #msg_blank?, #msg_contains?, #msg_reload, #msg_responds_to?, #msg_unload, #pn, #remove_child, #render, #root?, #send_message, #set_parent, #sql_value, #type_display, #value_display, #value_is_array?, #value_is_blank?, #value_string?

Methods inherited from Core::Baseo

#initialize, #type_display

Constructor Details

This class inherits a constructor from Gloo::Core::Obj

Class Method Details

.convert_obj_to_hash(obj) ⇒ Object

Convert the object to a hash of name and values.



157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/gloo/objs/web/json.rb', line 157

def self.convert_obj_to_hash( obj )
  h = {}

  if obj.child_count > 0
    obj.children.each do |child|
      h[ child.name ] = convert_obj_to_hash( child )
    end
  else
    return obj.value
  end

  return h
end

.convert_obj_to_json(obj) ⇒ Object

Convert the object to JSON.



147
148
149
150
151
152
# File 'lib/gloo/objs/web/json.rb', line 147

def self.convert_obj_to_json( obj )
  h = obj ? convert_obj_to_hash( obj ) : {}
  json = JSON.parse( h.to_json )
  json = JSON.pretty_generate( json )
  return json
end

.doc_dataObject

Get the object's documentation data.



212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
# File 'lib/gloo/objs/web/json.rb', line 212

def self.doc_data
  {
    :name => KEYWORD,
    :shortcut => KEYWORD_SHORT,
    :description => 'JSON data in a text string.',
    :messages => [
      'get ({path}) — Get a value from the JSON data. Example: tell myjson to get (\'title\'). The parameter is the path in JSON to the value we want. The value is put into it.',
      'set ({obj.path}) — Convert an object to an approximate JSON value. Example: tell myjson to set (my.object). The parameter is the path to the object used as the source. Note this is an approximate conversion — a gloo object can have both a simple value and be a container for child objects, which JSON can\'t represent the same way.',
      'parse ({dst.path}) — Parse the JSON data and put values in the object specified by the parameter. Example: tell myjson to parse (path.to.dst).',
      'pretty — Make the JSON format pretty.'
    ],
    :examples => <<~EXAMPLES.strip
      #
      # Get values from within a JSON object.
      #

      json_get [can] :
        on_load [script] :
          tell json_get.payload to get ('msg')
          show it
          tell json_get.payload to get ('sub.data')
          show it
          tell json_get.payload to get ('sub.child.msg')
          show it
        payload [json] : BEGIN
          { "msg":"The message from inside a JSON block",
            "sub":{"data":"in sub-object",
              "child":{"msg":"third level"}} }
          END
    EXAMPLES
  }
end

.get_value_in_json(json, path_to_value) ⇒ Object

Parse the JSON data and look for the value within it.



197
198
199
200
201
202
203
# File 'lib/gloo/objs/web/json.rb', line 197

def self.get_value_in_json( json, path_to_value )
  data = JSON.parse( json )
  path_to_value.split( '.' ).each do |segment|
    data = data[ segment ]
  end
  return data
end

.messagesObject

Get a list of message names that this object receives.



58
59
60
# File 'lib/gloo/objs/web/json.rb', line 58

def self.messages
  return super + %w[get set parse pretty]
end

.short_typenameObject

The short name of the object type.



25
26
27
# File 'lib/gloo/objs/web/json.rb', line 25

def self.short_typename
  return KEYWORD_SHORT
end

.typenameObject

The name of the object type.



18
19
20
# File 'lib/gloo/objs/web/json.rb', line 18

def self.typename
  return KEYWORD
end

Instance Method Details

#handle_json_to_obj(json, parent) ⇒ Object

Handle JSON, creating objects and setting values. Note that this is a recursive function.



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/gloo/objs/web/json.rb', line 175

def handle_json_to_obj( json, parent )
  if json.class == Hash
    json.each do |k, v|
      if ( v.class == Array ) || ( v.class == Hash )
        o = parent.find_add_child( k, 'can' )
        handle_json_to_obj( v, o )
      else
        o = parent.find_add_child( k, 'untyped' )
        o.set_value v
      end
    end
  elsif json.class == Array
    json.each_with_index do |o, index|
      child = parent.find_add_child( index.to_s, 'can' )
      handle_json_to_obj( o, child )
    end
  end
end

#line_countObject

Get the number of lines of text.



47
48
49
# File 'lib/gloo/objs/web/json.rb', line 47

def line_count
  return value.split( "\n" ).count
end

#msg_getObject

Get a value from the JSON data. The additional parameter is the path to the value.



80
81
82
83
84
85
86
87
88
89
90
# File 'lib/gloo/objs/web/json.rb', line 80

def msg_get
  if @params&.token_count&.positive?
    expr = Gloo::Expr::Expression.new( @engine, @params.tokens )
    data = expr.evaluate
  end
  return unless data

  field = Gloo::Objs::Json.get_value_in_json self.value, data
  @engine.heap.it.set_to field
  return field
end

#msg_parseObject

Parse the JSON data and put it in objects. The additional parameter is the path to the destination for the parsed objects.



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/gloo/objs/web/json.rb', line 123

def msg_parse
  if @params&.token_count&.positive?
    pn = Gloo::Core::Pn.new( @engine, @params.tokens.first )
    unless pn&.exists?
      @engine.err 'Destination path for parsed objects does not exist'
      return
    end
  else
    @engine.err 'Destination path for parsed objects is required'
    return
  end
  parent = pn.resolve

  json = JSON.parse( self.value )
  self.handle_json_to_obj( json, parent )
end

#msg_prettyObject

Make the JSON pretty.



65
66
67
68
69
70
71
72
73
74
# File 'lib/gloo/objs/web/json.rb', line 65

def msg_pretty
  return unless self.value

  json = JSON.parse( self.value )
  if self.value.start_with?( '"{' )
    json = JSON.parse( json )
  end
  pretty = JSON.pretty_generate( json )
  set_value pretty
end

#msg_setObject

Convert the target object to JSON and set the value of this JSON to that value.



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/gloo/objs/web/json.rb', line 96

def msg_set
  if @params&.token_count&.positive?
    pn = Gloo::Core::Pn.new( @engine, @params.tokens.first )
    unless pn&.exists?
      @engine.err 'Source path for objects does not exist'
      return
    end
  else
    @engine.err 'Source path for objects is required'
    return
  end
  parent = pn.resolve

  h = Json.convert_obj_to_hash( parent )
  json = JSON.parse( h.to_json )
  json = JSON.pretty_generate( json )

  set_value json
  @engine.heap.it.set_to json
  return json
end

#multiline_value?Boolean

Does this object support multi-line values? Initially only true for scripts.

Returns:



40
41
42
# File 'lib/gloo/objs/web/json.rb', line 40

def multiline_value?
  return false
end

#set_value(new_value) ⇒ Object

Set the value with any necessary type conversions.



32
33
34
# File 'lib/gloo/objs/web/json.rb', line 32

def set_value( new_value )
  self.value = new_value.to_s
end