xmlconv2 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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