Class: Rfm::SaxParser::Cursor

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/rfm/utilities/sax_parser.rb

Overview

A Cursor instance is created for each element encountered in the parsing run and is where the parsing result is constructed from the custom parsing template. The cursor is the glue between the handler and the resulting object build. The cursor receives input from the handler, loads the corresponding template data, and manipulates the incoming xml data to build the resulting object.

Each cursor is added to the stack when its element begins, and removed from the stack when its element ends. The cursor tracks all the important objects necessary to build the resulting object. If you call #cursor on the handler, you will always get the last object added to the stack. Think of a cursor as a framework of tools that accompany each element’s build process.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(_tag, _handler, _parent = nil, _initial_attributes = nil) ⇒ Cursor

, caller_binding=nil)



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/rfm/utilities/sax_parser.rb', line 183

def initialize(_tag, _handler, _parent=nil, _initial_attributes=nil) #, caller_binding=nil)
  #def initialize(_model, _obj, _tag, _handler)
  @tag     =  _tag
  @handler = _handler
  @parent = _parent || self
  @initial_attributes = _initial_attributes
  @level = @parent.level.to_i + 1
  @local_model = (model_elements?(@tag, @parent.model) || DEFAULT_CLASS.new)
  @element_attachment_prefs = attachment_prefs(@parent.model, @local_model, 'element')
  #@attribute_attachment_prefs = attachment_prefs(@parent.model, @local_model, 'attribute')

  if @element_attachment_prefs.is_a? Array
    @new_element_callback = @element_attachment_prefs[1..-1]
    @element_attachment_prefs = @element_attachment_prefs[0]
    if @element_attachment_prefs.to_s == 'default'
      @element_attachment_prefs = nil
    end
  end

  #puts ["\nINITIALIZE_CURSOR tag: #{@tag}", "parent.object: #{@parent.object.class}", "local_model: #{@local_model.class}", "el_prefs: #{@element_attachment_prefs}",  "new_el_callback: #{@new_element_callback}", "attributes: #{@initial_attributes}"]

  self
end

Instance Attribute Details

#element_attachment_prefsObject

model - currently active model (rename to current_model) local_model - model of this cursor’s tag (rename to local_model) newtag - incoming tag of yet-to-be-created cursor. Get rid of this if you can. element_attachment_prefs - local object’s attachment prefs based on local_model and current_model. level - cursor depth



158
159
160
# File 'lib/rfm/utilities/sax_parser.rb', line 158

def element_attachment_prefs
  @element_attachment_prefs
end

#handlerObject

model - currently active model (rename to current_model) local_model - model of this cursor’s tag (rename to local_model) newtag - incoming tag of yet-to-be-created cursor. Get rid of this if you can. element_attachment_prefs - local object’s attachment prefs based on local_model and current_model. level - cursor depth



158
159
160
# File 'lib/rfm/utilities/sax_parser.rb', line 158

def handler
  @handler
end

#initial_attributesObject

model - currently active model (rename to current_model) local_model - model of this cursor’s tag (rename to local_model) newtag - incoming tag of yet-to-be-created cursor. Get rid of this if you can. element_attachment_prefs - local object’s attachment prefs based on local_model and current_model. level - cursor depth



158
159
160
# File 'lib/rfm/utilities/sax_parser.rb', line 158

def initial_attributes
  @initial_attributes
end

#levelObject

model - currently active model (rename to current_model) local_model - model of this cursor’s tag (rename to local_model) newtag - incoming tag of yet-to-be-created cursor. Get rid of this if you can. element_attachment_prefs - local object’s attachment prefs based on local_model and current_model. level - cursor depth



158
159
160
# File 'lib/rfm/utilities/sax_parser.rb', line 158

def level
  @level
end

#local_modelObject

model - currently active model (rename to current_model) local_model - model of this cursor’s tag (rename to local_model) newtag - incoming tag of yet-to-be-created cursor. Get rid of this if you can. element_attachment_prefs - local object’s attachment prefs based on local_model and current_model. level - cursor depth



158
159
160
# File 'lib/rfm/utilities/sax_parser.rb', line 158

def local_model
  @local_model
end

#modelObject

model - currently active model (rename to current_model) local_model - model of this cursor’s tag (rename to local_model) newtag - incoming tag of yet-to-be-created cursor. Get rid of this if you can. element_attachment_prefs - local object’s attachment prefs based on local_model and current_model. level - cursor depth



158
159
160
# File 'lib/rfm/utilities/sax_parser.rb', line 158

def model
  @model
end

#new_element_callbackObject

model - currently active model (rename to current_model) local_model - model of this cursor’s tag (rename to local_model) newtag - incoming tag of yet-to-be-created cursor. Get rid of this if you can. element_attachment_prefs - local object’s attachment prefs based on local_model and current_model. level - cursor depth



158
159
160
# File 'lib/rfm/utilities/sax_parser.rb', line 158

def new_element_callback
  @new_element_callback
end

#objectObject

model - currently active model (rename to current_model) local_model - model of this cursor’s tag (rename to local_model) newtag - incoming tag of yet-to-be-created cursor. Get rid of this if you can. element_attachment_prefs - local object’s attachment prefs based on local_model and current_model. level - cursor depth



158
159
160
# File 'lib/rfm/utilities/sax_parser.rb', line 158

def object
  @object
end

#parentObject

model - currently active model (rename to current_model) local_model - model of this cursor’s tag (rename to local_model) newtag - incoming tag of yet-to-be-created cursor. Get rid of this if you can. element_attachment_prefs - local object’s attachment prefs based on local_model and current_model. level - cursor depth



158
159
160
# File 'lib/rfm/utilities/sax_parser.rb', line 158

def parent
  @parent
end

#tagObject

model - currently active model (rename to current_model) local_model - model of this cursor’s tag (rename to local_model) newtag - incoming tag of yet-to-be-created cursor. Get rid of this if you can. element_attachment_prefs - local object’s attachment prefs based on local_model and current_model. level - cursor depth



158
159
160
# File 'lib/rfm/utilities/sax_parser.rb', line 158

def tag
  @tag
end

Class Method Details

.get_constant(klass) ⇒ Object

Main get-constant method



166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/rfm/utilities/sax_parser.rb', line 166

def self.get_constant(klass)
  #puts "Getting constant '#{klass.to_s}'"

  case
  when klass.is_a?(Class); klass
    #when (klass=klass.to_s) == ''; DEFAULT_CLASS
  when klass.nil?; DEFAULT_CLASS
  when klass == ''; DEFAULT_CLASS
  when klass[/::/]; eval(klass)
  when defined?(klass); const_get(klass)  ## == 'constant'; const_get(klass)
    #when defined?(klass); eval(klass) # This was for 'element_handler' pattern.
  else
    Rfm.log.warn "Could not find constant '#{klass}'"
    DEFAULT_CLASS
  end
end

Instance Method Details

#accessor?(_model = @model) ⇒ Boolean

Returns:

  • (Boolean)


542
# File 'lib/rfm/utilities/sax_parser.rb', line 542

def accessor?(_model=@model); _model && _model['accessor'] && [_model['accessor']].flatten.compact; end

#as_name?(_model = @model) ⇒ Boolean

Returns:

  • (Boolean)


539
# File 'lib/rfm/utilities/sax_parser.rb', line 539

def as_name?(_model=@model); _model && _model['as_name']; end

#assign_attributes(_attributes) ⇒ Object

Assign attributes to element.



419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
# File 'lib/rfm/utilities/sax_parser.rb', line 419

