Add XML classes
This commit is contained in:
147
lib/calligraphy/xml/builder.rb
Normal file
147
lib/calligraphy/xml/builder.rb
Normal file
@@ -0,0 +1,147 @@
|
||||
module Calligraphy::XML
|
||||
class Builder
|
||||
SUPPORTED_NS_TAGS = %w(
|
||||
creationdate displayname exclusive getcontentlanguage getcontentlength
|
||||
getcontenttype getetag getlastmodified href lockdiscovery lockscope
|
||||
locktype owner write
|
||||
)
|
||||
|
||||
attr_reader :dav_ns, :default_ns, :server_protocol
|
||||
|
||||
def initialize(dav_ns: 'D', server_protocol: 'HTTP/1.1')
|
||||
@dav_ns = dav_ns
|
||||
@default_ns = { "xmlns:#{@dav_ns}" => 'DAV:' }
|
||||
@server_protocol = server_protocol
|
||||
end
|
||||
|
||||
def lock_res(activelock_properties)
|
||||
build :prop do |xml|
|
||||
xml.lockdiscovery do
|
||||
activelock_properties.each do |properties|
|
||||
activelock xml, properties
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def propfind_res(path, properties)
|
||||
multistatus do |xml|
|
||||
href xml, path
|
||||
propstat xml, properties[:found], :ok
|
||||
propstat xml, properties[:not_found], :not_found
|
||||
end
|
||||
end
|
||||
|
||||
def proppatch_res(path, actions)
|
||||
multistatus do |xml|
|
||||
href xml, path
|
||||
propstat xml, actions[:set]
|
||||
propstat xml, actions[:remove]
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def build(tag)
|
||||
Nokogiri::XML::Builder.new do |xml|
|
||||
xml[@dav_ns].send(tag, @default_ns) do
|
||||
yield xml
|
||||
end
|
||||
end.to_xml
|
||||
end
|
||||
|
||||
def activelock(xml, property_set)
|
||||
xml.activelock do
|
||||
property_set.each do |property|
|
||||
property_drilldown xml, property
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def href(xml, path)
|
||||
xml.href path
|
||||
end
|
||||
|
||||
def multistatus
|
||||
build :multistatus do |xml|
|
||||
xml.response do
|
||||
yield xml
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def prop(xml, property_set)
|
||||
xml.prop do
|
||||
property_set.each do |property|
|
||||
property_drilldown xml, property
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def propstat(xml, property_set, status=:ok)
|
||||
return unless property_set.length > 0
|
||||
|
||||
xml.propstat do
|
||||
prop xml, property_set
|
||||
status xml, status
|
||||
end
|
||||
end
|
||||
|
||||
def resourcetype(xml, property)
|
||||
if property.children.text == 'collection'
|
||||
xml[@dav_ns].resourcetype do
|
||||
xml.send 'collection'
|
||||
end
|
||||
else
|
||||
xml[@dav_ns].resourcetype
|
||||
end
|
||||
end
|
||||
|
||||
def status(xml, status)
|
||||
xml.status status_message status
|
||||
end
|
||||
|
||||
# NOTE: `xml[@dav_ns].send timeout` results in Timeout being called, so
|
||||
# we have this timeout method for convenience
|
||||
def timeout(xml, property)
|
||||
xml[@dav_ns].timeout do
|
||||
xml.text property.text
|
||||
end
|
||||
end
|
||||
|
||||
def property_drilldown(xml, property)
|
||||
if property.is_a? Array
|
||||
property.each do |prop|
|
||||
property_drilldown xml, prop
|
||||
end
|
||||
elsif property.children && property.text.nil?
|
||||
xml.send property.name do
|
||||
property.children.each do |child|
|
||||
property_drilldown xml, child
|
||||
end
|
||||
end
|
||||
elsif property.name == 'resourcetype'
|
||||
resourcetype xml, property
|
||||
elsif property.name == 'timeout'
|
||||
timeout xml, property
|
||||
elsif SUPPORTED_NS_TAGS.include? property.name
|
||||
xml[@dav_ns].send property.name do
|
||||
xml.text property.text
|
||||
end
|
||||
elsif property.namespace && property.namespace.href
|
||||
xml.send property.name, xmlns: property.namespace.href do
|
||||
xml.text property.text
|
||||
end
|
||||
else
|
||||
xml.send property.name, property.text do
|
||||
xml.parent.namespace = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def status_message(status)
|
||||
status_code = Rack::Utils.status_code status
|
||||
[@server_protocol, status_code, Rack::Utils::HTTP_STATUS_CODES[status_code]].join ' '
|
||||
end
|
||||
end
|
||||
end
|
||||
10
lib/calligraphy/xml/namespace.rb
Normal file
10
lib/calligraphy/xml/namespace.rb
Normal file
@@ -0,0 +1,10 @@
|
||||
module Calligraphy::XML
|
||||
class Namespace
|
||||
attr_accessor :href, :prefix
|
||||
|
||||
def initialize(namespace)
|
||||
@href = namespace.href if namespace.href
|
||||
@prefix = namespace.prefix if namespace.prefix
|
||||
end
|
||||
end
|
||||
end
|
||||
23
lib/calligraphy/xml/node.rb
Normal file
23
lib/calligraphy/xml/node.rb
Normal file
@@ -0,0 +1,23 @@
|
||||
module Calligraphy::XML
|
||||
class Node
|
||||
attr_accessor :children, :name, :namespace, :text
|
||||
|
||||
def initialize(node=nil)
|
||||
unless node.nil?
|
||||
@name = node.name
|
||||
@text = node.text unless node.text.empty?
|
||||
|
||||
if node.namespace
|
||||
@namespace = Calligraphy::XML::Namespace.new node.namespace
|
||||
end
|
||||
|
||||
if node.children&.length > 0
|
||||
@children = []
|
||||
node.children.each do |child|
|
||||
@children.push Calligraphy::XML::Node.new child
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user