class PolyrexCreateObject

Attributes

obj[R]
parent_node[RW]

Public Class Methods

new(schema=nil, id: nil, order: 'ascending', record: nil, debug: false) click to toggle source
# File lib/polyrex-createobject.rb, line 16
def initialize(schema=nil, id: nil, order: 'ascending', record: nil,
               debug: false)

  @order = order.to_s
  @id = id

  if @debug then
    puts 'inside PolyrexCreateObject: record: ' + record.xml.inspect
    puts 'record.text' + record.text('summary/schema')
  end
  
  @parent_node = record ? record.element('records') : record
  schema = record.text('summary/schema')
  puts ': schema: ' + schema.inspect if @debug
  raise "missing schema" unless schema


  @schema = schema =~ /\// ? schema[/\/(.*)$/,1] : schema
  
  a = PolyrexSchema.new(schema).to_a
  puts 'a: ' + a.inspect if @debug
  
  a.each do |rec|

    @obj = attach_create_handlers(rec)
    puts '@obj: ' + @obj.inspect if @debug
    
    @obj.class_eval do 
      def record=(node)
        @parent_node = node
      end
    end

    self.instance_eval %Q( def #{@obj.name.downcase}(h={}, id=@id, &blk)

      local_schema = @schema

      if local_schema[0] == '{' then
        fields = @schema[/#{obj.name.downcase}\\[([^\\]]+)/,1].split(/\\s*,\\s*/)
        local_schema = "%s[%s]%s" % ['#{@obj.name.downcase}', fields.join(','), 
                                                local_schema[/\\/.*$/].to_s]            
      end

      new_parent = create_node(@parent_node, local_schema, h, id)
      
      if block_given? then
        yield(PolyrexCreateObject.new(id: id, record: new_parent))
      else
        self
      end
    end
    )
  end
end

Public Instance Methods

id() click to toggle source
# File lib/polyrex-createobject.rb, line 72
def id() @id end
id=(s) click to toggle source
# File lib/polyrex-createobject.rb, line 71
def id=(s)  @id = s; self end
record=(node) click to toggle source
# File lib/polyrex-createobject.rb, line 44
def record=(node)
  @parent_node = node
end

Private Instance Methods

attach_create_handlers(a) click to toggle source
# File lib/polyrex-createobject.rb, line 80
def attach_create_handlers(a)

  #return if PolyrexCreateObject
  class_name = "root".capitalize
  parent_klass = if ObjectSpace.each_object(Class)\
                                    .to_a.map(&:name).include? 'Root' then
    Root
  else
    parent_klass = Object.const_set(class_name,Class.new)
  end
  result = scan parent_klass, a
end
create_node(parent_node, child_schema, params={}, id=nil) click to toggle source
# File lib/polyrex-createobject.rb, line 93
def create_node(parent_node, child_schema, params={}, id=nil)

  record = PolyrexSchema.new(child_schema).to_doc
  record.root.xpath('records/*').each(&:delete)

  if id then
    @id.succ!
  else
    if @id.to_i.to_s == @id.to_s then
      @id.succ!
    else
      @id = @parent_node.element('count(//@id)').to_i + 2
    end
  end

  record.root.add_attribute({'id' => @id.to_s.clone})

  if params.length > 0 then
    a = child_schema[/[^\[]+(?=\])/].split(',')

    summary = record.root.element('summary')
    a.each do |field_name|  
      field = summary.element(field_name.strip)
      field.text = params[field_name.strip.to_sym]
    end
  end

  method_name = @order == 'ascending' ? :add : :prepend
  parent_node.method(method_name).call record.root

end
scan(parent, list) { |obj| ... } click to toggle source
# File lib/polyrex-createobject.rb, line 125
def scan(parent, list)

  cname = list.shift
  args = list

  r = []

  fields = []

  fields << args.shift while args.first.is_a? Symbol

  class_name = cname.capitalize

  klass = if ObjectSpace.each_object(Class)\
                            .to_a.map(&:name).include? class_name.to_s then
    Object.const_get class_name
  else
    Object.const_set(class_name,Class.new)
  end

  parent.class_eval do

    define_method :create_node do |parent_node, child_schema, 
                                                          params={}, id=nil|
      
      record = PolyrexSchema.new(child_schema).to_doc
      record.root.xpath('records/*').each(&:delete)
   
      if id then
        @id.succ!
      else
        if @id.to_i.to_s == @id.to_s then
          @id.succ!
        else
          @id = @parent_node.element('count(//@id)').to_i + 1
        end
      end

      record.root.add_attribute({'id' => @@id.to_s.clone})

      a = child_schema[/[^\[]+(?=\])/].split(',')

      summary = record.root.element('summary')

      a.each do |field_name|  
        field = summary.element(field_name.strip)
        field.text = params[field_name.strip.to_sym]
      end

      parent_node.add record.root


    end # end of define_method :create_node

    define_method cname do |h, id=nil, &blk|

      id ||= @id

      local_schema = @parent_node.parent.text('summary/schema')[/\/(.*$)/,1]

      if local_schema[0] == '{' then

        local_schema = "%s[%s]%s" % [cname, fields.join(','), 
                                                local_schema[/\/[^;]+/].to_s]            

      end
      new_parent = create_node(@parent_node, local_schema, h, id)\
                                                          .element('records')
      
      obj = klass.new 
      def obj.record=(node)
        @parent_node = node
      end


      obj.record = new_parent

      if blk then
        blk.call obj  
      else
        obj
      end
      self
    end
  end

  return klass unless args.any?

  next_rec = args.shift

  if next_rec.first.is_a? Array then

    remaining = scan(parent, *args) unless args.length < 1

    next_rec.each do |x| 

      child_klass = scan(klass,x)

      if remaining then

        child_klass.class_eval do

          define_method remaining.name.downcase.to_sym do |h, id=nil, &blk|

            id ||= @id
            local_schema = @parent_node.parent.text('summary/schema')[/\/(.*$)/,1]
            if local_schema[0] == '{' then

              local_schema = "%s[%s]%s" % [cname, fields.join(','), 
                                                      local_schema[/\/.*$/].to_s]            
            end
            new_parent = create_node(@parent_node, local_schema, 
                                               params, id).element('records')
            obj = remaining.new
            obj.record = new_parent
            yield obj

            self
          end
        end
      end
    end

  else

    remaining = scan(klass, *list) unless args.length < 1
    scan(klass, next_rec)
    scan(r, remaining) if remaining
  end

  return klass
end