xmlconv 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. data/.gemtest +0 -0
  2. data/History.txt +6 -0
  3. data/LICENSE +339 -0
  4. data/README.txt +29 -0
  5. data/Rakefile +37 -0
  6. data/bin/admin +68 -0
  7. data/bin/xmlconvd +38 -0
  8. data/data/grammar/i2.grammar +73 -0
  9. data/lib/xmlconv/config.rb +61 -0
  10. data/lib/xmlconv/custom/lookandfeel.rb +50 -0
  11. data/lib/xmlconv/i2/address.rb +35 -0
  12. data/lib/xmlconv/i2/date.rb +41 -0
  13. data/lib/xmlconv/i2/document.rb +27 -0
  14. data/lib/xmlconv/i2/header.rb +32 -0
  15. data/lib/xmlconv/i2/order.rb +61 -0
  16. data/lib/xmlconv/i2/parser.rb +23 -0
  17. data/lib/xmlconv/i2/position.rb +45 -0
  18. data/lib/xmlconv/i2/record.rb +11 -0
  19. data/lib/xmlconv/model/address.rb +20 -0
  20. data/lib/xmlconv/model/agreement.rb +10 -0
  21. data/lib/xmlconv/model/bdd.rb +37 -0
  22. data/lib/xmlconv/model/bsr.rb +16 -0
  23. data/lib/xmlconv/model/delivery.rb +15 -0
  24. data/lib/xmlconv/model/delivery_item.rb +24 -0
  25. data/lib/xmlconv/model/document.rb +25 -0
  26. data/lib/xmlconv/model/freetext_container.rb +26 -0
  27. data/lib/xmlconv/model/id_container.rb +22 -0
  28. data/lib/xmlconv/model/invoice.rb +18 -0
  29. data/lib/xmlconv/model/invoice_item.rb +11 -0
  30. data/lib/xmlconv/model/item.rb +19 -0
  31. data/lib/xmlconv/model/item_container.rb +15 -0
  32. data/lib/xmlconv/model/name.rb +27 -0
  33. data/lib/xmlconv/model/part_info.rb +10 -0
  34. data/lib/xmlconv/model/part_info_container.rb +15 -0
  35. data/lib/xmlconv/model/party.rb +20 -0
  36. data/lib/xmlconv/model/party_container.rb +20 -0
  37. data/lib/xmlconv/model/price.rb +10 -0
  38. data/lib/xmlconv/model/price_container.rb +18 -0
  39. data/lib/xmlconv/model/transaction.rb +28 -0
  40. data/lib/xmlconv/state/global.rb +28 -0
  41. data/lib/xmlconv/state/global_predefine.rb +11 -0
  42. data/lib/xmlconv/state/login.rb +39 -0
  43. data/lib/xmlconv/state/transaction.rb +13 -0
  44. data/lib/xmlconv/state/transactions.rb +130 -0
  45. data/lib/xmlconv/util/application.rb +142 -0
  46. data/lib/xmlconv/util/autoload.rb +35 -0
  47. data/lib/xmlconv/util/destination.rb +249 -0
  48. data/lib/xmlconv/util/invoicer.rb +71 -0
  49. data/lib/xmlconv/util/known_user.rb +16 -0
  50. data/lib/xmlconv/util/mail.rb +31 -0
  51. data/lib/xmlconv/util/polling_manager.rb +198 -0
  52. data/lib/xmlconv/util/session.rb +23 -0
  53. data/lib/xmlconv/util/transaction.rb +133 -0
  54. data/lib/xmlconv/util/validator.rb +20 -0
  55. data/lib/xmlconv/view/foot.rb +27 -0
  56. data/lib/xmlconv/view/head.rb +13 -0
  57. data/lib/xmlconv/view/login.rb +36 -0
  58. data/lib/xmlconv/view/navigation.rb +30 -0
  59. data/lib/xmlconv/view/navigationlink.rb +21 -0
  60. data/lib/xmlconv/view/pager.rb +73 -0
  61. data/lib/xmlconv/view/preformatted.rb +54 -0
  62. data/lib/xmlconv/view/template.rb +17 -0
  63. data/lib/xmlconv/view/transaction.rb +42 -0
  64. data/lib/xmlconv/view/transactions.rb +90 -0
  65. data/lib/xmlconv.rb +3 -0
  66. data/test/config.rb +12 -0
  67. data/test/mock.rb +149 -0
  68. data/test/suite.rb +16 -0
  69. data/test/test_i2/address.rb +88 -0
  70. data/test/test_i2/date.rb +50 -0
  71. data/test/test_i2/document.rb +62 -0
  72. data/test/test_i2/header.rb +39 -0
  73. data/test/test_i2/order.rb +94 -0
  74. data/test/test_i2/parser.rb +312 -0
  75. data/test/test_i2/position.rb +65 -0
  76. data/test/test_model/address.rb +35 -0
  77. data/test/test_model/agreement.rb +22 -0
  78. data/test/test_model/bdd.rb +55 -0
  79. data/test/test_model/bsr.rb +38 -0
  80. data/test/test_model/delivery.rb +79 -0
  81. data/test/test_model/delivery_item.rb +52 -0
  82. data/test/test_model/freetext_container.rb +45 -0
  83. data/test/test_model/invoice.rb +65 -0
  84. data/test/test_model/invoice_item.rb +41 -0
  85. data/test/test_model/name.rb +57 -0
  86. data/test/test_model/part_info.rb +24 -0
  87. data/test/test_model/party.rb +96 -0
  88. data/test/test_model/price.rb +24 -0
  89. data/test/test_util/application.rb +168 -0
  90. data/test/test_util/destination.rb +415 -0
  91. data/test/test_util/invoicer.rb +42 -0
  92. data/test/test_util/polling_manager.rb +299 -0
  93. data/test/test_util/transaction.rb +130 -0
  94. metadata +178 -0
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+ # PartyContainer -- xmlconv2 -- 01.06.2004 -- hwyss@ywesee.com
3
+
4
+ module XmlConv
5
+ module Model
6
+ module PartyContainer
7
+ attr_accessor :employee, :ship_to, :bill_to, :seller, :customer
8
+ def add_party(party)
9
+ if((role = party.role) && !role.empty?)
10
+ role = role.gsub(/\B[A-Z]/, '_\&')
11
+ instance_variable_set("@#{role.downcase}", party)
12
+ self.parties.push(party)
13
+ end
14
+ end
15
+ def parties
16
+ @parties ||= []
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # Model::Price -- xmlconv2 -- 21.06.2004 -- hwyss@ywesee.com
3
+
4
+ module XmlConv
5
+ module Model
6
+ class Price
7
+ attr_accessor :purpose, :amount
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+ # PriceContainer -- xmlconv2 -- 22.06.2004 -- hwyss@ywesee.com
3
+
4
+ module XmlConv
5
+ module Model
6
+ module PriceContainer
7
+ def add_price(price)
8
+ self.prices.push(price)
9
+ end
10
+ def get_price(purpose)
11
+ self.prices.find { |price| price.purpose == purpose }
12
+ end
13
+ def prices
14
+ @prices ||= []
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env ruby
2
+ # Model::Transaction -- xmlconv2 -- 23.06.2004 -- hwyss@ywesee.com
3
+
4
+ require 'xmlconv/model/freetext_container'
5
+ require 'xmlconv/model/id_container'
6
+ require 'xmlconv/model/item_container'
7
+ require 'xmlconv/model/party_container'
8
+ require 'xmlconv/model/price_container'
9
+
10
+ module XmlConv
11
+ module Model
12
+ class Transaction
13
+ include IdContainer
14
+ include ItemContainer
15
+ include FreeTextContainer
16
+ include PartyContainer
17
+ include PriceContainer
18
+ attr_accessor :agreement, :status, :status_date,
19
+ :transport_cost
20
+ def customer_id
21
+ self.id_table['customer']
22
+ end
23
+ def reference_id
24
+ self.id_table['acc']
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env ruby
2
+ # State::Global -- xmlconv2 -- 09.06.2004 -- hwyss@ywesee.com
3
+
4
+ require 'xmlconv/state/login'
5
+ require 'xmlconv/state/transaction'
6
+ require 'xmlconv/state/transactions'
7
+
8
+ module XmlConv
9
+ module State
10
+ class Global < SBSM::State
11
+ def logout
12
+ @session.logout
13
+ Login.new(@session, @model)
14
+ end
15
+ def transaction
16
+ if((id = @session.user_input(:transaction_id)) \
17
+ && (transaction = @session.transaction(id)))
18
+ Transaction.new(@session, transaction)
19
+ else
20
+ self
21
+ end
22
+ end
23
+ def home
24
+ Transactions.new(@session, @session.transactions)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+ # State::Global -- xmlconv2 -- 09.06.2004 -- hwyss@ywesee.com
3
+
4
+ require 'sbsm/state'
5
+
6
+ module XmlConv
7
+ module State
8
+ class Global < SBSM::State
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env ruby
2
+ # State::Login -- xmlconv2 -- 09.06.2004 -- hwyss@ywesee.com
3
+
4
+ require 'sbsm/state'
5
+ require 'xmlconv/view/login'
6
+ require 'xmlconv/state/transactions'
7
+
8
+ module XmlConv
9
+ module State
10
+ class Login < SBSM::State
11
+ VIEW = View::Login
12
+ def login
13
+ if(@session.login)
14
+ Transactions.new(@session, @session.transactions)
15
+ else
16
+ self
17
+ end
18
+ end
19
+ def transaction
20
+ if((id = @session.user_input(:transaction_id)) \
21
+ && (transaction = @session.transaction(id)))
22
+ TransactionLogin.new(@session, transaction)
23
+ else
24
+ self
25
+ end
26
+ end
27
+ end
28
+ class TransactionLogin < SBSM::State
29
+ VIEW = View::Login
30
+ def login
31
+ if(@session.login)
32
+ Transaction.new(@session, @model)
33
+ else
34
+ self
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+ # State::Transaction -- xmlconv2 -- 09.06.2004 -- hwyss@ywesee.com
3
+
4
+ require 'xmlconv/state/global_predefine'
5
+ require 'xmlconv/view/transaction'
6
+
7
+ module XmlConv
8
+ module State
9
+ class Transaction < Global
10
+ VIEW = View::Transaction
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,130 @@
1
+ #!/usr/bin/env ruby
2
+ # State::Transactions -- xmlconv2 -- 09.06.2004 -- hwyss@ywesee.com
3
+
4
+ require 'xmlconv/state/global_predefine'
5
+ require 'xmlconv/view/transactions'
6
+
7
+ module XmlConv
8
+ module State
9
+ class Transactions < Global
10
+ class PageFacade
11
+ attr_accessor :model, :pages
12
+ def initialize(int)
13
+ @int = int
14
+ end
15
+ def next
16
+ PageFacade.new(@int.next)
17
+ end
18
+ def pages
19
+ @pages[[[@int - (PAGER_SIZE / 2), total - PAGER_SIZE].min,
20
+ 0].max, PAGER_SIZE]
21
+ end
22
+ def previous
23
+ PageFacade.new(@int-1)
24
+ end
25
+ def total
26
+ @pages.size
27
+ end
28
+ def to_i
29
+ @int
30
+ end
31
+ def to_s
32
+ @int.next.to_s
33
+ end
34
+ end
35
+ DIRECT_EVENT = :home
36
+ PAGE_SIZE = 20
37
+ PAGER_SIZE = 10
38
+ REVERSE_MAP = {
39
+ :commit_time => true,
40
+ }
41
+ VIEW = View::Transactions
42
+ def init
43
+ @transactions = @model
44
+ @model = @transactions.reverse
45
+ setup_pages
46
+ @filter = Proc.new {
47
+ page
48
+ }
49
+ super
50
+ end
51
+ def compare_entries(a, b)
52
+ @sortby.each { |sortby|
53
+ aval, bval = nil
54
+ begin
55
+ aval = a.send(sortby)
56
+ bval = b.send(sortby)
57
+ rescue
58
+ next
59
+ end
60
+ res = if(aval.nil? && bval.nil?)
61
+ 0
62
+ elsif(aval.nil?)
63
+ 1
64
+ elsif(bval.nil?)
65
+ -1
66
+ else
67
+ aval <=> bval
68
+ end
69
+ return res unless(res == 0)
70
+ }
71
+ 0
72
+ end
73
+ def get_sortby!
74
+ @sortby ||= []
75
+ sortvalue = @session.user_input(:sortvalue)
76
+ if(sortvalue.is_a? String)
77
+ sortvalue = sortvalue.intern
78
+ end
79
+ if(@sortby.first == sortvalue)
80
+ @sort_reverse = !@sort_reverse
81
+ else
82
+ @sort_reverse = self.class::REVERSE_MAP[sortvalue]
83
+ end
84
+ @sortby.delete_if { |sortby|
85
+ sortby == sortvalue
86
+ }
87
+ @sortby.unshift(sortvalue)
88
+ end
89
+ def page
90
+ if(pge = @session.user_input(:page))
91
+ @page = @pages[pge.to_i]
92
+ else
93
+ @page ||= @pages.first
94
+ end
95
+ end
96
+ def page_size
97
+ self::class::PAGE_SIZE
98
+ end
99
+ def self
100
+ self
101
+ end
102
+ def setup_pages
103
+ @pages = []
104
+ @page = nil
105
+ pages = [(@model.size / PAGE_SIZE.to_f).ceil, 1].max
106
+ pages.times { |pnum|
107
+ page = PageFacade.new(pnum)
108
+ page.model = @model[pnum * PAGE_SIZE, PAGE_SIZE]
109
+ page.pages = @pages
110
+ @pages.push(page)
111
+ }
112
+ end
113
+ def size
114
+ @model.size
115
+ end
116
+ def sort
117
+ return self unless @model.is_a? Array
118
+ get_sortby!
119
+ @model = @transactions.dup
120
+ @model.sort! { |a, b| compare_entries(a, b) }
121
+ @model.reverse! if(@sort_reverse)
122
+ setup_pages
123
+ self
124
+ end
125
+ def transactions
126
+ self
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,142 @@
1
+ #!/usr/bin/env ruby
2
+ # XmlConv::Application -- xmlconv2 -- 07.06.2004 -- hwyss@ywesee.com
3
+
4
+ require 'sbsm/drbserver'
5
+ require 'xmlconv/state/global'
6
+ require 'xmlconv/util/invoicer'
7
+ require 'xmlconv/util/polling_manager'
8
+ require 'xmlconv/util/session'
9
+ require 'xmlconv/util/transaction'
10
+ require 'xmlconv/util/validator'
11
+ require 'thread'
12
+ require 'odba'
13
+
14
+ module XmlConv
15
+ module Util
16
+ class Application
17
+ attr_reader :transactions, :failed_transactions
18
+ include ODBA::Persistable
19
+ ODBA_EXCLUDE_VARS = ['@next_transaction_id', '@id_mutex']
20
+ def initialize
21
+ @transactions = []
22
+ @failed_transactions = []
23
+ end
24
+ def init
25
+ @id_mutex = Mutex.new
26
+ end
27
+ def execute(transaction)
28
+ _execute(transaction)
29
+ transaction.notify
30
+ rescue Exception => error
31
+ ## survive notification failure
32
+ end
33
+ def _execute(transaction)
34
+ transaction.transaction_id = next_transaction_id
35
+ transaction.execute
36
+ transaction.postprocess
37
+ rescue Exception => error
38
+ transaction.error = error
39
+ ensure
40
+ @transactions.push(transaction)
41
+ ODBA.transaction {
42
+ @transactions.odba_store
43
+ }
44
+ end
45
+ def next_transaction_id
46
+ @id_mutex.synchronize {
47
+ @next_transaction_id ||= @transactions.collect { |transaction|
48
+ transaction.transaction_id.to_i
49
+ }.max.to_i
50
+ @next_transaction_id += 1
51
+ }
52
+ end
53
+ def transaction(transaction_id)
54
+ transaction_id = transaction_id.to_i
55
+ if((last_id = @transactions.last.transaction_id) \
56
+ && (last_id >= transaction_id))
57
+ start = (transaction_id - last_id - 1)
58
+ if(start + @transactions.size < 0)
59
+ start = 0
60
+ end
61
+ @transactions[start..-1].each { |trans|
62
+ return trans if(trans.transaction_id == transaction_id)
63
+ }
64
+ end
65
+ end
66
+ def send_invoice(time_range, date = Date.today)
67
+ transactions = @transactions.select { |trans|
68
+ time_range.include?(trans.commit_time)
69
+ }
70
+ Util::Invoicer.run(time_range, transactions, date)
71
+ end
72
+ end
73
+ end
74
+ end
75
+
76
+ class XmlConvApp < SBSM::DRbServer
77
+ ENABLE_ADMIN = true
78
+ SESSION = XmlConv::Util::Session
79
+ VALIDATOR = XmlConv::Util::Validator
80
+ POLLING_INTERVAL = 60 #* 15
81
+ attr_reader :polling_thread, :dispatch_queue, :dispatcher_thread
82
+ def initialize
83
+ @system = ODBA.cache.fetch_named('XmlConv', self) {
84
+ XmlConv::Util::Application.new
85
+ }
86
+ @system.init
87
+ @dispatch_queue = Queue.new
88
+ if(self::class::POLLING_INTERVAL)
89
+ start_polling
90
+ end
91
+ start_dispatcher
92
+ start_invoicer if XmlConv::CONFIG.run_invoicer
93
+ super(@system)
94
+ end
95
+ def dispatch(transaction)
96
+ @dispatch_queue.push(transaction)
97
+ end
98
+ def execute_with_response(transaction)
99
+ begin
100
+ @system.execute(transaction)
101
+ rescue Exception => e
102
+ puts "rescued #{e.class}"
103
+ end
104
+ transaction.response.to_s
105
+ end
106
+ def start_dispatcher
107
+ @dispatcher_thread = Thread.new {
108
+ Thread.current.abort_on_exception = true
109
+ loop {
110
+ @system.execute(@dispatch_queue.pop)
111
+ }
112
+ }
113
+ end
114
+ def start_invoicer
115
+ @invoicer_thread = Thread.new {
116
+ Thread.current.abort_on_exception = true
117
+ loop {
118
+ this_month = Date.today
119
+ next_month = this_month >> 1
120
+ strt = Time.local(this_month.year, this_month.month)
121
+ stop = Time.local(next_month.year, next_month.month)
122
+ sleep(stop - Time.now)
123
+ @system.send_invoice(strt...stop)
124
+ }
125
+ }
126
+ end
127
+ def start_polling
128
+ @polling_thread = Thread.new {
129
+ Thread.current.abort_on_exception = true
130
+ loop {
131
+ begin
132
+ XmlConv::Util::PollingManager.new(@system).poll_sources
133
+ rescue Exception => exc
134
+ XmlConv::LOGGER.error(XmlConv::CONFIG.program_name) {
135
+ [exc.class, exc.message].concat(exc.backtrace).join("\n")
136
+ }
137
+ end
138
+ sleep(self::class::POLLING_INTERVAL)
139
+ }
140
+ }
141
+ end
142
+ end
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env ruby
2
+ # Util#autoload -- xmlconv2 -- 28.08.2006 -- hwyss@ywesee.com
3
+
4
+ module XmlConv
5
+ module Util
6
+ def Util.autoload(dir, type)
7
+ config = XmlConv::CONFIG
8
+ logger = XmlConv::LOGGER
9
+ dir = File.expand_path(dir)
10
+ prefix = File.basename(dir)
11
+ search_path = File.dirname(dir)
12
+ $:.push(search_path) unless $:.include?(search_path)
13
+ logger.debug(config.program_name) {
14
+ "checking directory '#{dir}' for #{type}s"
15
+ }
16
+ Dir.glob(File.join(dir, '*')) { |entry|
17
+ if(/\.(rb|so)$/.match(entry))
18
+ keyword = File.basename(entry)
19
+ keyword.slice!(/#{File.extname(keyword)}$/)
20
+ rpath = File.join(prefix, keyword)
21
+ logger.debug(config.program_name) {
22
+ "loading #{type}: '#{rpath}' (#{File.basename(entry)})"
23
+ }
24
+ begin
25
+ require rpath #File.basename(keyword)
26
+ rescue
27
+ logger.warn(config.program_name) {
28
+ "loading #{type} '#{rpath}' failed!"
29
+ }
30
+ end
31
+ end
32
+ }
33
+ end
34
+ end
35
+ end