lib/openwfe/util/xml.rb in ruote-0.9.19 vs lib/openwfe/util/xml.rb in ruote-0.9.20

- old
+ new

@@ -1,41 +1,29 @@ -# #-- -# Copyright (c) 2008 John Mettraux, OpenWFE.org -# All rights reserved. +# Copyright (c) 2008-2009, John Mettraux, jmettraux@gmail.com # -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: # -# . Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. # -# . Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. # -# . Neither the name of the "OpenWFE" nor the names of its contributors may be -# used to endorse or promote products derived from this software without -# specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. +# Made in Japan. #++ -# -# -# "made in Japan" -# require 'openwfe/rexml' require 'builder' @@ -68,201 +56,67 @@ end module OpenWFE - # - # Simple methods for converting launchitems and workitems from and to - # XML. - # - # There are also the from_xml(xml) and the to_xml(object) methods - # that are interesting (though limited). - # module Xml - #-- - # launchitems - #++ - # - # Turns a launchitem into an XML String + # This method is used by all the to_xml methods, it ensures a builder + # is available via the :builder key in the options hash. # - def self.launchitem_to_xml (li, indent=0) - - b = Builder::XmlMarkup.new :indent => indent - - b.instruct! - - b.launchitem do - b.workflow_definition_url li.workflow_definition_url - b.attributes do - hash_to_xml b, li.attributes - end - end - - b.target! - end - + # Usage example : # - # Given some XML (string or rexml doc/elt), extracts the LaunchItem - # instance. + # builder(options) do |xml| + # xml.hash do + # h.each do |k, v| + # xml.entry do + # object_to_xml k, options + # object_to_xml v, options + # end + # end + # end + # end # - def self.launchitem_from_xml (xml) - - root = to_element xml, 'launchitem' - - li = LaunchItem.new - - li.wfdurl = text root, 'workflow_definition_url' - - li.attributes = object_from_xml( - root.owfe_first_elt_child('attributes').owfe_first_elt_child) - - li - end - - #-- - # flow expression id - #++ - - def self.fei_to_xml (fei, indent=0) - - b = Builder::XmlMarkup.new :indent => indent - - b.instruct! - - _fei_to_xml b, fei - - b.target! - end - - def self.fei_from_xml (xml) - - xml = to_element xml, 'flow_expression_id' - - fei = FlowExpressionId.new - - FlowExpressionId::FIELDS.each do |f| - fei.send "#{f}=", text(xml, f.to_s) + def self.builder (options={}, &block) + if b = options[:builder] + block.call(b) + else + b = Builder::XmlMarkup.new(:indent => (options[:indent] || 0)) + options[:builder] = b + b.instruct! unless options[:instruct] == false + block.call(b) + b.target! end - - fei end - #-- - # workitems - #++ + def self.object_to_xml (o, options={}) - # - # Turns an [InFlow]WorkItem into some XML. - # - def self.workitem_to_xml (wi, indent=0) - - b = Builder::XmlMarkup.new :indent => indent - - b.instruct! - - _workitem_to_xml b, wi - - b.target! - end - - # - # Pipes a workitem into a XML builder - # - def self._workitem_to_xml (builder, wi) - - atts = {} - atts['href'] = wi.uri if wi.uri - - builder.workitem(atts) do - - _fei_to_xml builder, wi.fei # flow expression id - - builder.last_modified to_httpdate(wi.last_modified) - - builder.participant_name wi.participant_name - - builder.dispatch_time to_httpdate(wi.dispatch_time) - #builder.filter ... - builder.store wi.store - - builder.attributes do - hash_to_xml builder, wi.attributes + builder(options) do |xml| + case o + when true then xml.true + when false then xml.false + when nil then xml.null + when Numeric then xml.number(o.to_s) + when Hash then hash_to_xml(o, options) + when Array then array_to_xml(o, options) + when String then xml.string(o.to_s) + when Symbol then xml.symbol(o.to_s) + else xml.object(o.to_s) end end end # - # Extracts an [InFlow]WorkItem instance from some XML. + # an alias # - def self.workitem_from_xml (xml) + def self.to_xml (o, options={}) - root = to_element xml, 'workitem' - - wi = InFlowWorkItem.new - - wi.uri = root.attribute('href') - wi.uri = wi.uri.value if wi.uri - - wi.fei = fei_from_xml root.elements['flow_expression_id'] - - wi.last_modified = from_httpdate(text(root, 'last_modified')) - wi.participant_name = text root, 'participant_name' - wi.dispatch_time = from_httpdate(text(root, 'dispatch_time')) - - wi.attributes = object_from_xml( - root.owfe_first_elt_child('attributes').owfe_first_elt_child) - - wi + object_to_xml(o, options) end # - # Extracts a list of workitems from some XML. - # - def self.workitems_from_xml (xml) - - root = to_element xml, 'workitems' - - root.owfe_elt_children.collect do |elt| - workitem_from_xml elt - end - end - - #-- - # cancelitems - #++ - - def self.cancelitem_to_xml (ci) - - nil # TODO : implement me - end - - def self.cancelitem_from_xml (xml) - - nil # TODO : implement me - end - - # - # An 'internal' method, turning an object into some XML. - # - def self.object_to_xml (xml, o) - - return xml.true if o == true - return xml.false if o == false - return xml.null if o == nil - return xml.number(o.to_s) if o.is_a?(Numeric) - - return hash_to_xml(xml, o) if o.is_a?(Hash) - return array_to_xml(xml, o) if o.is_a?(Array) - - return xml.string(o.to_s) if o.is_a?(String) - - xml.object o.to_s - end - - # # Turns XML into an object (quite basic though). # # For example : # # <array> @@ -283,21 +137,17 @@ object_from_xml xml end # - # from_xml, the other way + # Like to_xml(o) but instead of returning a String, returns a REXML + # Element # - def self.to_xml (o, indent=0, instruct = false) + def self.to_rexml (o) - b = Builder::XmlMarkup.new :indent => indent - - b.instruct! if instruct - - object_to_xml b, o - - b.target! + d = REXML::Document.new(to_xml(o)) + d.root end private def self.to_httpdate (t) @@ -316,54 +166,49 @@ #-- # OUT #++ - def self._fei_to_xml (xml, fei) - - xml.flow_expression_id do - FlowExpressionId::FIELDS.each do |f| - xml.tag! f.to_s, fei.send(f) - end - - xml.fei_short fei.to_s - # a short, 1 string version of the fei - end - end - def self.to_element (xml, root_name=nil) xml = if xml.is_a?(REXML::Element) xml elsif xml.is_a?(REXML::Document) xml.root else REXML::Document.new(xml).root end - raise "not the XML of a #{root_name} ('#{xml.name}')" \ - if root_name and (xml.name != root_name) + #raise "not the XML of a #{root_name} ('#{xml.name}')" \ + # if root_name and (xml.name != root_name) + return nil if root_name and (xml.name != root_name) xml end - def self.hash_to_xml (xml, h) + def self.hash_to_xml (h, options={}) - xml.hash do - h.each do |k, v| - xml.entry do - object_to_xml xml, k - object_to_xml xml, v + tagname = options.delete(:tag) || 'hash' + + builder(options) do |xml| + xml.tag!(tagname) do + h.each do |k, v| + xml.entry do + object_to_xml(k, options) + object_to_xml(v, options) + end end end end end - def self.array_to_xml (xml, a) + def self.array_to_xml (a, options={}) - xml.array do - a.each { |o| object_to_xml xml, o } + builder(options) do |xml| + xml.array do + a.each { |o| object_to_xml(o, options) } + end end end #-- # IN @@ -373,10 +218,11 @@ # Returns the text wrapped in the child elt with the given # name. # def self.text (parent, elt_name) - parent.elements[elt_name].text + elt = parent.elements[elt_name] + elt ? elt.text : nil end def self.object_from_xml (elt) name = elt.name