class Tilia::Dav::Xml::Element::Response
WebDAV {DAV:}response parser
This class parses the {DAV:}response element, as defined in:
Attributes
Returns the url
@return string
Returns the httpStatus value
@return string
Returns the property list
@return array
Public Class Methods
The href argument is a url relative to the root of the server. This class will calculate the full path.
The responseProperties argument is a list of properties within an array with keys representing HTTP status codes
Besides specific properties, the entire {DAV:}response element may also have a http status code. In most cases you don't need it.
This is currently used by the Sync
extension to indicate that a node is deleted.
@param string href @param array response_properties
@param string http_status
# File lib/tilia/dav/xml/element/response.rb, line 46 def initialize(href, response_properties, http_status = nil) @href = href @response_properties = response_properties @http_status = http_status end
The deserialize method is called during xml parsing.
This method is called statictly, this is because in theory this method may be used as a type of constructor, or factory method.
Often you want to return an instance of the current class, but you are free to return other data as well.
You are responsible for advancing the reader to the next element. Not doing anything will result in a never-ending loop.
If you just want to skip parsing for this element altogether, you can just call reader.next
reader.parse_inner_tree will parse the entire sub-tree, and advance to the next element.
@param Reader reader @return mixed
# File lib/tilia/dav/xml/element/response.rb, line 137 def self.xml_deserialize(reader) reader.push_context reader.element_map['{DAV:}propstat'] = Tilia::Xml::Element::KeyValue # We are overriding the parser for {DAV:}prop. This deserializer is # almost identical to the one for Sabre\Xml\Element\KeyValue. # # The difference is that if there are any child-elements inside of # {DAV:}prop, that have no value, normally any deserializers are # called. But we don't want this, because a singular element without # child-elements implies 'no value' in {DAV:}prop, so we want to skip # deserializers and just set null for those. reader.element_map['{DAV:}prop'] = lambda do |reader| if reader.empty_element? reader.next return {} end values = {} reader.read loop do if reader.node_type == ::LibXML::XML::Reader::TYPE_ELEMENT clark = reader.clark if reader.empty_element? values[clark] = nil reader.next else values[clark] = reader.parse_current_element['value'] end else reader.read end break unless reader.node_type != ::LibXML::XML::Reader::TYPE_END_ELEMENT end reader.read values end elems = reader.parse_inner_tree reader.pop_context href = nil property_lists = {} status_code = nil elems.each do |elem| case elem['name'] when '{DAV:}href' href = elem['value'] when '{DAV:}propstat' status = elem['value']['{DAV:}status'] status = status.split(' ')[1] properties = elem['value'].key?('{DAV:}prop') ? elem['value']['{DAV:}prop'] : [] property_lists[status] = properties if properties.any? when '{DAV:}status' status_code = elem['value'].split(' ')[1] end end new(href, property_lists, status_code) end
Public Instance Methods
The serialize method is called during xml writing.
It should use the writer argument to encode this object into XML.
Important note: it is not needed to create the parent element. The parent element is already created, and we only have to worry about attributes, child elements and text (if any).
Important note 2: If you are writing any new elements, you are also responsible for closing them.
@param Writer writer @return void
# File lib/tilia/dav/xml/element/response.rb, line 80 def xml_serialize(writer) if @http_status writer.write_element('{DAV:}status', "HTTP/1.1 #{@http_status} #{Tilia::Http::Response.status_codes[@http_status]}") end writer.write_element('{DAV:}href', writer.context_uri + Http::encode_path(href)) empty = true @response_properties.each do |status, properties| # Skipping empty lists # TODO: this code is slightly extended, wait for Evert if the original PHP code was correct next if properties.is_a?(Hash) && properties.empty? next if properties.blank? next if status.to_i.to_s != status.to_s empty = false writer.start_element('{DAV:}propstat') writer.write_element('{DAV:}prop', properties) writer.write_element('{DAV:}status', "HTTP/1.1 #{status} #{Tilia::Http::Response.status_codes[status]}") writer.end_element # {DAV:}propstat end if empty # The WebDAV spec _requires_ at least one DAV:propstat to appear for # every DAV:response. In some circumstances however, there are no # properties to encode. # # In those cases we MUST specify at least one DAV:propstat anyway, with # no properties. writer.write_element( '{DAV:}propstat', '{DAV:}prop' => [], '{DAV:}status' => "HTTP/1.1 418 #{Http::Response.status_codes[418]}" ) end end