xmlconv2 2.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 (108) hide show
  1. data/History.txt +6 -0
  2. data/LICENCE.txt +339 -0
  3. data/Manifest.txt +107 -0
  4. data/README.txt +25 -0
  5. data/Rakefile +28 -0
  6. data/bin/admin +65 -0
  7. data/bin/xmlconvd +19 -0
  8. data/data/grammar/i2.grammar +73 -0
  9. data/src/conversion/bdd_geh.rb +281 -0
  10. data/src/conversion/bdd_i2.rb +102 -0
  11. data/src/conversion/bdd_xml.rb +242 -0
  12. data/src/conversion/geh_bdd.rb +165 -0
  13. data/src/conversion/i2_bdd.rb +271 -0
  14. data/src/conversion/xml_bdd.rb +125 -0
  15. data/src/custom/lookandfeel.rb +47 -0
  16. data/src/i2/address.rb +33 -0
  17. data/src/i2/date.rb +37 -0
  18. data/src/i2/document.rb +26 -0
  19. data/src/i2/header.rb +24 -0
  20. data/src/i2/order.rb +44 -0
  21. data/src/i2/parser.rb +25 -0
  22. data/src/i2/position.rb +37 -0
  23. data/src/i2/record.rb +11 -0
  24. data/src/model/address.rb +20 -0
  25. data/src/model/agreement.rb +10 -0
  26. data/src/model/bdd.rb +26 -0
  27. data/src/model/bsr.rb +16 -0
  28. data/src/model/delivery.rb +15 -0
  29. data/src/model/delivery_item.rb +18 -0
  30. data/src/model/freetext_container.rb +26 -0
  31. data/src/model/id_container.rb +15 -0
  32. data/src/model/invoice.rb +18 -0
  33. data/src/model/invoice_item.rb +11 -0
  34. data/src/model/item.rb +19 -0
  35. data/src/model/item_container.rb +15 -0
  36. data/src/model/name.rb +27 -0
  37. data/src/model/part_info.rb +10 -0
  38. data/src/model/part_info_container.rb +15 -0
  39. data/src/model/party.rb +23 -0
  40. data/src/model/party_container.rb +20 -0
  41. data/src/model/price.rb +10 -0
  42. data/src/model/price_container.rb +18 -0
  43. data/src/model/transaction.rb +28 -0
  44. data/src/state/global.rb +28 -0
  45. data/src/state/global_predefine.rb +11 -0
  46. data/src/state/login.rb +38 -0
  47. data/src/state/transaction.rb +13 -0
  48. data/src/state/transactions.rb +130 -0
  49. data/src/util/application.rb +143 -0
  50. data/src/util/destination.rb +130 -0
  51. data/src/util/invoicer.rb +72 -0
  52. data/src/util/known_user.rb +16 -0
  53. data/src/util/polling_manager.rb +78 -0
  54. data/src/util/session.rb +23 -0
  55. data/src/util/transaction.rb +105 -0
  56. data/src/util/validator.rb +20 -0
  57. data/src/view/foot.rb +27 -0
  58. data/src/view/head.rb +13 -0
  59. data/src/view/login.rb +36 -0
  60. data/src/view/navigation.rb +30 -0
  61. data/src/view/navigationlink.rb +21 -0
  62. data/src/view/pager.rb +73 -0
  63. data/src/view/preformatted.rb +39 -0
  64. data/src/view/template.rb +17 -0
  65. data/src/view/transaction.rb +42 -0
  66. data/src/view/transactions.rb +90 -0
  67. data/test/mock.rb +149 -0
  68. data/test/suite.rb +16 -0
  69. data/test/test_conversion/bdd_geh.rb +533 -0
  70. data/test/test_conversion/bdd_i2.rb +314 -0
  71. data/test/test_conversion/bdd_xml.rb +556 -0
  72. data/test/test_conversion/geh_bdd.rb +372 -0
  73. data/test/test_conversion/i2_bdd.rb +804 -0
  74. data/test/test_conversion/xml_bdd.rb +203 -0
  75. data/test/test_i2/address.rb +88 -0
  76. data/test/test_i2/date.rb +49 -0
  77. data/test/test_i2/document.rb +62 -0
  78. data/test/test_i2/header.rb +39 -0
  79. data/test/test_i2/order.rb +94 -0
  80. data/test/test_i2/parser.rb +309 -0
  81. data/test/test_i2/position.rb +65 -0
  82. data/test/test_integration/geh_i2.rb +312 -0
  83. data/test/test_integration/i2_geh.rb +449 -0
  84. data/test/test_integration/i2_xml.rb +162 -0
  85. data/test/test_integration/xml_i2.rb +254 -0
  86. data/test/test_model/address.rb +35 -0
  87. data/test/test_model/agreement.rb +22 -0
  88. data/test/test_model/bdd.rb +55 -0
  89. data/test/test_model/bsr.rb +38 -0
  90. data/test/test_model/delivery.rb +79 -0
  91. data/test/test_model/delivery_item.rb +52 -0
  92. data/test/test_model/freetext_container.rb +45 -0
  93. data/test/test_model/invoice.rb +65 -0
  94. data/test/test_model/invoice_item.rb +41 -0
  95. data/test/test_model/name.rb +57 -0
  96. data/test/test_model/part_info.rb +24 -0
  97. data/test/test_model/party.rb +96 -0
  98. data/test/test_model/price.rb +24 -0
  99. data/test/test_util/application.rb +168 -0
  100. data/test/test_util/destination.rb +197 -0
  101. data/test/test_util/invoicer.rb +36 -0
  102. data/test/test_util/polling_manager.rb +111 -0
  103. data/test/test_util/transaction.rb +129 -0
  104. data/user-stories/UserStories_XmlConv2.txt +381 -0
  105. data/user-stories/doku/ABB.incoming.HTTP.invoice.xml +315 -0
  106. data/user-stories/doku/ABB.received.xml +259 -0
  107. data/user-stories/doku/BO_OrderProcessing.sxw +0 -0
  108. metadata +195 -0