def assign_attributes(_attributes)
  if _attributes && !_attributes.empty?

    _attributes.each do |k,v|
      #attach_new_object(base_object, v, k, base_model, model_attributes?(k, new_model), 'attribute')}
      attr_model = model_attributes?(k, @local_model)

      label = label_or_tag(k, attr_model)

      prefs = [attachment_prefs(@model, attr_model, 'attribute')].flatten(1)[0]

      shared_var_name = shared_variable_name(prefs)
      (prefs = "shared") if shared_var_name

      # Use local create_accessors prefs first, then more general ones.
      create_accessors = accessor?(attr_model) || create_accessors?(@model)
      #(create_accessors = create_accessors?(@model)) unless create_accessors && create_accessors.any?

      #puts ["\nATTACH_NEW_OBJECT 1", "type: #{type}", "label: #{label}", "base_object: #{base_object.class}", "new_object: #{new_object.class}", "delimiter: #{delimiter?(new_model)}", "prefs: #{prefs}", "shared_var_name: #{shared_var_name}", "create_accessors: #{create_accessors}"]
      @object._attach_object!(v, label, delimiter?(attr_model), prefs, 'attribute', :default_class=>DEFAULT_CLASS, :shared_variable_name=>shared_var_name, :create_accessors=>create_accessors)
    end

  end
end

#attach?(_model = @model) ⇒ Boolean

Returns:

  • (Boolean)


535
# File 'lib/rfm/utilities/sax_parser.rb', line 535

def attach?(_model=@model); _model && _model['attach']; end

#attach_attributes?(_model = @model) ⇒ Boolean

Returns:

  • (Boolean)


537
# File 'lib/rfm/utilities/sax_parser.rb', line 537

def attach_attributes?(_model=@model); _model && _model['attach_attributes']; end

#attach_elements?(_model = @model) ⇒ Boolean

Returns:

  • (Boolean)


536
# File 'lib/rfm/utilities/sax_parser.rb', line 536

def attach_elements?(_model=@model); _model && _model['attach_elements']; end

#attach_new_element(name, new_object) ⇒ Object

def attach_new_object(base_object, new_object, name, base_model, new_model, type)

  label = label_or_tag(name, new_model)

  # Was this, which works fine, but not as efficient:
  # prefs = [attachment_prefs(base_model, new_model, type)].flatten(1)[0]
  prefs = if type=='attribute'
    [attachment_prefs(base_model, new_model, type)].flatten(1)[0]
  else
    @element_attachment_prefs
  end

  shared_var_name = shared_variable_name(prefs)
  (prefs = "shared") if shared_var_name

  # Use local create_accessors prefs first, then more general ones.
  create_accessors = accessor?(new_model)
  (create_accessors = create_accessors?(base_model)) unless create_accessors && create_accessors.any?

  # # This is NEW!
  # translator = new_model['translator']
  # if translator
  #   new_object = base_object.send translator, name, new_object
  # end

  #puts ["\nATTACH_NEW_OBJECT 1", "type: #{type}", "label: #{label}", "base_object: #{base_object.class}", "new_object: #{new_object.class}", "delimiter: #{delimiter?(new_model)}", "prefs: #{prefs}", "shared_var_name: #{shared_var_name}", "create_accessors: #{create_accessors}"]
  base_object._attach_object!(new_object, label, delimiter?(new_model), prefs, type, :default_class=>DEFAULT_CLASS, :shared_variable_name=>shared_var_name, :create_accessors=>create_accessors)
  #puts ["\nATTACH_NEW_OBJECT 2: #{base_object.class} with ", label, delimiter?(new_model), prefs, type, :shared_variable_name=>shared_var_name, :create_accessors=>create_accessors]
  # if type == 'attribute'
  #   puts ["\nATTACH_ATTR", "name: #{name}", "label: #{label}", "new_object: #{new_object.class rescue ''}", "base_object: #{base_object.class rescue ''}", "base_model: #{base_model['name'] rescue ''}", "new_model: #{new_model['name'] rescue ''}", "prefs: #{prefs}"]
  # end
end


477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
# File 'lib/rfm/utilities/sax_parser.rb', line 477

