Class: ActivityStreams::ASObj

Inherits:
Object
  • Object
show all
Includes:
Makers
Defined in:
lib/streams/activitystreams.rb

Overview

Represents a basic Activity Streams Object… Instances, once created, are immutable for all the core properties. The object maintains an internal hash and performs basic input validation to ensure that the built object conforms to the basic requirements of the Activity Streams specifications. Specific validation requirements are defined by the Spec module associated with the object_type specified for the ASObj instance

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Makers

#activity, #collection, #copy_from, #media_link, #now, #object

Constructor Details

#initialize(object_type = nil) ⇒ ASObj

Returns a new instance of ASObj.



208
209
210
211
212
213
214
# File 'lib/streams/activitystreams.rb', line 208

def initialize object_type=nil
  @_ = {}
  @_.__object_type = object_type
  @object_type = object_type  
  extend SPECS[object_type] || SPECS[nil]
  strict
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missingObject

Within the generator, any method call that has exactly one parameter will be turned into a member of the underlying hash



356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
# File 'lib/streams/activitystreams.rb', line 356

def property m, *args, &block

  # Return nil if it's looking for an unknown alias_for_* method
  return nil if m =~ /^alias\_for\_.*/
  
  # Special magic... if an unknown ? method is called, it's treated 
  # as a check against the internal hash to see if the given field
  # has been set. For instance, priority? will check to see if the 
  # priority field has been set
  return @_.has_key?(m.to_s[0...-1].to_sym) if m =~ /.*\?/
  
  # Is it an unknown to_ method? e.g. to_ary ... if so, fall through to default
  if m =~ /^to\_.*/
    super
    return
  end
  
  # Once we get past the special cases, check to see if we have the 
  # expected number of arguments. 
  if !args.length.within?(1..2)
    raise NoMethodError
    return
  end
  
  # Now we start to figure out the exact value to set
  transform, alias_for, checker = [:transform_,:alias_for_,:check_].map {|x| "#{x}#{m}".to_sym }
  
  v = args[0]
  
  # First, if the value given is a ASObj, call finish on it
  v = (v.is_a?(ASObj) ? v.finish : v) unless v == nil
  
  # If it's an Enumerable, but not a Hash, convert to an Array using Map,
  # If each of the member items are ASObj's call finish.
  v = v.map {|i| i.is_a?(ASObj) ? i.finish : i } if v.is_a?(Enumerable) && !v.is_a?(Hash)
  
  # If the value is a Time object, let's make sure it's ISO 8601
  v = v.iso8601 if v.is_a? Time
       
  # Finally, do the object_type specific transform, if any 
  # note, this could potentially undo the previous checks if 
  # the transform provided by a given spec module isn't well
  # behaved. that's ok tho, we'll trust that it's doing the
  # right thing and just move on ... we're going to be validating
  # next anyway
  v = send transform, v if method? transform
  
  # Now let's do validation... unless lenient is set
  if !args[1] && strict?
    ok = method?(checker) ? send(checker,v) : missing_check(v)
    raise ArgumentError unless ok
  end
  m = send alias_for if method? alias_for
  @_[m] = v unless v == nil
  @_.delete m if v == nil
end

Class Method Details

.from(other, *without, &block) ⇒ Object

Creates a new ASObj by copying from another one

Raises:

  • (ArgumentError)


373
374
375
376
377
378
379
380
381
# File 'lib/streams/activitystreams.rb', line 373

def from other, *without, &block
  raise ArgumentError unless other.one_of_type?(ASObj,Hash)
  m = ASObj.new other.__object_type
  m.pretty if other.pretty?
  m.lenient if other.lenient?
  other.finish.each_pair {|k,y| m[k] = y unless without.include? k }
  m.instance_eval &block unless not block_given?
  m.freeze
end

.generate(object_type = nil, do_not_set_object_type = false, &block) ⇒ Object

Performs the actual work of creating an ASObj and executing the associated block to build it up, then freezing the ASObj before returning it



365
366
367
368
369
370
# File 'lib/streams/activitystreams.rb', line 365

def generate object_type=nil, do_not_set_object_type=false, &block
  m = ASObj.new object_type
  m[:objectType] = object_type unless do_not_set_object_type
  m.instance_eval &block unless not block_given?
  m.freeze
end

Instance Method Details

#[](k) ⇒ Object



277
278
279
# File 'lib/streams/activitystreams.rb', line 277

def [] k
  @_[send("alias_for_#{k}".to_sym) || k]
end

#__object_typeObject

the internal object type identifier for this ASObj



247
248
249
# File 'lib/streams/activitystreams.rb', line 247

def __object_type 
  @object_type 
end

#append_to(out) ⇒ Object Also known as: >>

write this thing out, the param must repond to the << operator for appending

Raises:

  • (ArgumentError)


257
258
259
260
# File 'lib/streams/activitystreams.rb', line 257