data/src/model/name.rb ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ # Name -- xmlconv2 -- 01.06.2004 -- hwyss@ywesee.com
3
+
4
+ module XmlConv
5
+ module Model
6
+ class Name
7
+ attr_reader :first, :last, :text
8
+ def first=(arg)
9
+ set_attr('@first', arg && arg.strip)
10
+ end
11
+ def last=(arg)
12
+ set_attr('@last', arg && arg.strip)
13
+ end
14
+ def text=(arg)
15
+ set_attr('@text', arg && arg.strip)
16
+ end
17
+ def to_s
18
+ [@first, @text, @last].compact.join(' ')
19
+ end
20
+ private
21
+ def set_attr(attr, arg)
22
+ str = arg.to_s
23
+ instance_variable_set(attr, str.empty? ? nil : str)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # Model::PartInfo -- xmlconv2 -- 23.06.2004 -- hwyss@ywesee.com
3
+
4
+ module XmlConv
5
+ module Model
6
+ class PartInfo
7
+ attr_accessor :dimension, :value
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # Model::PartInfoContainer -- xmlconv2 -- 23.06.2004 -- hwyss@ywesee.com
3
+
4
+ module XmlConv
5
+ module Model
6
+ module PartInfoContainer
7
+ def add_part_info(info)
8
+ self.part_infos.push(info)
9
+ end
10
+ def part_infos
11
+ @part_infos ||= []
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+ # Party -- xmlconv2 -- 01.06.2004 -- hwyss@ywesee.com
3
+
4
+ require 'model/party_container'
5
+ require 'model/id_container'
6
+
7
+ module XmlConv
8
+ module Model
9
+ class Party
10
+ attr_accessor :role, :address, :name
11
+ include PartyContainer
12
+ include IdContainer
13
+ def party_id
14
+ sorted = self.ids.sort
15
+ domain, value = sorted.first
16
+ value
17
+ end
18
+ def acc_id
19
+ self.ids['ACC']
20
+ end
21
+ end
22
+ end
23
+ end
@@ -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
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 'model/freetext_container'
5
+ require 'model/id_container'
6
+ require 'model/item_container'
7
+ require 'model/party_container'
8
+ require '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, :free_text, :status, :status_date
19
+ attr_accessor :customer, :seller
20
+ def customer_id
21
+ self.ids['Customer']
22
+ end
23
+ def reference_id
24
+ self.ids['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 'state/login'
5
+ require 'state/transaction'
6
+ require '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,38 @@
1
+ #!/usr/bin/env ruby
2
+ # State::Login -- xmlconv2 -- 09.06.2004 -- hwyss@ywesee.com
3
+
4
+ require 'sbsm/state'
5
+ require 'view/login'
6
+ require '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
+ def login
30
+ if(@session.login)
31
+ Transaction.new(@session, @model)
32
+ else
33
+ self
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+ # State::Transaction -- xmlconv2 -- 09.06.2004 -- hwyss@ywesee.com
3
+
4
+ require 'state/global_predefine'
5
+ require '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 'state/global_predefine'
5
+ require '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,143 @@
1
+ #!/usr/bin/env ruby
2
+ # XmlConv::Application -- xmlconv2 -- 07.06.2004 -- hwyss@ywesee.com
3
+
4
+ require 'sbsm/drbserver'
5
+ require 'state/global'
6
+ require 'util/invoicer'
7
+ require 'util/polling_manager'
8
+ require 'util/session'
9
+ require 'util/transaction'
10
+ require 'util/validator'
11
+ require 'thread'
12
+ require 'odba'
13
+
14
+ VERSION = '2.0.0'
15
+
16
+ module XmlConv
17
+ module Util
18
+ class Application
19
+ attr_reader :transactions, :failed_transactions
20
+ include ODBA::Persistable
21
+ ODBA_EXCLUDE_VARS = ['@next_transaction_id', '@id_mutex']
22
+ def initialize
23
+ @transactions = []
24
+ @failed_transactions = []
25
+ end
26
+ def init
27
+ @id_mutex = Mutex.new
28
+ end
29
+ def execute(transaction)
30
+ _execute(transaction)
31
+ transaction.notify
32
+ rescue Exception => error
33
+ ## survive notification failure
34
+ end
35
+ def _execute(transaction)
36
+ transaction.transaction_id = next_transaction_id
37
+ transaction.execute
38
+ rescue Exception => error
39
+ transaction.error = error
40
+ ensure
41
+ @transactions.push(transaction)
42
+ ODBA.transaction {
43
+ @transactions.odba_store
44
+ }
45
+ end
46
+ def next_transaction_id
47
+ @id_mutex.synchronize {
48
+ @next_transaction_id ||= @transactions.collect { |transaction|
49
+ transaction.transaction_id.to_i
50
+ }.max.to_i
51
+ @next_transaction_id += 1
52
+ }
53
+ end
54
+ def transaction(transaction_id)
55
+ transaction_id = transaction_id.to_i
56
+ if((last_id = @transactions.last.transaction_id) \
57
+ && (last_id >= transaction_id))
58
+ start = (transaction_id - last_id - 1)
59
+ if(start + @transactions.size < 0)
60
+ start = 0
61
+ end
62
+ @transactions[start..-1].each { |trans|
63
+ return trans if(trans.transaction_id == transaction_id)
64
+ }
65
+ end
66
+ end
67
+ def send_invoice(time_range, date = Date.today)
68
+ transactions = @transactions.select { |trans|
69
+ time_range.include?(trans.commit_time)
70
+ }
71
+ Util::Invoicer.run(time_range, transactions, date)
72
+ end
73
+ end
74
+ end
75
+ end
76
+
77
+ class XmlConvApp < SBSM::DRbServer
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 = []
88
+ @dispatch_mutex = Mutex.new
89
+ if(self::class::POLLING_INTERVAL)
90
+ start_polling
91
+ end
92
+ start_dispatcher
93
+ start_invoicer
94
+ super(@system)
95
+ end
96
+ def dispatch(transaction)
97
+ @dispatch_mutex.synchronize {
98
+ @dispatch_queue.push(transaction)
99
+ }
100
+ @dispatcher_thread.wakeup
101
+ end
102
+ def start_dispatcher
103
+ @dispatcher_thread = Thread.new {
104
+ Thread.current.abort_on_exception = true
105
+ loop {
106
+ Thread.stop
107
+ while(!@dispatch_queue.empty?)
108
+ transaction = nil
109
+ @dispatch_mutex.synchronize {
110
+ transaction = @dispatch_queue.shift
111
+ }
112
+ @system.execute(transaction)
113
+ end
114
+ }
115
+ }
116
+ end
117
+ def start_invoicer
118
+ @invoicer_thread = Thread.new {
119
+ loop {
120
+ this_month = Date.today
121
+ next_month = this_month >> 1
122
+ strt = Time.local(this_month.year, this_month.month)
123
+ stop = Time.local(next_month.year, next_month.month)
124
+ sleep(stop - Time.now)
125
+ @system.send_invoice(strt...stop)
126
+ }
127
+ }
128
+ end
129
+ def start_polling
130
+ @polling_thread = Thread.new {
131
+ loop {
132
+ begin
133
+ #puts "polling"
134
+ XmlConv::Util::PollingManager.new(@system).poll_sources
135
+ #puts "done"
136
+ rescue Exception => exc
137
+ puts exc
138
+ end
139
+ sleep(self::class::POLLING_INTERVAL)
140
+ }
141
+ }
142
+ end
143
+ end