class ROBundle::Manifest
The manifest.json managed file entry for a Research Object.
Public Class Methods
Create a new managed file entry to represent the manifest.json file.
# 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 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 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 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 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
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
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
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
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
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
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
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
Has this manifest been initialized?
# File lib/ro-bundle/ro/manifest.rb 36 def initialized? 37 @initialized 38 end
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 (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
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 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 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
# 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
# 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
# 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
# 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
# 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
# File lib/ro-bundle/ro/manifest.rb 295 def stored 296 @edited = false 297 (aggregates + annotations).each { |a| a.stored } 298 end
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