def append_to out
  raise ArgumentError unless out.respond_to?:<<
  out << to_s
end

#copy_of(*without, &block) ⇒ Object

generates a copy of this object



269
270
271
# File 'lib/streams/activitystreams.rb', line 269

def copy_of *without, &block
  ASObj.from self, *without, &block
end

#finishObject

return a frozen copy of the internal hash



252
253
254
# File 'lib/streams/activitystreams.rb', line 252

def finish 
  @_.dup.freeze
end

#freezeObject



293
294
295
296
# File 'lib/streams/activitystreams.rb', line 293

def freeze
  @_.freeze
  super
end

#lenientObject

Puts this ASObj into lenient validation mode



217
218
219
# File 'lib/streams/activitystreams.rb', line 217

def lenient  
  @lenient = true   
end

#lenient?Boolean

true if this ASObj is operating in lenient mode

Returns:

  • (Boolean)


237
238
239
# File 'lib/streams/activitystreams.rb', line 237

def lenient? 
  @lenient          
end

#prettyObject

Tells this ASObj to generate formatted JSON output



227
228
229
# File 'lib/streams/activitystreams.rb', line 227

def pretty   
  @pretty = true    
end

#pretty?Boolean

true if this ASObj has been configured to generate formatted JSON output

Returns:

  • (Boolean)


232
233
234
# File 'lib/streams/activitystreams.rb', line 232

def pretty?  
  @pretty || false  
end

#pretty_to(out) ⇒ Object

force pretty printing



264
265
266
# File 'lib/streams/activitystreams.rb', line 264

def pretty_to out
  out << JSON.pretty_generate(@_)
end

#property(m, *args, &block) ⇒ Object Also known as: method_missing

Within the generator, any method call that has exactly one parameter will be turned into a member of the underlying hash



300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
# File 'lib/streams/activitystreams.rb', line 300

def property m, *args, &block

  # Return nil if it's looking for an unknown alias_for_* method
  return nil if m =~ /^alias\_for\_.*/
  
  # Special magic... if an unknown ? method is called, it's treated 
  # as a check against the internal hash to see if the given field
  # has been set. For instance, priority? will check to see if the 
  # priority field has been set
  return @_.has_key?(m.to_s[0...-1].to_sym) if m =~ /.*\?/
  
  # Is it an unknown to_ method? e.g. to_ary ... if so, fall through to default
  if m =~ /^to\_.*/
    super
    return
  end
  
  # Once we get past the special cases, check to see if we have the 
  # expected number of arguments. 
  if !args.length.within?(1..2)
    raise NoMethodError
    return
  end
  
  # Now we start to figure out the exact value to set
  transform, alias_for, checker = [:transform_,:alias_for_,:check_].map {|x| "#{x}#{m}".to_sym }
  
  v = args[0]
  
  # First, if the value given is a ASObj, call finish on it
  v = (v.is_a?(ASObj) ? v.finish : v) unless v == nil
  
  # If it's an Enumerable, but not a Hash, convert to an Array using Map,
  # If each of the member items are ASObj's call finish.
  v = v.map {|i| i.is_a?(ASObj) ? i.finish : i } if v.is_a?(Enumerable) && !v.is_a?(Hash)
  
  # If the value is a Time object, let's make sure it's ISO 8601
  v = v.iso8601 if v.is_a? Time
       
  # Finally, do the object_type specific transform, if any 
  # note, this could potentially undo the previous checks if 
  # the transform provided by a given spec module isn't well
  # behaved. that's ok tho, we'll trust that it's doing the
  # right thing and just move on ... we're going to be validating
  # next anyway
  v = send transform, v if method? transform
  
  # Now let's do validation... unless lenient is set
  if !args[1] && strict?
    ok = method?(checker) ? send(checker,v) : missing_check(v)
    raise ArgumentError unless ok
  end
  m = send alias_for if method? alias_for
  @_[m] = v unless v == nil
  @_.delete m if v == nil
end

#set(k, v) ⇒ Object Also known as: []=

Sets a value on the internal hash without any type checking if v is an instance of ASObj, finish will be called to get the frozen hash …



285
286
287
288
289
290
# File 'lib/streams/activitystreams.rb', line 285

def set k,v
  key = k.to_s.to_sym
  v = (v.is_a?(ASObj) ? v.finish : v) unless v == nil
  @_[key] = v unless v == nil
  @_.delete key if v == nil
end

#strictObject

Puts this ASObj into strict validation mode



222
223
224
# File 'lib/streams/activitystreams.rb', line 222

def strict   
  @lenient = false  
end

#strict?Boolean

true if this ASObj is operating in strict mode

Returns:

  • (Boolean)


242
243
244
# File 'lib/streams/activitystreams.rb', line 242

def strict?  
  !lenient?         
end

#to_sObject



273
274
275
# File 'lib/streams/activitystreams.rb', line 273

def to_s
  pretty? ? JSON.pretty_generate(@_) : @_.to_json
end