class Fedora::Repository
def self.flush
def self.flush Thread.current[:repo]=nil end
def self.instance
def self.instance raise "did you register a repo?" unless Thread.current[:repo] Thread.current[:repo] end
def self.register(url, surrogate=nil)
def self.register(url, surrogate=nil) url = url.to_s.chop if url.to_s =~ /\/\Z/ Thread.current[:repo]= Fedora::Repository.new(url, surrogate) begin repo = Thread.current[:repo] attributes = repo.describe_repository repo.repository_name = attributes["repositoryName"].first repo.base_url = attributes["repositoryBaseURL"].first repo.fedora_version = attributes["repositoryVersion"].first repo.pid_namespace = attributes["repositoryPID"].first["PID-namespaceIdentifier"].first repo.pid_delimiter = attributes["repositoryPID"].first["PID-delimiter"].first rescue end Thread.current[:repo] end
def connection(refresh = false)
The +refresh+ parameter toggles whether or not the connection is refreshed at every request
Low level access to the remote fedora server
def connection(refresh = false) if refresh || @connection.nil? @connection = Fedora::Connection.new(@fedora_url, Fedora::XmlFormat, @surrogate) end @connection end
def convert_xml(response)
def convert_xml(response) results = FedoraObjects.new return results unless response && response['resultList'] results.session_token = response['listSession']['token'] if response['listSession'] objectFields = response['resultList']['objectFields'] case objectFields when Array objectFields.each { |attrs| results << FedoraObject.new(attrs.rekey!) } when Hash results << FedoraObject.new(objectFields.rekey!) end results.each {|result| result.new_object = false} results end
def create(object)
def create(object) case object when Fedora::FedoraObject pid = (object.pid ? object : 'new') response = connection.post("#{url_for(pid)}?" + object.attributes.to_fedora_query, object.blob) if response.code == '201' object.pid = extract_pid(response) object.new_object = false true else false end when Fedora::Datastream raise ArgumentError, "Missing dsID attribute" if object.dsid.nil? extra_headers = {} extra_headers['Content-Type'] = object.attributes[:mimeType] if object.attributes[:mimeType] response = connection.post("#{url_for(object)}?" + object.attributes.to_fedora_query, object.blob, extra_headers) if response.code == '201' object.new_object = false true else false end else raise ArgumentError, "Unknown object type" end end
def delete(object)
boolean:: whether the operation is successful
== Return
This can be a uri String ("demo:1", "fedora:info/demo:1") or any object that responds uri method.
object
def delete(object) raise ArgumentError, "Object must not be nil" if object.nil? response = connection.delete("#{url_for(object)}") response.code == '200' or response.code == '204' # Temporary hack around error in Fedora 3.0 Final's REST API end
def describe_repository
def describe_repository result_body = connection.raw_get("#{fedora_url.path}/describe?xml=true").body XmlSimple.xml_in(result_body) end
def export(object, extra_params={})
extra_params
method
object
== Parameters
Export the given object
def export(object, extra_params={}) extra_params = {:format=>:foxml, :context=>:archive}.merge!(extra_params) if extra_params[:format].kind_of?(String) format = extra_params[:format] else format = case extra_params[:format] when :atom then "info:fedora/fedora-system:ATOM-1.1" when :atom_zip then "info:fedora/fedora-system:ATOMZip-1.1" when :mets then "info:fedora/fedora-system:METSFedoraExt-1.1" when :foxml then "info:fedora/fedora-system:FOXML-1.1" else "info:fedora/fedora-system:FOXML-1.1" end end fetch_custom(object, "export", :format=>format, :context=>extra_params[:context].to_s) end
def extract_pid(response)
def extract_pid(response) CGI.unescape(response['Location'].split('/').last) end
def fetch_content(object_uri)
def fetch_content(object_uri) response = connection.raw_get("#{url_for(object_uri)}?format=xml") StringResponse.new(response.body, response.content_type) end
def fetch_custom(object, method, extra_params = { :format => 'xml' })
This method returns raw xml response from the server
== Returns
extra_params
method
object
== Parameters
such as profile, versions, etc...
Fetch the given object using custom method. This is used to fetch other aspects of a fedora object,
def fetch_custom(object, method, extra_params = { :format => 'xml' }) path = case method when :profile then "" else "/#{method}" end extra_params.delete(:format) if method == :export connection.raw_get("#{url_for(object)}#{path}?#{extra_params.to_fedora_query}").body end
def find_model(pid, klazz)
def find_model(pid, klazz) obj = self.find_objects("pid=#{pid}").first doc = REXML::Document.new(obj.object_xml, :ignore_whitespace_nodes=>:all) klazz.deserialize(doc) end
def find_objects(*args)
find_objects("label=Image1", :include => [:label])
find_objects("label=Image1", :include => :all)
find_objects("pid~demo:*", "label=test")
find_objects("label=Image1")
== Examples
The field "pid" is always included.
select
limit
== Options
options
query
== Parameters
Find fedora objects with http://www.fedora.info/wiki/index.php/API-A-Lite_findObjects
def find_objects(*args) raise ArgumentError, "Missing query string" unless args.length >= 1 options = args.last.is_a?(Hash) ? args.pop : {} fields = options[:select] fields = (fields.nil? || (fields == :all)) ? ALL_FIELDS : ([:pid] + ([fields].flatten! - [:pid])) query = args.join(' ') params = { :resultFormat => 'xml', :query => query } params[:maxResults] = options[:limit] if options[:limit] params[:sessionToken] = options[:sessionToken] if options[:sessionToken] includes = fields.inject("") { |s, f| s += "&#{f}=true"; s } convert_xml(connection.get("#{fedora_url.path}/objects?#{params.to_fedora_query}#{includes}")) end
def ingest(content_to_ingest, extra_params={})
def ingest(content_to_ingest, extra_params={}) if extra_params[:pid] url = url_for(extra_params[:pid]) else url = url_for("new") end if content_to_ingest.kind_of?(File) content_to_ingest = content_to_ingest.read end connection.post(url,content_to_ingest) end
def initialize(fedora_url, surrogate=nil)
def initialize(fedora_url, surrogate=nil) @fedora_url = fedora_url.is_a?(URI) ? fedora_url : URI.parse(fedora_url) @surrogate = surrogate @connection = nil end
def nextid
def nextid d = REXML::Document.new(connection.post(fedora_url.path+"/management/getNextPID?xml=true").body) d.elements['//pid'].text end
def save(object)
boolean:: whether the operation is successful
== Return
Create the given object if it's new (not obtained from a find method). Otherwise update the object.
def save(object) object.new_object? ? create(object) : update(object) end
def update(object)
boolean:: whether the operation is successful
== Return
Update the given object
def update(object) raise ArgumentError, "Missing pid attribute" if object.nil? || object.pid.nil? case object when Fedora::FedoraObject response = connection.put("#{url_for(object)}?" + object.attributes.to_fedora_query) response.code == '200' || '307' when Fedora::Datastream raise ArgumentError, "Missing dsID attribute" if object.dsid.nil? response = connection.put("#{url_for(object)}?" + object.attributes.to_fedora_query, object.blob) response.code == '200' || '201' return response.code else raise ArgumentError, "Unknown object type" end end
def url_for(object)
def url_for(object) uri = object.respond_to?(:uri) ? object.uri : object.to_s uri = (uri[0..NAMESPACE.length-1] == NAMESPACE ? uri[NAMESPACE.length..-1] : uri) # strip of fedora:info namespace "#{fedora_url.path}/objects/#{uri}" end