def attach_new_element(name, new_object)   #old params (base_object, new_object, name, base_model, new_model, type)
  label = label_or_tag(name, @local_model)

  # Was this, which works fine, but not as efficient:
  # prefs = [attachment_prefs(base_model, new_model, type)].flatten(1)[0]
  prefs = @element_attachment_prefs

  shared_var_name = shared_variable_name(prefs)
  (prefs = "shared") if shared_var_name

  # Use local create_accessors prefs first, then more general ones.
  create_accessors = accessor?(@local_model) || create_accessors?(@parent.model)
  #(create_accessors = create_accessors?(@parent.model)) unless create_accessors && create_accessors.any?

  # # This is NEW!
  # translator = new_model['translator']
  # if translator
  #   new_object = base_object.send translator, name, new_object
  # end


  #puts ["\nATTACH_NEW_ELEMENT 1", "new_object: #{new_object}", "parent_object: #{@parent.object}", "label: #{label}", "delimiter: #{delimiter?(@local_model)}", "prefs: #{prefs}", "shared_var_name: #{shared_var_name}", "create_accessors: #{create_accessors}"]
  @parent.object._attach_object!(new_object, label, delimiter?(@local_model), prefs, 'element', :default_class=>DEFAULT_CLASS, :shared_variable_name=>shared_var_name, :create_accessors=>create_accessors)
  # if type == 'attribute'
  #   puts ["\nATTACH_ATTR", "name: #{name}", "label: #{label}", "new_object: #{new_object.class rescue ''}", "base_object: #{base_object.class rescue ''}", "base_model: #{base_model['name'] rescue ''}", "new_model: #{new_model['name'] rescue ''}", "prefs: #{prefs}"]
  # end
end

#attachment_prefs(base_model, new_model, type) ⇒ Object



505
506
507
508
509
510
# File 'lib/rfm/utilities/sax_parser.rb', line 505

def attachment_prefs(base_model, new_model, type)
  case type
  when 'element'; attach?(new_model) || attach_elements?(base_model) #|| attach?(top.model) || attach_elements?(top.model)
  when 'attribute'; attach?(new_model) || attach_attributes?(base_model) #|| attach?(top.model) || attach_attributes?(top.model)
  end
end

#before_close?(_model = @model) ⇒ Boolean

Returns:

  • (Boolean)


532
# File 'lib/rfm/utilities/sax_parser.rb', line 532

def before_close?(_model=@model); _model && _model['before_close']; end

#clean_member(val) ⇒ Object



580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
# File 'lib/rfm/utilities/sax_parser.rb', line 580

def clean_member(val)
  if val.is_a?(Hash) || val.is_a?(Array); 
    if val && val.empty?
      nil
    elsif val && val.respond_to?(:values) && val.size == 1
      val.values[0]
    else
      val
    end
  else
    val
    #   # Probably shouldn't do this on instance-var values. ...Why not?
    #     if val.instance_variables.size < 1
    #       nil
    #     elsif val.instance_variables.size == 1
    #       val.instance_variable_get(val.instance_variables[0])
    #     else
    #       val
    #     end
  end
end

#clean_members(obj = @object) ⇒ Object



552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
# File 'lib/rfm/utilities/sax_parser.rb', line 552

def clean_members(obj=@object)
  #puts ["CURSOR.clean_members: #{object.class}", "tag: #{tag}", "model-name: #{model[:name]}"]
  #   cursor.object = clean_member(cursor.object)
  #   clean_members(ivg(shared_attribute_var, obj))
  if obj.is_a?(Hash)
    obj.dup.each do |k,v|
      obj[k] = clean_member(v)
      yield(v) if block_given?
    end
  elsif obj.is_a?(Array)
    obj.dup.each_with_index do |v,i|
      obj[i] = clean_member(v)
      yield(v) if block_given?
    end
  else  
    obj.instance_variables.each do |var|
      dat = obj.instance_variable_get(var)
      obj.instance_variable_set(var, clean_member(dat))
      yield(dat) if block_given?
    end
  end
  #   obj.instance_variables.each do |var|
  #     dat = obj.instance_variable_get(var)
  #     obj.instance_variable_set(var, clean_member(dat))
  #     yield(dat) if block_given?
  #   end
end

#compact?(_model = @model) ⇒ Boolean

Returns:

  • (Boolean)


534
# File 'lib/rfm/utilities/sax_parser.rb', line 534

def compact?(_model=@model); _model && _model['compact']; end

#create_accessors?(_model = @model) ⇒ Boolean

