Class: Coarnotify::Core::Notify::NotifyBase

Inherits:
Object
  • Object
show all
Defined in:
lib/coarnotify/core/notify.rb

Overview

Base class from which all Notify objects extend.

There are two kinds of Notify objects:

  1. Patterns, which are the notifications themselves

  2. Pattern Parts, which are nested elements in the Patterns, such as objects, contexts, actors, etc

This class forms the basis for both of those types, and provides essential services, such as construction, accessors and validation, as well as supporting the essential properties “id” and “type”

Direct Known Subclasses

NotifyPattern, NotifyPatternPart

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(stream: nil, validate_stream_on_construct: true, validate_properties: true, validators: nil, validation_context: nil, properties_by_reference: true) ⇒ NotifyBase

Base constructor that all subclasses should call

Parameters:

  • stream (ActivityStreams2::ActivityStream, Hash) (defaults to: nil)

    The activity stream object, or a hash from which one can be created

  • validate_stream_on_construct (Boolean) (defaults to: true)

    should the incoming stream be validated at construction-time

  • validate_properties (Boolean) (defaults to: true)

    should individual properties be validated as they are set

  • validators (Validate::Validator) (defaults to: nil)

    the validator object for this class and all nested elements

  • validation_context (String, Array) (defaults to: nil)

    the context in which this object is being validated

  • properties_by_reference (Boolean) (defaults to: true)

    should properties be get and set by reference (the default) or by value



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/coarnotify/core/notify.rb', line 139

def initialize(stream: nil, validate_stream_on_construct: true, validate_properties: true,
               validators: nil, validation_context: nil, properties_by_reference: true)
  @validate_stream_on_construct = validate_stream_on_construct
  @validate_properties = validate_properties
  @validators = validators || VALIDATORS
  @validation_context = validation_context
  @properties_by_reference = properties_by_reference
  validate_now = false

  if stream.nil?
    @stream = ActivityStreams2::ActivityStream.new
  elsif stream.is_a?(Hash)
    validate_now = validate_stream_on_construct
    @stream = ActivityStreams2::ActivityStream.new(stream)
  else
    validate_now = validate_stream_on_construct
    @stream = stream
  end

  if @stream.get_property(ActivityStreams2::Properties::ID).nil?
    @stream.set_property(ActivityStreams2::Properties::ID, "urn:uuid:#{SecureRandom.hex}")
  end

  validate if validate_now
end

Instance Attribute Details

#properties_by_referenceObject (readonly)

Returns the value of attribute properties_by_reference.



129
130
131
# File 'lib/coarnotify/core/notify.rb', line 129

def properties_by_reference
  @properties_by_reference
end

#validate_propertiesObject (readonly)

Returns the value of attribute validate_properties.



129
130
131
# File 'lib/coarnotify/core/notify.rb', line 129

def validate_properties
  @validate_properties
end

#validate_stream_on_constructObject (readonly)

Returns the value of attribute validate_stream_on_construct.



129
130
131
# File 'lib/coarnotify/core/notify.rb', line 129

def validate_stream_on_construct
  @validate_stream_on_construct
end

#validatorsObject (readonly)

Returns the value of attribute validators.



129
130
131
# File 'lib/coarnotify/core/notify.rb', line 129

def validators
  @validators
end

Instance Method Details

#docHash

The underlying ActivityStream object, excluding the JSON-LD @context

Returns:

  • (Hash)

    the document hash



168
169
170
# File 'lib/coarnotify/core/notify.rb', line 168

def doc
  @stream.doc
end

#get_property(prop_name, by_reference: nil) ⇒ Object

Generic property getter. It is strongly recommended that all accessors proxy for this method as this enforces by-reference/by-value accessing, and mediates directly with the underlying activity stream object.

Parameters:

  • prop_name (String, Array)

    The property to retrieve

  • by_reference (Boolean) (defaults to: nil)

    Whether to retrieve by_reference or by_value

Returns:

  • (Object)

    the property value



207
208
209
210
211
212
213
214
215
# File 'lib/coarnotify/core/notify.rb', line 207

def get_property(prop_name, by_reference: nil)
  by_reference = @properties_by_reference if by_reference.nil?
  val = @stream.get_property(prop_name)
  if by_reference
    val
  else
    val.dup rescue val  # Deep copy where possible
  end
end

#idString

The id of the object

Returns:

  • (String)

    the id



175
176
177
# File 'lib/coarnotify/core/notify.rb', line 175

def id
  get_property(ActivityStreams2::Properties::ID)
end

#id=(value) ⇒ Object

Set the id of the object

Parameters:

  • value (String)

    the id to set



182
183
184
# File 'lib/coarnotify/core/notify.rb', line 182

def id=(value)
  set_property(ActivityStreams2::Properties::ID, value)
end

#optional_and_validate(ve, prop_name, value) ⇒ Object

Validate the value if it is not nil, but do not raise a validation error if it is nil

Parameters:

  • ve (ValidationError)

    the validation error to add to

  • prop_name (String, Array)

    the property name

  • value (Object)

    the value to validate



328
329
330
331
332
333
334
335
336
337
338
339
340
# File 'lib/coarnotify/core/notify.rb', line 328

def optional_and_validate(ve, prop_name, value)
  if value
    if value.is_a?(NotifyBase)
      begin
        value.validate
      rescue ValidationError => subve
        ve.add_nested_errors(prop_name, subve)
      end
    else
      register_property_validation_error(ve, prop_name, value)
    end
  end
