class ROBundle::Manifest

The manifest.json managed file entry for a Research Object.

Public Class Methods

new click to toggle source

Create a new managed file entry to represent the manifest.json file.

Calls superclass method
   # File lib/ro-bundle/ro/manifest.rb
24 def initialize
25   super(FILE_NAME, :required => true)
26 
27   @structure = nil
28   @initialized = false
29   @edited = false
30 end

Public Instance Methods

add_aggregate(entry) → Aggregate click to toggle source
add_aggregate(uri) → Aggregate

Add the given entry or URI to the list of aggregates in this manifest. Errno:ENOENT is raised if the entry does not exist.

The Aggregate object added to the Research Object is returned.

    # File lib/ro-bundle/ro/manifest.rb
117 def add_aggregate(entry)
118   unless entry.instance_of?(Aggregate)
119     unless Util.is_absolute_uri?(entry)
120       raise Errno::ENOENT if container.find_entry(entry).nil?
121     end
122 
123     entry = Aggregate.new(entry)
124   end
125 
126   @edited = true
127   structure[:aggregates] << entry
128   entry
129 end
add_annotation(annotation) → Annotation click to toggle source
add_annotation(target, content = nil) → Annotation

Add an annotation to this Research Object. An annotation can either be an already created annotation object, or a pair of values to build a new annotation object explicitly.

Errno:ENOENT is raised if the target of the annotation is not an annotatable resource in this RO.

The Annotation object added to the Research Object is returned.

    # File lib/ro-bundle/ro/manifest.rb
170 def add_annotation(object, content = nil)
171   if object.instance_of?(Annotation)
172     # If the supplied Annotation object is already registered then it is
173     # the annotation itself we are annotating!
174     if container.annotation?(object)
175       object = Annotation.new(object.uri, content)
176     end
177   else
178     object = Annotation.new(object, content)
179   end
180 
181   target = object.target
182   unless container.annotatable?(target)
183     raise Errno::ENOENT,
184       "'#{target}' is not a member of this Research Object or a URI."
185   end
186 
187   @edited = true
188   structure[:annotations] << object
189   object
190 end
add_context click to toggle source

Add a URI to the front of the @context list.

   # File lib/ro-bundle/ro/manifest.rb
52 def add_context(uri)
53   @edited = true
54   structure[:@context].insert(0, uri.to_s)
55 end
add_history(entry) click to toggle source

Add the given entry to the history list in this manifest. Errno:ENOENT is raised if the entry does not exist.

   # File lib/ro-bundle/ro/manifest.rb
89 def add_history(entry)
90   raise Errno::ENOENT if container.find_entry(entry).nil?
91 
92   # Mangle the filename according to the RO Bundle specification.
93   name = entry_name(entry)
94   dir = "#{@parent.full_name}/"
95   name = name.start_with?(dir) ? name.sub(dir, "") : "/#{name}"
96 
97   @edited = true
98   structure[:history] << name
99 end
aggregates → List of aggregated resources. click to toggle source

Return a list of all the aggregated resources in this Research Object.

    # File lib/ro-bundle/ro/manifest.rb
105 def aggregates
106   structure[:aggregates]
107 end
annotations click to toggle source

Return a list of all the annotations in this Research Object.

    # File lib/ro-bundle/ro/manifest.rb
221 def annotations
222   structure[:annotations]
223 end
context → List of context URIs click to toggle source

Return the list of @context URIs for this Research Object manifest.

   # File lib/ro-bundle/ro/manifest.rb
44 def context
45   structure[:@context].dup
46 end
edited? → true or false click to toggle source

Has this manifest been altered in any way?

    # File lib/ro-bundle/ro/manifest.rb
229 def edited?
230   if @structure.nil?
231     @edited
232   else
233     @edited || edited(aggregates) || edited(annotations)
234   end
235 end
history → List of history entry names click to toggle source

Return a list of filenames that hold provenance information for this Research Object.

   # File lib/ro-bundle/ro/manifest.rb
80 def history
81   structure[:history].dup
82 end
id → String click to toggle source

An RO identifier (usually '/') indicating the relative top-level folder as the identifier.

   # File lib/ro-bundle/ro/manifest.rb
62 def id
63   structure[:id]
64 end
id = new_id click to toggle source

Set the id of this Manifest.

   # File lib/ro-bundle/ro/manifest.rb
70 def id=(new_id)
71   @edited = true
72   structure[:id] = new_id
73 end
initialized? → true or false click to toggle source

Has this manifest been initialized?

   # File lib/ro-bundle/ro/manifest.rb
36 def initialized?
37   @initialized
38 end
remove_aggregate(filename) click to toggle source
remove_aggregate(uri)
remove_aggregate(Aggregate)

