iab-ActiveRecordBDBXml 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/Marshaller.rb +224 -0
  2. metadata +3 -3
data/lib/Marshaller.rb ADDED
@@ -0,0 +1,224 @@
1
+ # Copyright (c) 2007-2008 Orangery Technology Limited
2
+ # You can redistribute it and/or modify it under the same terms as Ruby.
3
+ #
4
+ #add method to class that allows access to instantiate method
5
+ #as per rails 1.2
6
+ require 'activerecord'
7
+ require 'cgi'
8
+ class ActiveRecord::Base
9
+ def self.public_instantiate(myHash)
10
+ instantiate(myHash)
11
+ end
12
+ end
13
+
14
+ module Marshaller
15
+ def createXMLMessage(relation,params,nvp_format,&block)
16
+ @pqbNodes = Array.new
17
+ #dump the hash table rails builds for use in RTE message building test harness
18
+ #open('garyparams','w') { |f| YAML.dump(params, f) }
19
+ xml = buildXMLDocFromRailsParms(relation,params,nvp_format,Array.new,"",&block)
20
+ xml
21
+ end
22
+
23
+ def buildXMLDocFromRailsParms(nodeName,params,nvp_format,myagg,info,&block)
24
+ if (myagg.length == 0)
25
+ xml = createNode(nodeName.to_s,params,nvp_format,myagg,&block)
26
+ else
27
+ xml = createNode(myagg.to_s,params,nvp_format,myagg,&block)
28
+ end
29
+ xml << expandRelationships(:has_one,nodeName,params,nvp_format,myagg,info,&block)
30
+ xml << expandRelationships(:has_many,nodeName,params,nvp_format,myagg,info,&block)
31
+
32
+ xml = "" if !(xml.length > 0)
33
+ xml = "<#{nodeName}>#{xml}</#{nodeName}>" if (xml.length > 0 and !nvp_format)
34
+ xml
35
+ end
36
+
37
+ def createNode(table,params,nvp_format,myagg,&block)
38
+ xml=""
39
+ values = params[table]
40
+ if ( values != nil) then
41
+ fullName = expandedName(myagg)
42
+ if (values.is_a?(String))
43
+ if (nvp_format)
44
+ xml << block.call("#{fullName}Value",values.strip)
45
+ else
46
+ xml << block.call("Value",values.strip)
47
+ end
48
+ else
49
+ values.each_key do |key|
50
+ if (values[key].length > 0)
51
+ if (nvp_format)
52
+ xml << block.call("#{fullName}#{key}",values[key])
53
+ else
54
+ xml << block.call(key,values[key])
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ xml
61
+ end
62
+
63
+ def expandedName(myagg)
64
+ fullName = ""
65
+ myagg.each do |a|
66
+ fullName << "#{a.to_s.gsub(/[0-9]/,"")}_"
67
+ end
68
+ fullName
69
+ end
70
+
71
+ def expandRelationships(cardinality,nodeName,params,nvp_format,myagg,info,&block)
72
+ xml = ""
73
+ associations = {}
74
+ #strip out subscripts when accessing the generated data dictionary
75
+ if (myagg.length == 0)
76
+ entityName = nodeName.to_s.gsub(/[0-9]/,"")
77
+ else
78
+ entityName = myagg.to_s.gsub(/[0-9]/,"")
79
+ end
80
+ begin
81
+ associations = eval("#{entityName}.reflect_on_all_associations(:#{cardinality.id2name})")
82
+ rescue
83
+ raise "#{entityName} does not exist - please check the entity and coverage library definitions\nPerhaps you intended:#{info}"
84
+ end
85
+
86
+ associations.each do |ass|
87
+ klass = eval(ass.name.id2name)
88
+ if (myagg.last.to_s.include?("PremiumQuoteBreakdown") and (klass.nodeName == "GrossAmount"))
89
+ @pqbNodes.push("#{expandedName(myagg)}#{klass.nodeName}")
90
+ end
91
+ if (myagg.to_s == "PremiumQuoteBreakdown" and
92
+ (klass.nodeName == "Amount" or klass.nodeName == "IPTAmount" or klass.nodeName == "IPTPercent" ) )
93
+ @pqbNodes.push("#{expandedName(myagg)}#{klass.nodeName}")
94
+ end
95
+ myagg.push(klass.nodeName)
96
+ #puts "THE NODENAME:#{nodeN}\n AND THE REAL HASHNAME: #{ass.name.id2name}\n OUR DERIVED EQUIVALENT:#{myagg}"
97
+ if (cardinality.id2name == "has_one")
98
+ xml << buildXMLDocFromRailsParms(klass.nodeName,params,nvp_format,myagg,ass.name.id2name,&block)
99
+ else
100
+ #make this call as many times as there are instances of this has_many type
101
+ #make sure we add in the subscript each time into the myagg string first though
102
+ #use findDimension to look inside the rails dispatcher generated hash table of the http paramaters
103
+ #to determine the number of entries for a given multiply occuring complex type
104
+ findDimension(params,myagg).times do |i|
105
+ myagg.push(myagg.pop.to_s.gsub(/[0-9]/,"")+"#{i}")
106
+ xml << buildXMLDocFromRailsParms(klass.nodeName,params,nvp_format,myagg,ass.name.id2name,&block)
107
+ end
108
+ end
109
+ myagg.pop
110
+ end
111
+ xml
112
+ end
113
+
114
+ def findDimension(params,myagg)
115
+ low = 0
116
+ high = 50
117
+
118
+ while (high-low) > 1
119
+ middle = (low + high) / 2
120
+ str = "#{myagg}#{middle}"
121
+ if hashEntryExists(params,str)
122
+ low = middle
123
+ else
124
+ high = middle
125
+ end
126
+ end
127
+ #indexing starts at 0 so need to add 1 to calculated dimension
128
+ low = low + 1
129
+ #puts "DIMENSION for #{myagg} is #{low}"
130
+ low
131
+ end
132
+
133
+ def hashEntryExists(params,str)
134
+ params.each do |key, value|
135
+ if (key.match(str))
136
+ return true
137
+ end
138
+ end
139
+ return false
140
+ end
141
+
142
+ def prepareModels(product,xml)
143
+ #identify model parts for which we have data
144
+ #and instantiate classes for it
145
+ @pHashes = {}
146
+ doc = REXML::Document.new(xml)
147
+ xml_node_to_hash([],doc.root_node,product)
148
+ @pHashes
149
+ end
150
+
151
+ def xml_node_to_hash(path, node,product, parent_namespaces={}) #:nodoc
152
+ this_node = {}
153
+ namespaces = parent_namespaces.dup
154
+ node.attributes.each do |name, value|
155
+ case name
156
+ when 'xmlns'
157
+ (namespaces['@xmlns'] ||= {})['$'] = value
158
+ when /^xmlns:(.*)/
159
+ (namespaces['@xmlns'] ||= {})[$1] = value
160
+ else
161
+ this_node["@#{name}"] = value
162
+ end
163
+ end
164
+ node.each_child do |child|
165
+ case child.node_type
166
+ when :element
167
+ key, value = child.expanded_name, xml_node_to_hash(path.clone.push(child.expanded_name),child, product, namespaces)
168
+ when :text
169
+ if unescape(child.to_s).strip.length > 0
170
+ pn,en = "#{path.pop}","#{path}".gsub(product,'')
171
+ #puts "VALUES are:#{en},#{pn}=#{unescape(child.to_s).strip}"
172
+ collectValue(child,en,pn)
173
+ end
174
+ key, value = '$', unescape(child.to_s).strip
175
+ next if value.empty?
176
+ end
177
+ current = this_node[key]
178
+ case current
179
+ when Array
180
+ this_node[key] << value
181
+ when nil
182
+ this_node[key] = value
183
+ else
184
+ this_node[key] = [current.dup, value]
185
+ end
186
+ end
187
+ return this_node.merge(namespaces)
188
+ end
189
+
190
+ def collectValue(child,en,pn)
191
+ #there are issues with this approach to multi-occ returns
192
+ #this will get the client stuff running
193
+ #will now switch to using the cardinalities in the model
194
+ #by stepping up one level in the tree and reviewing all cardinalties of
195
+ #contained relations which will include the current subject
196
+ if (!@pHashes.has_key?(en))
197
+ @pHashes[en] = HashWithIndifferentAccess.new
198
+ @pHashes[en][pn] = unescape(child.to_s).strip
199
+ else
200
+ if @pHashes[en].is_a?(Array)
201
+ if (!@pHashes[en][@pHashes[en].length-1].has_key?(pn))
202
+ @pHashes[en][@pHashes[en].length-1][pn] = unescape(child.to_s).strip
203
+ else
204
+ h = HashWithIndifferentAccess.new
205
+ h[pn] = unescape(child.to_s).strip
206
+ @pHashes[en].push(h)
207
+ end
208
+ elsif @pHashes[en][pn]
209
+ existingHash = @pHashes[en]
210
+ @pHashes[en] = Array.new
211
+ @pHashes[en].push(existingHash)
212
+ h = HashWithIndifferentAccess.new
213
+ h[pn] = unescape(child.to_s).strip
214
+ @pHashes[en].push(h)
215
+ else
216
+ @pHashes[en][pn] = unescape(child.to_s).strip
217
+ end
218
+ end
219
+ end
220
+
221
+ def unescape(str)
222
+ return CGI.unescapeHTML(str)
223
+ end
224
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iab-ActiveRecordBDBXml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gary Mawdsley
@@ -40,8 +40,8 @@ extensions: []
40
40
 
41
41
  extra_rdoc_files: []
42
42
 
43
- files: []
44
-
43
+ files:
44
+ - lib/Marshaller.rb
45
45
  has_rdoc: true
46
46
  homepage: http://github.com/iab/ActiveRecordBDBXml
47
47
  post_install_message: