moab-versioning 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/lib/moab.rb +59 -0
  3. data/lib/moab/bagger.rb +289 -0
  4. data/lib/moab/config.rb +21 -0
  5. data/lib/moab/exceptions.rb +18 -0
  6. data/lib/moab/file_group.rb +244 -0
  7. data/lib/moab/file_group_difference.rb +336 -0
  8. data/lib/moab/file_group_difference_subset.rb +45 -0
  9. data/lib/moab/file_instance.rb +82 -0
  10. data/lib/moab/file_instance_difference.rb +54 -0
  11. data/lib/moab/file_inventory.rb +279 -0
  12. data/lib/moab/file_inventory_difference.rb +132 -0
  13. data/lib/moab/file_manifestation.rb +85 -0
  14. data/lib/moab/file_signature.rb +200 -0
  15. data/lib/moab/signature_catalog.rb +195 -0
  16. data/lib/moab/signature_catalog_entry.rb +61 -0
  17. data/lib/moab/storage_object.rb +220 -0
  18. data/lib/moab/storage_object_version.rb +333 -0
  19. data/lib/moab/storage_repository.rb +57 -0
  20. data/lib/moab/storage_services.rb +104 -0
  21. data/lib/moab/verification_result.rb +83 -0
  22. data/lib/moab/version_metadata.rb +38 -0
  23. data/lib/moab/version_metadata_entry.rb +64 -0
  24. data/lib/moab/version_metadata_event.rb +47 -0
  25. data/lib/moab_stanford.rb +18 -0
  26. data/lib/monkey_patches.rb +65 -0
  27. data/lib/serializer.rb +36 -0
  28. data/lib/serializer/manifest.rb +76 -0
  29. data/lib/serializer/serializable.rb +178 -0
  30. data/lib/stanford/active_fedora_object.rb +34 -0
  31. data/lib/stanford/content_inventory.rb +236 -0
  32. data/lib/stanford/dor_metadata.rb +49 -0
  33. data/lib/stanford/storage_repository.rb +46 -0
  34. data/lib/stanford/storage_services.rb +66 -0
  35. data/lib/tasks/yard.rake +34 -0
  36. data/lib/tools/api_doc_generator.rb +396 -0
  37. data/lib/tools/spec_generator.rb +410 -0
  38. data/lib/tools/spec_generator_old.rb +49 -0
  39. metadata +252 -0
@@ -0,0 +1,49 @@
1
+ require 'moab_stanford'
2
+
3
+ module Stanford
4
+
5
+ # Stanford-specific utility methods for interfacing with DOR metadata files
6
+ #
7
+ # ====Data Model
8
+ # * <b>{DorMetadata} = utility methods for interfacing with Stanford metadata files (esp contentMetadata)</b>
9
+ # * {ContentInventory} [1..1] = utilities for transforming contentMetadata to versionInventory and doing comparsions
10
+ # * {ActiveFedoraObject} [1..*] = utility for extracting content or other information from a Fedora Instance
11
+ #
12
+ # @note Copyright (c) 2012 by The Board of Trustees of the Leland Stanford Junior University.
13
+ # All rights reserved. See {file:LICENSE.rdoc} for details.
14
+ class DorMetadata
15
+
16
+ # @return [String] The digital object identifier (druid)
17
+ attr_accessor :digital_object_id
18
+
19
+ # @return [Integer] \@versionId = The ordinal version number
20
+ attr_accessor :version_id
21
+
22
+ # @param digital_object_id [String] The digital object identifier
23
+ # @param version_id [Integer] The ordinal version number
24
+ # @return [Stanford::DorMetadata]
25
+ def initialize(digital_object_id, version_id=nil)
26
+ @digital_object_id = digital_object_id
27
+ @version_id = version_id
28
+ end
29
+
30
+ # @api internal
31
+ # @param directory [String] The location of the directory to be inventoried
32
+ # @param version_id (see #initialize)
33
+ # @return [FileInventory] Inventory of the files under the specified directory
34
+ def inventory_from_directory(directory, version_id=nil)
35
+ version_id ||= @version_id
36
+ version_inventory = FileInventory.new(:type=>'version',:digital_object_id=>@digital_object_id, :version_id=>version_id)
37
+ content_metadata = IO.read(File.join(directory,'contentMetadata.xml'))
38
+ content_group = ContentInventory.new.group_from_cm(content_metadata, 'preserve' )
39
+ version_inventory.groups << content_group
40
+ metadata_group = FileGroup.new(:group_id=>'metadata').group_from_directory(directory)
41
+ version_inventory.groups << metadata_group
42
+ version_inventory
43
+ end
44
+
45
+
46
+
47
+ end
48
+
49
+ end
@@ -0,0 +1,46 @@
1
+ require 'moab_stanford'
2
+
3
+ module Stanford
4
+
5
+ # A class to represent the SDR repository store
6
+ #
7
+ # ====Data Model
8
+ # * <b>{StorageRepository} = represents a digital object repository storage node</b>
9
+ #
10
+ # @note Copyright (c) 2012 by The Board of Trustees of the Leland Stanford Junior University.
11
+ # All rights reserved. See {file:LICENSE.rdoc} for details.
12
+ class StorageRepository < Moab::StorageRepository
13
+
14
+ # @param object_id [String] The identifier of the digital object whose version is desired
15
+ # @return [Pathname] The location of the desired object's home directory
16
+ def storage_object_pathname(object_id)
17
+ case Moab::Config.path_method.to_s
18
+ when 'druid_tree'
19
+ repository_home.join(druid_tree(object_id))
20
+ when 'druid'
21
+ repository_home.join(object_id.split(/:/)[-1])
22
+ end
23
+ end
24
+
25
+ # @param object_id [String] The identifier of the digital object whose path is requested
26
+ # @return [String] the druid tree directory path based on the given object identifier.
27
+ def druid_tree(object_id)
28
+ syntax_msg = "Identifier has invalid suri syntax: #{object_id}"
29
+ raise syntax_msg + "nil or empty" if object_id.to_s.empty?
30
+ identifier = object_id.split(':')[-1]
31
+ raise syntax_msg if identifier.to_s.empty?
32
+ # The object identifier must be in the SURI format, otherwise an exception is raised:
33
+ # e.g. druid:aannnaannnn or aannnaannnn
34
+ # where 'a' is an alphabetic character
35
+ # where 'n' is a numeric character
36
+ if identifier =~ /^([a-z]{2})(\d{3})([a-z]{2})(\d{4})$/
37
+ return File.join( $1, $2, $3, $4, identifier)
38
+ else
39
+ raise syntax_msg
40
+ end
41
+ end
42
+
43
+
44
+ end
45
+
46
+ end
@@ -0,0 +1,66 @@
1
+ require 'moab_stanford'
2
+
3
+ module Stanford
4
+
5
+ # An interface class to support access to SDR storage via a RESTful server
6
+ class StorageServices < Moab::StorageServices
7
+
8
+ # @return [StorageRepository] an instance of the interface to SDR storage
9
+ @@repository = Stanford::StorageRepository.new
10
+
11
+ # @param new_content_metadata [String] The content metadata to be compared to the base
12
+ # @param object_id [String] The digital object identifier of the object whose version inventory is the basis of the comparison
13
+ # @param subset [String] Speciifes which subset of files to list in the inventories extracted from the contentMetadata (all|preserve|publish|shelve)
14
+ # @param base_version [Integer] The ID of the version whose inventory is the basis of, if nil use latest version
15
+ # @return [FileInventoryDifference] The report of differences between the content metadata and the specified version
16
+ def self.compare_cm_to_version(new_content_metadata, object_id, subset, base_version=nil)
17
+ new_inventory = ContentInventory.new.inventory_from_cm(new_content_metadata, object_id, subset)
18
+ begin
19
+ # ObjectNotFoundException is raised if the object does not exist in storage
20
+ base_version ||= self.current_version(object_id)
21
+ # FileNotFoundException is raised if object exists but has no contentMetadata file
22
+ base_cm_pathname = self.retrieve_file('metadata', 'contentMetadata.xml', object_id, base_version)
23
+ base_inventory = ContentInventory.new.inventory_from_cm(base_cm_pathname.read, object_id, subset, base_version)
24
+ rescue Moab::ObjectNotFoundException, Moab::FileNotFoundException
25
+ # Create a skeletal FileInventory object, containing no file entries
26
+ storage_object = StorageObject.new(object_id, 'dummy')
27
+ base_version = StorageObjectVersion.new(storage_object,0)
28
+ base_inventory = base_version.file_inventory('version')
29
+ end
30
+ diff = FileInventoryDifference.new.compare(base_inventory, new_inventory)
31
+ metadata_diff = diff.group_difference('metadata')
32
+ diff.group_differences.delete(metadata_diff) if metadata_diff
33
+ diff
34
+ end
35
+
36
+ # @param new_content_metadata [String] The content metadata to be compared to the current signtature catalog
37
+ # @param object_id [String] The digital object identifier of the object whose signature catalog is to be used
38
+ # @param version_id [Integer] The ID of the version whose signature catalog is to be used, if nil use latest version
39
+ # @return [FileInventory] The versionAddtions report showing which files are new or modified in the content metadata
40
+ def self.cm_version_additions(new_content_metadata, object_id, version_id=nil)
41
+ new_inventory = ContentInventory.new.inventory_from_cm(new_content_metadata, object_id, 'preserve')
42
+ begin
43
+ # ObjectNotFoundException is raised if the object does not exist in storage
44
+ version_id ||= self.current_version(object_id)
45
+ storage_object_version = @@repository.storage_object(object_id).find_object_version(version_id)
46
+ signature_catalog = storage_object_version.signature_catalog
47
+ rescue Moab::ObjectNotFoundException
48
+ storage_object = StorageObject.new(object_id, 'dummy')
49
+ base_version = StorageObjectVersion.new(storage_object,0)
50
+ signature_catalog = base_version.signature_catalog
51
+ end
52
+ signature_catalog.version_additions(new_inventory)
53
+ end
54
+
55
+ # @param object_id [String] The digital object identifier of the object whose contentMetadata is to be remediated
56
+ # @param version_id [Integer] The ID of the version whose file data is to be used, if nil use latest version
57
+ # @return [String] Returns a remediated copy of the contentMetadata with fixity data filled in
58
+ def self.cm_remediate(object_id, version_id=nil)
59
+ cm = self.retrieve_file('metadata', 'contentMetadata.xml', object_id, version_id)
60
+ group = self.retrieve_file_group('content', object_id, version_id)
61
+ ContentInventory.new.remediate_content_metadata(cm,group)
62
+ end
63
+
64
+ end
65
+
66
+ end
@@ -0,0 +1,34 @@
1
+ desc "Generate RDoc"
2
+ task :doc => ['doc:generate']
3
+
4
+ namespace :doc do
5
+ project_root = File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
6
+ doc_destination = File.join(project_root, 'doc')
7
+
8
+ begin
9
+ require 'yard'
10
+ require 'yard/rake/yardoc_task'
11
+
12
+ YARD::Rake::YardocTask.new(:generate) do |yt|
13
+ yt.files = Dir.glob(File.join(project_root, 'lib', '*.rb')) +
14
+ Dir.glob(File.join(project_root, 'lib', 'serializer', '*.rb')) +
15
+ Dir.glob(File.join(project_root, 'lib', 'moab', '*.rb')) +
16
+ Dir.glob(File.join(project_root, 'lib', 'stanford', '*.rb')) +
17
+ ['-'] +
18
+ [ File.join(project_root, 'LICENSE.rdoc') ]
19
+
20
+ yt.options = ['--output-dir', doc_destination, '--hide-void-return']
21
+ end
22
+ rescue LoadError
23
+ desc "Generate YARD Documentation"
24
+ task :generate do
25
+ abort "Please install the YARD gem to generate rdoc."
26
+ end
27
+ end
28
+
29
+ desc "Remove generated documentation"
30
+ task :clean do
31
+ rm_r doc_destination if File.exists?(doc_destination)
32
+ end
33
+
34
+ end
@@ -0,0 +1,396 @@
1
+ #$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', '..', 'lib'))
2
+ require 'rubygems'
3
+ require 'hashery/orderedhash'
4
+ require 'pathname'
5
+ require 'yard'
6
+ include YARD
7
+ require 'moab_stanford'
8
+ include Serializer
9
+ include Moab
10
+ include Stanford
11
+
12
+ class String
13
+ def snake_case
14
+ self.gsub(/::/, '/').
15
+ gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
16
+ gsub(/([a-z\d])([A-Z])/, '\1_\2').
17
+ tr("-", "_").
18
+ downcase
19
+ end
20
+ end
21
+
22
+ class Symbol
23
+ def snake_case
24
+ self.to_s.snake_case
25
+ end
26
+ end
27
+
28
+ class ApiClass
29
+ attr_accessor :class_name
30
+ attr_accessor :yard_class
31
+ attr_accessor :mhash
32
+ attr_accessor :ruby_class
33
+ attr_accessor :xml_tag
34
+ attr_accessor :description
35
+ attr_accessor :model
36
+
37
+ def self.class_hash=(class_hash)
38
+ @@class_hash = class_hash
39
+ end
40
+
41
+ def self.rootpath=(rootpath)
42
+ @@rootpath = rootpath
43
+ end
44
+
45
+ def initialize(class_name)
46
+ @class_name = class_name
47
+ @yard_class = @@class_hash[class_name]
48
+ if yard_class.nil?
49
+ raise "class_hash[#{class_name}] is Nil"
50
+ end
51
+ @mhash = categorize_members(@yard_class)
52
+ if @yard_class.path.include?('::')
53
+ ruby_module = Object::const_get(yard_class.path.split(/::/)[0])
54
+ @ruby_class = ruby_module.const_get(yard_class.name)
55
+ else
56
+ @ruby_class = Object::const_get(yard_class.path)
57
+ end
58
+
59
+ if @ruby_class.respond_to?(:tag_name)
60
+ @xml_tag = "<#{ruby_class.tag_name}>"
61
+ else
62
+ @xml_tag = '-'
63
+ end
64
+ docstring_all = confluence_translate(yard_class.docstring.all.split(/@/)[0])
65
+ docstring_parts = docstring_all.split(/h4. Data Model\n/)
66
+ @description = docstring_parts[0]
67
+ @model = docstring_parts.size > 1 ? docstring_parts[1] : nil
68
+ end
69
+
70
+ def categorize_members(yard_class)
71
+ mhash = {
72
+ :class_attributes => OrderedHash.new,
73
+ :instance_attributes => OrderedHash.new,
74
+ :class_methods => Array.new,
75
+ :instance_methods => Array.new
76
+ }
77
+ yard_class.children.each do |member|
78
+ attr_symbol = member.name.to_s.gsub(/=$/, '').to_sym
79
+ if member.name == :initialize
80
+ mhash[:constructor] = member
81
+ elsif yard_class.class_attributes[attr_symbol]
82
+ mhash[:class_attributes][attr_symbol] = yard_class.class_attributes[attr_symbol]
83
+ elsif yard_class.instance_attributes[attr_symbol]
84
+ mhash[:instance_attributes][attr_symbol] = yard_class.instance_attributes[attr_symbol]
85
+ elsif member.scope == :class
86
+ mhash[:class_methods] << member
87
+ elsif member.scope == :instance
88
+ mhash[:instance_methods] << member
89
+ end
90
+ end
91
+ mhash
92
+ end
93
+
94
+ def title
95
+ title = "\n{anchor:#{yard_class.name}}\n"
96
+ title << "h3. Class #{yard_class.path}"
97
+ title
98
+ end
99
+
100
+ def description
101
+ description = "\nh4. Description\n\n"
102
+ description << @description
103
+ description
104
+ end
105
+
106
+ def model
107
+ model = "\nh4. Data Model\n\n"
108
+ model << @model
109
+ model
110
+ end
111
+
112
+ def xml_example
113
+ xml_example = String.new
114
+ if yard_class.docstring.has_tag?('example')
115
+ xml_example << "\nh4. XML Example\n"
116
+ xml_example << "{code:lang=xml}\n"
117
+ filename = yard_class.docstring.tag('example').name.split(/[:)}]/)[2]
118
+ example = IO.read(File.join(@@rootpath, filename))
119
+ xml_example << example
120
+ xml_example << "{code}\n"
121
+ end
122
+ xml_example
123
+ end
124
+
125
+ def instance_attributes_table(mode=:all)
126
+ table = String.new
127
+ table << "\\\\\n||XML Element||Ruby Class||Inherits From||\n"
128
+ table << "|#{xml_tag}|[##{class_name}]|#{yard_class.superclass}|\n"
129
+ table << "\\\\\n||XML Child Node||Ruby Attribute||Data Type||Description||\n"
130
+ xml_names = xml_name_hash
131
+ @mhash[:instance_attributes].values.each do |attribute|
132
+ read = attribute[:read]
133
+ return_tag = read.docstring.tag(:return)
134
+ ruby_name = read.name.to_s
135
+ xml_name = xml_names[ruby_name] ? xml_names[ruby_name] : "-"
136
+ data_type = return_tag.types[0]
137
+ description = confluence_translate(return_tag.text.gsub(/\n/, ' '))
138
+ table_row = "|#{xml_name}|#{ruby_name}|#{data_type}|#{description.gsub(/\|/, '\\|')}|\n"
139
+ case mode
140
+ when :xml
141
+ if xml_name != '-'
142
+ table << table_row
143
+ end
144
+ when :ruby
145
+ if xml_name == '-'
146
+ table << table_row
147
+ end
148
+ else
149
+ table << table_row
150
+ end
151
+ end
152
+ table
153
+ end
154
+
155
+ def xml_name_hash
156
+ xml_name_hash = Hash.new
157
+ if @ruby_class.respond_to?(:attributes)
158
+ @ruby_class.attributes.each do |attribute|
159
+ xml_name_hash[attribute.name.to_s] = "@#{attribute.tag}"
160
+ end
161
+ end
162
+ if @ruby_class.respond_to?(:elements)
163
+ @ruby_class.elements.each do |element|
164
+ if element.options.size == 0 or element.options[:single]
165
+ xml_name_hash[element.name.to_s] = "<#{element.tag}>"
166
+ else
167
+ xml_name_hash[element.name.to_s] = "<#{element.tag}> \\[1..\\*]"
168
+ end
169
+ end
170
+ end
171
+ xml_name_hash
172
+ end
173
+
174
+ def methods_documentation
175
+
176
+ methods_documentation = String.new
177
+
178
+ #methods_documentation ""
179
+ #methods_documentation "h4. Constructor"
180
+ #method = mhash[:constructor]
181
+ #methods_documentation_method(method, yard_class) if method
182
+
183
+ methods =mhash[:class_methods]
184
+ if methods.size > 0
185
+ methods_documentation << "\nh4. Class Methods\n"
186
+ methods.each do |method|
187
+ methods_documentation << method_documentation(method)
188
+ end
189
+ end
190
+
191
+ methods =mhash[:instance_methods]
192
+ if methods.size > 0
193
+ public_methods = Array.new
194
+ methods.each do |method|
195
+ if method.docstring.has_tag?(:api) && method.docstring.tag(:api).text == 'external'
196
+ public_methods << method
197
+ end
198
+ end
199
+ if public_methods.size > 0
200
+ methods_documentation << "\nh4. Instance Methods\n"
201
+ public_methods.each do |method|
202
+ methods_documentation << method_documentation(method)
203
+ end
204
+ end
205
+ end
206
+ methods_documentation
207
+ end
208
+
209
+ def method_documentation(method)
210
+
211
+ method_documentation = String.new
212
+ if method.nil?
213
+ raise "method is nil"
214
+ end
215
+ method_documentation << "\nh5. #{method.path}\n"
216
+
217
+ method_documentation << "||Method||Return Type||Description||\n"
218
+ if method.name == :initialize
219
+ return_type = @yard_class.name
220
+ description = 'constructor'
221
+ else
222
+ return_tag = method.docstring.tag(:return)
223
+ if return_tag.nil?
224
+ raise "#{method.name} return tag is nil"
225
+ end
226
+ return_type = return_tag.types[0]
227
+ description = confluence_translate(return_tag.text.gsub(/\n/, ' '))
228
+ end
229
+ method_documentation << "|#{method.name}|#{return_type}|#{example.description}|\n"
230
+
231
+ if method.respond_to?(:docstring)
232
+ params = method.docstring.tags(:param)
233
+ if params && params.size > 0
234
+ method_documentation << "\n||Parameter||Data Type||Description||\n"
235
+ params.each do |p|
236
+ description = confluence_translate(p.text.gsub(/\n/, ' '))
237
+ method_documentation << "|#{p.name}|#{p.types.join(', ')}|#{example.description}|\n"
238
+ end
239
+ end
240
+ end
241
+
242
+ method_documentation << "{code:lang=none|title=Ruby Source Code}\n"
243
+ method_documentation << method.source
244
+ method_documentation << "{code}\n"
245
+
246
+ if method.docstring.has_tag?('example')
247
+ method_documentation << "\n{code:lang=none|title=Usage Example}\n"
248
+ filename = method.docstring.tag('example').name.split(/[:)}]/)[2]
249
+ example = IO.read(File.join(@@rootpath, filename))
250
+ method_documentation << example
251
+ method_documentation << "{code}\n"
252
+ end
253
+ method_documentation
254
+ end
255
+
256
+ def confluence_translate(input)
257
+ map = OrderedHash.new
258
+ map[/\|/] = "\\|"
259
+ map[/====/] = "h4. "
260
+ map[/\*/] = "\\*"
261
+ map[/\n\s{6}\\\*\s/] = "\n****\s"
262
+ map[/\n\s{4}\\\*\s/] = "\n***\s"
263
+ map[/\n\s{2}\\\*\s/] = "\n**\s"
264
+ map[/\n\\\*\s/] = "\n*\s"
265
+ map[/<[\/]*b>/] = "*"
266
+ map[/<[\/]*i>/] = "_"
267
+ map[/\[/] = "\\["
268
+ map[/\{#/] = "[#"
269
+ map[/\{http/] = "[http"
270
+ map[/\{/] = "[#"
271
+ map[/\}/] = "]"
272
+ output = input
273
+ map.each do |regex, replacement|
274
+ output.gsub!(regex, replacement)
275
+ end
276
+ output
277
+ end
278
+
279
+ end
280
+
281
+
282
+ class ApiDoc < ApiClass
283
+ attr_accessor :ios
284
+ attr_accessor :classes
285
+
286
+ def process_doc(ios)
287
+ @ios = ios
288
+ parse_model
289
+
290
+ output component
291
+ output model
292
+ output description
293
+ output xml_example
294
+ output xml_nodes
295
+ classes_detail
296
+ end
297
+
298
+ def component
299
+ component = "h2. Component: #{yard_class.name}\n"
300
+ component
301
+ end
302
+
303
+ def xml_nodes
304
+ nodes = "\nh4. XML Nodes\n"
305
+ @classes.each do |cls|
306
+ nodes << cls.instance_attributes_table(mode=:xml)
307
+ end
308
+ nodes
309
+ end
310
+
311
+ def classes_detail
312
+ @classes.each do |cls|
313
+ output cls.title
314
+ output cls.description if cls != self
315
+ output cls.methods_documentation
316
+ end
317
+ end
318
+
319
+ def parse_model
320
+ @classes = Array.new
321
+ @classes << self
322
+ if @model
323
+ model.lines.each do |line|
324
+ matches = line.scan(/\[#(.*)?\]/)
325
+ if matches.size > 0
326
+ match = matches[0][0].split(/\]/)[0]
327
+ if match != class_name
328
+ @classes << ApiClass.new(match)
329
+ end
330
+ end
331
+ end
332
+ end
333
+
334
+ end
335
+
336
+ def output(string)
337
+ @ios.puts string
338
+ end
339
+
340
+
341
+ end
342
+
343
+
344
+ class DocGenerator
345
+
346
+ def initialize(rootpath)
347
+ @rootpath = rootpath
348
+ end
349
+
350
+ def generate_docs(apis)
351
+ temp_pathname = Pathname(@rootpath).join('api', 'temp')
352
+ ApiClass.class_hash = get_class_hash
353
+ ApiClass.rootpath = @rootpath
354
+ apis.each do |api_name|
355
+ doc_pathname = temp_pathname.join(api_name + "_confluence.txt")
356
+ doc_pathname.parent.mkpath
357
+ #puts doc_pathname.to_s
358
+ #unless doc_pathname.exist?
359
+ begin
360
+ @constructor_params = Array.new
361
+ @indent = 0
362
+ ios = doc_pathname.open("w")
363
+ api_doc = ApiDoc.new(api_name)
364
+ api_doc.process_doc(ios)
365
+ ensure
366
+ ios.close
367
+ end
368
+ #end
369
+ end
370
+ end
371
+
372
+ def get_class_hash()
373
+ class_hash = Hash.new
374
+ yardoc = File.join(@rootpath, '.yardoc')
375
+ Registry.load!(yardoc) # loads all objects into memory
376
+ class_array = Registry.all(:class) # Array
377
+ class_array.each do |cls|
378
+ class_hash[cls.name.to_s] = cls
379
+ end
380
+ class_hash
381
+ end
382
+
383
+ end
384
+
385
+ apis = Array.new
386
+ apis << 'FileInventory'
387
+ apis << 'SignatureCatalog'
388
+ apis << 'FileInventoryDifference'
389
+ apis << 'VersionMetadata'
390
+ apis << 'Serializable'
391
+ apis << 'StorageObject'
392
+ apis << 'StorageRepository'
393
+ apis << 'DorMetadata'
394
+
395
+ sg = DocGenerator.new(File.expand_path(File.join(File.dirname(__FILE__), '..', '..')))
396
+ sg.generate_docs(apis)