Remove (unregister) an aggregate from this Research Object. If a filename is supplied then the file is no longer aggregated, but it is not deleted from the bundle by this method.

Any annotations with the removed aggregate as their target are also removed from the RO.

    # File lib/ro-bundle/ro/manifest.rb
142 def remove_aggregate(object)
143   removed = nil
144 
145   if object.is_a?(Aggregate)
146     removed = structure[:aggregates].delete(object)
147     removed = removed.uri unless removed.nil?
148   else
149     removed = remove_aggregate_by_uri(object)
150   end
151 
152   unless removed.nil?
153     remove_annotation(removed)
154     @edited = true
155   end
156 end
remove_annotation(Annotation) click to toggle source
remove_annotation(target)
remove_annotation(id)

Remove (unregister) annotations from this Research Object and return them. Return nil if the annotation does not exist.

Any annotation content that is stored in the .ro/annotations directory is automatically cleaned up when the RO is closed.

    # File lib/ro-bundle/ro/manifest.rb
202 def remove_annotation(object)
203   if object.is_a?(Annotation)
204     removed = [structure[:annotations].delete(object)].compact
205   else
206     removed = remove_annotation_by_field(object)
207   end
208 
209   removed.each do |ann|
210     id = ann.uri
211     remove_annotation(id) unless id.nil?
212   end
213 
214   @edited = true unless removed.empty?
215 end
to_json(options = nil) → String click to toggle source

Write this Manifest out as a json string. Takes the same options as JSON#generate.

    # File lib/ro-bundle/ro/manifest.rb
242 def to_json(*a)
243   JSON.generate(Util.clean_json(structure),*a)
244 end
write click to toggle source

Write this manifest into the RO Bundle, overwriting the old version.

    # File lib/ro-bundle/ro/manifest.rb
250 def write
251   container.file.open(full_name, "w") do |m|
252     m.puts JSON.pretty_generate(self)
253   end
254 
255   stored
256 end

Protected Instance Methods

validate → true or false click to toggle source

Validate the correctness of the manifest file contents.

    # File lib/ro-bundle/ro/manifest.rb
283 def validate
284   begin
285     structure
286   rescue JSON::ParserError, ROError
287     return false
288   end
289 
290   true
291 end

Private Instance Methods

edited(resource) click to toggle source
    # File lib/ro-bundle/ro/manifest.rb
366 def edited(resource)
367   resource.each do |res|
368     return true if res.edited?
369   end
370 
371   false
372 end
init_default_context(struct) click to toggle source
    # File lib/ro-bundle/ro/manifest.rb
316 def init_default_context(struct)
317   context = struct[:@context]
318   if context.nil?
319     @edited = true
320     struct[:@context] = [ DEFAULT_CONTEXT ]
321   else
322     struct[:@context] = [*context]
323   end
324 
325   struct
326 end
init_default_id(struct) click to toggle source
    # File lib/ro-bundle/ro/manifest.rb
328 def init_default_id(struct)
329   id = struct[:id]
330   if id.nil?
331     @edited = true
332     struct[:id] = DEFAULT_ID
333   end
334 
335   struct
336 end
remove_aggregate_by_uri(object) click to toggle source
    # File lib/ro-bundle/ro/manifest.rb
338 def remove_aggregate_by_uri(object)
339   structure[:aggregates].each do |agg|
340     if object == agg.uri || object == agg.file_entry
341       return structure[:aggregates].delete(agg).uri
342     end
343   end
344 
345   # Return nil if nothing removed.
346   nil
347 end
remove_annotation_by_field(object) click to toggle source
    # File lib/ro-bundle/ro/manifest.rb
349 def remove_annotation_by_field(object)
350   removed = []
351 
352   # Need to dup the list here so we don't break it when deleting things.
353   # We can't use delete_if because we want to know what we've deleted!
354   structure[:annotations].dup.each do |ann|
355     if ann.uri == object ||
356       ann.target == object ||
357       ann.content == object
358 
359       removed << structure[:annotations].delete(ann)
360     end
361   end
362 
363   removed
364 end
stored() click to toggle source
    # File lib/ro-bundle/ro/manifest.rb
295 def stored
296   @edited = false
297   (aggregates + annotations).each { |a| a.stored }
298 end
structure() click to toggle source

The internal structure of this class cannot be setup at construction time in the initializer as there is no route to its data on disk at that point. Once loaded, parts of the structure are converted to local objects where appropriate.

    # File lib/ro-bundle/ro/manifest.rb
304 def structure
305   return @structure if initialized?
306 
307   begin
308     struct ||= JSON.parse(contents, :symbolize_names => true)
309   rescue Errno::ENOENT
310     struct = {}
311   end
312 
313   init(struct)
314 end