Class: Tilia::Dav::PropPatch

Inherits:
Object
  • Object
show all
Defined in:
lib/tilia/dav/prop_patch.rb

Overview

This class represents a set of properties that are going to be updated.

Usually this is simply a PROPPATCH request, but it can also be used for internal updates.

Property updates must always be atomic. This means that a property update must either completely succeed, or completely fail.

Direct Known Subclasses

MkCol

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(mutations) ⇒ PropPatch

Constructor

Parameters:

  • array

    mutations A list of updates



38
39
40
41
42
43
# File 'lib/tilia/dav/prop_patch.rb', line 38

def initialize(mutations)
  self.mutations = mutations
  self.result = {}
  self.failed = false
  self.property_update_callbacks = []
end

Instance Attribute Details

#failedObject

This property will be set to true if the operation failed.



33
34
35
# File 'lib/tilia/dav/prop_patch.rb', line 33

def failed
  @failed
end

#mutationsObject

Returns the full list of mutations

Returns:

  • array



17
18
19
# File 'lib/tilia/dav/prop_patch.rb', line 17

def mutations
  @mutations
end

#property_update_callbacksObject

This is the list of callbacks when we’re performing the actual update.



28
29
30
# File 'lib/tilia/dav/prop_patch.rb', line 28

def property_update_callbacks
  @property_update_callbacks
end

#resultObject

Returns the result of the operation.

Returns:

  • array



23
24
25
# File 'lib/tilia/dav/prop_patch.rb', line 23

def result
  @result
end

Instance Method Details

#commitObject

Performs the actual update, and calls all callbacks.

This method returns true or false depending on if the operation was successful.

Returns:

  • bool



164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/tilia/dav/prop_patch.rb', line 164

def commit
  # First we validate if every property has a handler
  mutations.keys.each do |property_name|
    unless result.key? property_name
      self.failed = true
      result[property_name] = 403
    end
  end

  property_update_callbacks.each do |callbackInfo|
    break if failed
    if callbackInfo[0].is_a? String
      do_callback_single_prop(callbackInfo[0], callbackInfo[1])
    else
      do_callback_multi_prop(callbackInfo[0], callbackInfo[1])
    end
  end

  # If anywhere in this operation updating a property failed, we must
  # update all other properties accordingly.
  if failed
    result.each do |property_name, status|
      if status == 202
        # Failed dependency
        result[property_name] = 424
      end
    end
  end

  !failed
end

#handle(properties, callback) ⇒ Object

Call this function if you wish to handle updating certain properties. For instance, your class may be responsible for handling updates for the DAV:displayname property.

In that case, call this method with the first argument “DAV:displayname” and a second argument that’s a method that does the actual updating.

It’s possible to specify more than one property as an array.

The callback must return a boolean or an it. If the result is true, the operation was considered successful. If it’s false, it’s consided failed.

If the result is an integer, we’ll use that integer as the http status code associated with the operation.

Parameters:

  • string|string[]

    properties

  • callable

    callback

Returns:

  • void



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/tilia/dav/prop_patch.rb', line 65

def handle(properties, callback)
  used_properties = []
  [properties].flatten.each do |property_name|
    next unless mutations.key?(property_name) && !result.key?(property_name)
    used_properties << property_name
    # HTTP Accepted
    result[property_name] = 202
  end

  # Only registering if there's any unhandled properties.
  return nil unless used_properties.any?

  property_update_callbacks << [
    # If the original argument to this method was a string, we need
    # to also make sure that it stays that way, so the commit function
    # knows how to format the arguments to the callback.
    properties.is_a?(String) ? properties : used_properties,
    callback]
end

#handle_remaining(callback) ⇒ Object

Call this function if you wish to handle all properties that haven’t been handled by anything else yet. Note that you effectively claim with this that you promise to process all properties that are coming in.

Parameters:

  • callable

    callback

Returns:

  • void



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/tilia/dav/prop_patch.rb', line 91

def handle_remaining(callback)
  properties = remaining_mutations
  unless properties.any?
    # Nothing to do, don't register callback
    return
  end

  properties.each do |property_name|
    # HTTP Accepted
    result[property_name] = 202

    property_update_callbacks << [
      properties,
      callback]
  end
end

#remaining_mutationsObject

Returns the list of properties that don’t have a result code yet.

This method returns a list of property names, but not its values.

Returns:

  • string[]



137
138
139
140
141
142
143
# File 'lib/tilia/dav/prop_patch.rb', line 137

def remaining_mutations
  remaining = []
  mutations.keys.each do |property_name|
    remaining << property_name unless result.key? property_name
  end
  remaining
end

#remaining_result_code=(result_code) ⇒ Object

Sets the result code for all properties that did not have a result yet.

Parameters:

  • int

    result_code

Returns:

  • void



125
126
127
128
129
130
# File 'lib/tilia/dav/prop_patch.rb', line 125

def remaining_result_code=(result_code)
  update_result_code(
    remaining_mutations,
    result_code
  )
end

#remaining_valuesObject

Returns the list of properties that don’t have a result code yet.

This method returns list of properties and their values.

Returns:

  • array



150
151
152
153
154
155
156
# File 'lib/tilia/dav/prop_patch.rb', line 150

def remaining_values
  remaining = {}
  mutations.each do |property_name, prop_value|
    remaining[property_name] = prop_value unless result.key? property_name
  end
  remaining
end

#update_result_code(properties, result_code) ⇒ Object

Sets the result code for one or more properties.

Parameters:

  • string|string[]

    properties

  • int

    result_code

Returns:

  • void



113
114
115
116
117
118
119
# File 'lib/tilia/dav/prop_patch.rb', line 113

def update_result_code(properties, result_code)
  [properties].flatten.each do |property_name|
    result[property_name] = result_code
  end

  self.failed = true if result_code >= 400
end