root/tags/0.2/src/springy/context/serialization.rb

Revision 6998 (checked in by jan, 1 year ago)

springy 0.2

Line 
1 module Springy
2
3     SCHEMAS = {
4        "http://www.springframework.org/schema/beans" => "http://www.springframework.org/schema/beans/spring-beans-2.0.xsd",
5        "http://www.springframework.org/schema/util"  => "http://www.springframework.org/schema/util/spring-util-2.0.xsd"
6     }
7
8     include_class 'springy.context.AbstractSerializableManagedList'
9     include_class 'springy.context.AbstractSerializableManagedMap'
10     include_class 'springy.context.AbstractSerializableRuntimeBeanReference'
11     include_class 'springy.context.AbstractSerializableRootBeanDefinition'
12     include_class 'springy.context.AbstractSerializablePropertyValue'
13     include_class 'com.sun.org.apache.xerces.internal.dom.DocumentImpl'
14
15     module ValueSerializable
16         def serialize_xml(doc)
17             doc.tag('value') { self.to_s }
18         end
19     end
20
21     [ String, Fixnum, TrueClass, FalseClass ].each {|c| c.send(:include, ValueSerializable) }
22
23     # add some syntatic sugar to DocumentImpl in order to make it usable
24     # (based on the ruby xml builder)
25     JavaUtilities.extend_proxy('com.sun.org.apache.xerces.internal.dom.DocumentImpl') {
26         def tag(sym, *args, &block)
27             text = nil
28             attrs = nil
29             sym = "#{sym}:#{args.shift}" if args.first.kind_of?(Symbol)
30             args.each do |arg|
31                 case arg
32                 when Hash
33                   attrs ||= {}
34                   attrs.merge!(arg)
35                 else
36                   text ||= ''
37                   text << arg.to_s
38                 end
39             end
40
41             tag = self.create_element(sym.to_s)
42             attrs.each {|name,value| tag.set_attribute(name, value)} if attrs
43             tag = last_element.append_child(tag)
44
45             if block
46                 begin
47                     push(tag)
48                     val = block.call
49                     set_text(val) if val.kind_of?(String)
50                 ensure
51                     pop
52                 end
53             end
54         end
55
56         def comment(data)
57             last_element.append_child(self.create_comment(data))
58         end
59
60         def set_text(val)
61             last_element.set_text_content(val.to_s)
62         end
63
64         def serialize(out=java.lang.System.err)
65             include_class('com.sun.org.apache.xml.internal.serialize.XMLSerializer')
66             serializer = XMLSerializer.new(java.io.PrintWriter.new(out), output_format)
67             serializer.serialize(self)
68         end
69
70         def serialize_to_s
71             bos = java.io.ByteArrayOutputStream.new
72             serialize(bos)
73             bos.to_string
74         end
75
76         def output_format
77             include_class('com.sun.org.apache.xml.internal.serialize.OutputFormat')
78             of = OutputFormat.new
79             of.set_indent(4)
80             of.set_encoding('UTF-8')
81             of.set_line_width(120)
82             of
83         end
84
85         def validate!
86             factory = javax.xml.validation.SchemaFactory.newInstance('http://www.w3.org/2001/XMLSchema');
87             schema_file = javax.xml.transform.stream.StreamSource.new(get_class.get_resource_as_stream('/org/springframework/beans/factory/xml/spring-beans-2.0.xsd'))
88             schema = factory.newSchema(schema_file)
89             validator = schema.newValidator()
90             validator.validate(javax.xml.transform.dom.DOMSource.new(self))
91         end
92
93         def push(element)
94             ensure_stack
95             $tag_stack.push(element)
96         end
97
98         def pop
99             ensure_stack
100             $tag_stack.pop
101         end
102
103         def ensure_stack
104             unless defined?($tag_stack)
105                 $tag_stack = []
106                 $tag_stack.push(self)
107             end
108         end
109
110         def last_element
111             ensure_stack
112             $tag_stack.last
113         end
114     }
115
116     class SerializableManagedList < AbstractSerializableManagedList
117         def serialize_xml(doc)
118             doc.tag('list') do
119                 self.each do |item|
120                     if item.respond_to?(:serialize_xml)
121                       item.serialize_xml(doc)
122                     end
123                 end
124             end
125         end
126     end
127
128     class SerializableManagedMap < AbstractSerializableManagedMap
129         def serialize_xml(doc)
130            doc.tag('map') do
131              self.each do |k,v|
132                 doc.tag('entry', "key"=>k.to_s) do
133                     if v.respond_to?(:serialize_xml)
134                         v.serialize_xml(doc)
135                     end
136                 end
137              end
138            end
139         end
140     end
141
142     class SerializableRuntimeBeanReference < AbstractSerializableRuntimeBeanReference
143         def initialize(name)
144             super(name)
145         end
146
147         def serialize_xml(doc)
148             doc.tag('ref', "bean"=>bean_name)
149         end
150     end
151
152     class SerializablePropertyValue < AbstractSerializablePropertyValue
153         def initialize(name, value)
154             super
155         end
156
157         def serialize_xml(doc)
158             if value.respond_to?(:serialize_xml)
159                 value.serialize_xml(doc)
160             end
161         end
162     end
163
164     class BeanDef < AbstractSerializableRootBeanDefinition
165        def serialize_xml(doc)
166             attrs = {}
167             attrs['id'] = self.bean_id unless @auto_generated
168             attrs['class'] = self.bean_class_name                       
169             doc.tag("bean", attrs) do
170                 (0..constructor_argument_values.argument_count-1).each do |i|
171                     doc.tag("constructor-arg",  "index" => i.to_s) do
172                         v = constructor_argument_values.get_argument_value(i, nil)
173                         if v.value.respond_to?(:serialize_xml)
174                             v.value.serialize_xml(doc)
175                         else
176                             v.value.to_s.serialize_xml(doc)
177                         end
178                     end
179                 end
180
181                 property_values.getPropertyValues.each do |val|
182                     doc.tag('property', "name" => val.name) do
183                         val.serialize_xml(doc)
184                     end
185                 end
186            end
187         end
188     end
189
190     #Serialize the context to xml.
191     def serialize_context(out=java.lang.System.err, validate=true)
192         doc = DocumentImpl.new
193         begin
194             attrs = {
195                 "xmlns"=>"http://www.springframework.org/schema/beans",
196                 "xmlns:xsi"=>"http://www.w3.org/2001/XMLSchema-instance"
197             }
198
199             attrs['default-init-method']    = BEANDEFAULTS[:init_method] if BEANDEFAULTS[:init_method]
200             attrs['default-destroy-method'] = BEANDEFAULTS[:destroy_method] if BEANDEFAULTS[:destroy_method]
201
202             xsi_schemaLocation=''
203             SCHEMAS.each do |k,v|
204                 xsi_schemaLocation += "#{k} #{v} "
205             end
206
207             attrs['xsi:schemaLocation'] = xsi_schemaLocation
208
209             alias_map = {}
210             names     = []
211             bean_factory.bean_definition_names.each do |name|
212               names << name
213               alias_map[name] = bean_factory.get_aliases(name)
214             end
215
216             #alias_map.each {|name, aliases| names.reject! {|n| aliases.include?(n)}}
217             doc.comment("serialized by springy on #{Time.new}")
218             doc.tag('beans', attrs) do
219                 names.each do |name|
220                     bd = bean_factory.get_bean_definition(name)
221                     bd.serialize_xml(doc) if bd.respond_to?(:serialize_xml)
222                     alias_map[name].each { |a| doc.tag('alias', "name"=>name, "alias"=>a) } if alias_map[name]
223                 end
224             end
225             doc.validate! if validate
226         ensure
227             #doc.serialize(out)
228         end
229         return doc.serialize_to_s, doc
230     end
231 end
Note: See TracBrowser for help on using the browser.