Returns:

  • (Boolean)


541
# File 'lib/rfm/utilities/sax_parser.rb', line 541

def create_accessors?(_model=@model); _model && _model['create_accessors'] && [_model['create_accessors']].flatten.compact; end

#delimiter?(_model = @model) ⇒ Boolean

Returns:

  • (Boolean)


538
# File 'lib/rfm/utilities/sax_parser.rb', line 538

def delimiter?(_model=@model); _model && _model['delimiter']; end

#depth?(_model = @model) ⇒ Boolean

Returns:

  • (Boolean)


531
# File 'lib/rfm/utilities/sax_parser.rb', line 531

def depth?(_model=@model); _model && _model['depth']; end

#each_before_close?(_model = @model) ⇒ Boolean

Returns:

  • (Boolean)


533
# File 'lib/rfm/utilities/sax_parser.rb', line 533

def each_before_close?(_model=@model); _model && _model['each_before_close']; end

#element_handler?(_model = @model) ⇒ Boolean

Returns:

  • (Boolean)


543
# File 'lib/rfm/utilities/sax_parser.rb', line 543

def element_handler?(_model=@model); _model && _model['element_handler']; end

#get_callback(callback, caller_binding = binding, defaults = {}) ⇒ Object

Parse callback instructions, compile & send callback method ###

TODO: This is way too convoluted. Document it better, or refactor!!!

This method will send a method to an object, with parameters, and return a new object. Input (first param): string, symbol, or array of strings Returns: object Default options:

:object=>object
:method=>'a method name string or symbol'
:params=>"params string to be eval'd in context of cursor"

Usage:

callback: send a method (or eval string) to an object with parameters, consisting of...
  string: a string to be eval'd in context of current object.
  or symbol: method to be called on current object.
  or array: object, method, params.
    object: <object or string>
    method: <string or symbol>
    params: <string>

TODO-MAYBE: Change param order to (method, object, params),

might help confusion with param complexities.


342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
# File 'lib/rfm/utilities/sax_parser.rb', line 342

def get_callback(callback, caller_binding=binding, defaults={})
  input = callback.is_a?(Array) ? callback.dup : callback
  #puts "\nGET_CALLBACK tag: #{tag}, callback: #{callback}"
  params = case
           when input.is_a?(String) || input.is_a?(Symbol)
             [nil, input]
             # when input.is_a?(Symbol)
             #   [nil, input]
           when input.is_a?(Array)
             #puts ["\nCURSOR#get_callback is an array", input]
             case
             when input[0].is_a?(Symbol)
               [nil, input].flatten(1)
             when input[1].is_a?(String) && ( input.size > 2 || (remove_colon=(input[1][0,1]==":"); remove_colon) )
               code_or_method = input[1].dup
               code_or_method[0]='' if remove_colon
               code_or_method = code_or_method.to_sym
               output = [input[0], code_or_method, input[2..-1]].flatten(1)
               #puts ["\nCURSOR#get_callback converted input[1] to symbol", output]
               output
             else # when input is ['object', 'sym-or-str', 'param1',' param2', ...]
               input
             end
           else
             []
           end

  obj_raw = params.shift
  #puts ["\nOBJECT_RAW:","class: #{obj_raw.class}", "object: #{obj_raw}"]
  obj = if obj_raw.is_a?(String)
          eval(obj_raw.to_s, caller_binding)
        else
          obj_raw
        end
  if obj.nil? || obj == ''
    obj = defaults[:object] || @object
  end
  #puts ["\nOBJECT:","class: #{obj.class}", "object: #{obj}"]

  code = params.shift || defaults[:method]
  params.each_with_index do |str, i|
    if str.is_a?(String)
      params[i] = eval(str, caller_binding)
    end
  end
  params = defaults[:params] if params.size == 0
  #puts ["\nGET_CALLBACK tag: #{@tag}" ,"callback: #{callback}", "obj.class: #{obj.class}", "code: #{code}", "params-class #{params.class}"]
  case
  when (code.nil? || code=='')
    obj
  when (code.is_a?(Symbol) || params)
    #puts ["\nGET_CALLBACK sending symbol", obj.class, code] 
    obj.send(*[code, params].flatten(1).compact)
  when code.is_a?(String)
    #puts ["\nGET_CALLBACK evaling string", obj.class, code]
    obj.send :eval, code
    #eval(code, caller_binding)
  end          
end

#get_constant(klass) ⇒ Object

UTILITY #####



522
523
524
# File 'lib/rfm/utilities/sax_parser.rb', line 522

def get_constant(klass)
  self.class.get_constant(klass)
end

#initialize_with?(_model = @model) ⇒ Boolean

Returns:

  • (Boolean)


540
# File 'lib/rfm/utilities/sax_parser.rb', line 540

def initialize_with?(_model=@model); _model && _model['initialize_with']; end

#ivg(name, _object = @object) ⇒ Object

Methods for current _model



527
# File 'lib/rfm/utilities/sax_parser.rb', line 527

def ivg(name, _object=@object); _object.instance_variable_get "@#{name}"; end

#ivs(name, value, _object = @object) ⇒ Object



528
# File 'lib/rfm/utilities/sax_parser.rb', line 528

def ivs(name, value, _object=@object); _object.instance_variable_set "@#{name}", value; end

#label_or_tag(_tag = @tag, new_model = @local_model) ⇒ Object

This might be broken.



549
# File 'lib/rfm/utilities/sax_parser.rb', line 549

def label_or_tag(_tag=@tag, new_model=@local_model); as_name?(new_model) || _tag; end

#model_attributes?(which = nil, _model = @model) ⇒ Boolean

Returns:

  • (Boolean)


530
# File 'lib/rfm/utilities/sax_parser.rb', line 530

def model_attributes?(which=nil, _model=@model); _model && _model.has_key?('attributes') && ((_model['attributes'] && which) ? _model['attributes'].find{|a| a['name']==which} : _model['attributes']) ; end

#model_elements?(which = nil, _model = @model) ⇒ Boolean

Returns:

  • (Boolean)


529
# File 'lib/rfm/utilities/sax_parser.rb', line 529

def model_elements?(which=nil, _model=@model); _model && _model.has_key?('elements') && ((_model['elements'] && which) ? _model['elements'].find{|e| e['name']==which} : _model['elements']) ; end

#process_new_element(caller_binding = binding) ⇒ Object

Decides how to attach element & attributes associated with this cursor.



227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
# File 'lib/rfm/utilities/sax_parser.rb', line 227

def process_new_element(caller_binding=binding)
  #puts ["\nPROCESS_NEW_ELEMENT tag: #{@tag}", "@element_attachment_prefs: #{@element_attachment_prefs}", "@local_model: #{local_model}"]

  new_element = @new_element_callback ? get_callback(@new_element_callback, caller_binding) : nil

  case
    # when inital cursor, just set model & object.
  when @tag == '__TOP__';
    #puts "__TOP__"
    @model = @handler.template
    @object = @handler.initial_object

  when @element_attachment_prefs == 'none';
    #puts "__NONE__"
    @model = @parent.model #nil
    @object = @parent.object #nil

    if @initial_attributes && @initial_attributes.any? #&& @attribute_attachment_prefs != 'none'
      assign_attributes(@initial_attributes) #, @object, @model, @local_model) 
    end

  when @element_attachment_prefs == 'cursor';
    #puts "__CURSOR__"
    @model = @local_model
    @object = new_element || DEFAULT_CLASS.allocate

    if @initial_attributes && @initial_attributes.any? #&& @attribute_attachment_prefs != 'none'
      assign_attributes(@initial_attributes) #, @object, @model, @local_model) 
    end

  else
    #puts "__OTHER__"
    @model = @local_model
    @object = new_element || DEFAULT_CLASS.allocate

    if @initial_attributes && @initial_attributes.any? #&& @attribute_attachment_prefs != 'none'
      #puts "PROCESS_NEW_ELEMENT calling assign_attributes with ATTRIBUTES #{@initial_attributes}"
      assign_attributes(@initial_attributes) #, @object, @model, @local_model) 
    end

    # If @local_model has a delimiter, defer attach_new_element until later.
    #puts "PROCESS_NEW_ELEMENT delimiter of @local_model #{delimiter?(@local_model)}"
    if !delimiter?(@local_model) 
      #attach_new_object(@parent.object, @object, @tag, @parent.model, @local_model, 'element')
      #puts "PROCESS_NEW_ELEMENT calling attach_new_element with TAG #{@tag} and OBJECT #{@object}"
      attach_new_element(@tag, @object)
    end      
  end

  self
