xmlconv 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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