end

#register_property_validation_error(ve, prop_name, value) ⇒ Object

Force validate the property and if an error is found, add it to the validation error

Parameters:

  • ve (ValidationError)

    the validation error to add to

  • prop_name (String, Array)

    the property name

  • value (Object)

    the value to validate



282
283
284
285
# File 'lib/coarnotify/core/notify.rb', line 282

def register_property_validation_error(ve, prop_name, value)
  success, msg = validate_property(prop_name, value, force_validate: true, raise_error: false)
  ve.add_error(prop_name, msg) unless success
end

#required(ve, prop_name, value) ⇒ Object

Add a required error to the validation error if the value is nil

Parameters:

  • ve (ValidationError)

    The validation error to which to add the message

  • prop_name (String, Array)

    The property to check

  • value (Object)

    The value



292
293
294
295
296
297
# File 'lib/coarnotify/core/notify.rb', line 292

def required(ve, prop_name, value)
  if value.nil?
    pn = prop_name.is_a?(Array) ? prop_name[0] : prop_name
    ve.add_error(prop_name, Validate::REQUIRED_MESSAGE % pn)
  end
end

#required_and_validate(ve, prop_name, value) ⇒ Object

Add a required error to the validation error if the value is nil, and then validate the value if not.

Any error messages are added to the ValidationError object

Parameters:

  • ve (ValidationError)

    the validation error to which to add the message

  • prop_name (String, Array)

    The property to check

  • value (Object)

    the value to check



306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
# File 'lib/coarnotify/core/notify.rb', line 306

def required_and_validate(ve, prop_name, value)
  if value.nil?
    pn = prop_name.is_a?(Array) ? prop_name[0] : prop_name
    ve.add_error(prop_name, Validate::REQUIRED_MESSAGE % pn)
  else
    if value.is_a?(NotifyBase)
      begin
        value.validate
      rescue ValidationError => subve
        ve.add_nested_errors(prop_name, subve)
      end
    else
      register_property_validation_error(ve, prop_name, value)
    end
  end
end

#set_property(prop_name, value, by_reference: nil) ⇒ Object

Generic property setter. It is strongly recommended that all accessors proxy for this method as this enforces by-reference/by-value accessing, and mediates directly with the underlying activity stream object.

Parameters:

  • prop_name (String, Array)

    The property to set

  • value (Object)

    The value to set

  • by_reference (Boolean) (defaults to: nil)

    Whether to set by_reference or by_value



224
225
226
227
228
229
# File 'lib/coarnotify/core/notify.rb', line 224

def set_property(prop_name, value, by_reference: nil)
  by_reference = @properties_by_reference if by_reference.nil?
  validate_property(prop_name, value)
  value = value.dup rescue value unless by_reference  # Deep copy where possible
  @stream.set_property(prop_name, value)
end

#to_jsonldHash

Get the notification pattern as JSON-LD

Returns:

  • (Hash)

    JSON-LD representation of the pattern



345
346
347
# File 'lib/coarnotify/core/notify.rb', line 345

def to_jsonld
  @stream.to_jsonld
end

#typeString+

The type of the object

Returns:

  • (String, Array<String>)

    the type



189
190
191
# File 'lib/coarnotify/core/notify.rb', line 189

def type
  get_property(ActivityStreams2::Properties::TYPE)
end

#type=(types) ⇒ Object

Set the type of the object

Parameters:

  • types (String, Array<String>)

    the type(s) to set



196
197
198
# File 'lib/coarnotify/core/notify.rb', line 196

def type=(types)
  set_property(ActivityStreams2::Properties::TYPE, types)
end

#validateBoolean

Validate the object. This provides the basic validation on id and type. Subclasses should override this method with their own validation, and call this method via super first to ensure the basic properties are validated.

Returns:

  • (Boolean)

    true or raise a ValidationError if there are errors



236
237
238
239
240
241
242
243
244
# File 'lib/coarnotify/core/notify.rb', line 236

def validate
  ve = ValidationError.new

  required_and_validate(ve, ActivityStreams2::Properties::ID, id)
  required_and_validate(ve, ActivityStreams2::Properties::TYPE, type)

  raise ve if ve.has_errors?
  true
end

#validate_property(prop_name, value, force_validate: false, raise_error: true) ⇒ Array

Validate a single property. This is used internally by set_property.

If the object has validate_properties set to false then that behaviour may be overridden by setting force_validate to true

The validator applied to the property will be determined according to the validators property of the object and the validation_context of the object.

Parameters:

  • prop_name (String, Array)

    The property to validate

  • value (Object)

    the value to validate

  • force_validate (Boolean) (defaults to: false)

    whether to validate anyway, even if property validation is turned off at the object level

  • raise_error (Boolean) (defaults to: true)

    raise an exception on validation failure, or return a tuple with the result

Returns:

  • (Array)

    A tuple of whether validation was successful, and the error message if it was not



258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
# File 'lib/coarnotify/core/notify.rb', line 258

def validate_property(prop_name, value, force_validate: false, raise_error: true)
  return [true, ""] if value.nil?
  if @validate_properties || force_validate
    validator = @validators.get(prop_name, @validation_context)
    if validator
      begin
        validator.call(self, value)
      rescue ArgumentError => ve
        if raise_error
          raise ve
        else
          return [false, ve.message]
        end
      end
    end
  end
  [true, ""]
end