# Martin Fowler's Reader Framework example from his "Language Workbenches"
# and "Generating Code for DSLs" papers.  
# H. Conrad Cunningham 
# Original: 4 October 2006 
# Revision: 9 October 2006

# DIRECT CONFIGURATION OF THE READER FRAMEWORK

require 'ReaderFramework'

# Method BuilderDirect#configure takes a ReaderFramework::Reader object
# and configures it with appropriate ReaderFramework::ReaderStrategy and
# ReaderFramework::FieldExtractor objects for the example given in the
# comments in the ReaderFramework module source and in Fowler's paper.

class BuilderDirect

  def configure(reader)
    reader.add_strategy(configure_service_call)
    reader.add_strategy(configure_usage)
  end

private

  def configure_service_call
    result = ReaderFramework::ReaderStrategy.new("SVCL", ServiceCall)
    result.add_field_extractor( 4, 18, "customer_name")
    result.add_field_extractor(19, 23, "customer_id")
    result.add_field_extractor(24, 27, "call_typ_code")
    result.add_field_extractor(28, 35, "date_of_call_string")
    result
  end

  def configure_usage
    result = ReaderFramework::ReaderStrategy.new("USGE", Usage)
    result.add_field_extractor( 4,  8, "customer_id")
    result.add_field_extractor( 9, 22, "customer_name")
    result.add_field_extractor(30, 30, "cycle")
    result.add_field_extractor(31, 36, "read_date")
    result
  end

end#BuilderDirect

# Classes used to hold the data read

class ServiceCall
end#ServiceCall

class Usage
end#Usage


# TESTING THE CONFIGURATION AND FRAMEWORK

class TestBuilderDirect

  def TestBuilderDirect.run
    puts "Testing BuilderDirect."
    rdr = ReaderFramework::Reader.new
    cfg = BuilderDirect.new
    cfg.configure(rdr)
    inp = File.new("fowlerdata.txt")
    res = rdr.process(inp)
    inp.close
    res.each {|o| puts o.inspect}
  end

end#TestBuilderDirect