end

#receive_attribute(name, value) ⇒ Object

Receive a single attribute (any named attribute or text)



211
212
213
214
215
216
217
# File 'lib/rfm/utilities/sax_parser.rb', line 211

def receive_attribute(name, value)
  #puts ["\nRECEIVE_ATTR '#{name}'", "value: #{value}", "tag: #{@tag}", "object: #{object.class}", "model: #{model['name']}"]
  new_att = {name=>value}    #.new.tap{|att| att[name]=value}
  assign_attributes(new_att) #, @object, @model, @local_model)
rescue
  Rfm.log.warn "Error: could not assign attribute '#{name.to_s}' to element '#{self.tag.to_s}': #{$!}"
end

#receive_end_element(_tag) ⇒ Object



280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
# File 'lib/rfm/utilities/sax_parser.rb', line 280

def receive_end_element(_tag)
  #puts ["\nRECEIVE_END_ELEMENT '#{_tag}'", "tag: #{@tag}", "object: #{@object.class}", "model: #{@model['name']}", "local_model: #{@local_model['name']}"]
  #puts ["\nEND_ELEMENT_OBJECT", object.to_yaml]
  begin

    if _tag == @tag && (@model == @local_model)
      # Data cleaup
      compactor_settings = compact? || compact?(top.model)
      #(compactor_settings = compact?(top.model)) unless compactor_settings # prefer local settings, or use top settings.
      (clean_members {|v| clean_members(v){|w| clean_members(w)}}) if compactor_settings
    end

    if (delimiter = delimiter?(@local_model); delimiter && !['none','cursor'].include?(@element_attachment_prefs.to_s))
      #attach_new_object(@parent.object, @object, @tag, @parent.model, @local_model, 'element')
      #puts "RECEIVE_END_ELEMENT attaching new element TAG (#{@tag}) OBJECT (#{@object.class}) #{@object.to_yaml} WITH LOCAL MODEL #{@local_model.to_yaml} TO PARENT (#{@parent.object.class}) #{@parent.object.to_yaml} PARENT MODEL #{@parent.model.to_yaml}"
      attach_new_element(@tag, @object)
    end      

    if _tag == @tag #&& (@model == @local_model)
      # End-element callbacks.
      #run_callback(_tag, self)
      callback = before_close?(@local_model)
      get_callback(callback, binding) if callback
    end

    if _tag == @tag
      # return true only if matching tags
      return true
    end

    # # return true only if matching tags
    # if _tag == @tag
    #   return true
    # end

    return
    #           rescue
    #            Rfm.log.debug "Error: end_element tag '#{_tag}' failed: #{$!}"
  end
end

#receive_start_element(_tag, _attributes) ⇒ Object



219
220
221
222
223
224
# File 'lib/rfm/utilities/sax_parser.rb', line 219

def receive_start_element(_tag, _attributes)
  #puts ["\nRECEIVE_START '#{_tag}'", "current_object: #{@object.class}", "current_model: #{@model['name']}", "attributes #{_attributes}"]
  new_cursor = Cursor.new(_tag, @handler, self, _attributes) #, binding)
  new_cursor.process_new_element(binding)
  new_cursor
end

#shared_variable_name(prefs) ⇒ Object



512
513
514
515
516
517
# File 'lib/rfm/utilities/sax_parser.rb', line 512

def shared_variable_name(prefs)
  rslt = nil
  if prefs.to_s[0,1] == "_"
    rslt = prefs.to_s[1..-1] #prefs.gsub(/^_/, '')
  end
end