app/helpers/api_helper.rb
# BioCatalogue: app/helpers/api_helper.rb
#
# Copyright (c) 2008-2009, University of Manchester, The European Bioinformatics
# Institute (EMBL-EBI) and the University of Southampton.
# See license.txt for details.
module ApiHelper
def xml_root_attributes
{ "xmlns" => "http://www.sysmo-db.org/2010/xml/rest",
"xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
"xsi:schemaLocation" => "http://www.sysmo-db.org/2010/xml/rest/schema-v1.xsd",
"xmlns:xlink" => "http://www.w3.org/1999/xlink",
"xmlns:dc" => "http://purl.org/dc/elements/1.1/",
"xmlns:dcterms" => "http://purl.org/dc/terms/" }
end
def uri_for_path(path, *args)
Seek::Api.uri_for_path(path, *args)
end
def api_partial_path_for_item object
Seek::Api.api_partial_path_for_item(object)
end
def uri_for_collection(resource_name, *args)
Seek::Api.uri_for_collection(resource_name, *args)
end
def uri_for_object(resource_obj, *args)
Seek::Api.uri_for_object(resource_obj, *args)
end
def previous_link_xml_attributes(resource_uri)
xlink_attributes(resource_uri, :title => xlink_title("Previous page of results"))
end
def next_link_xml_attributes(resource_uri)
xlink_attributes(resource_uri, :title => xlink_title("Next page of results"))
end
def assay_type_xlink assay
xlink = xlink_attributes(assay.assay_type_uri)
xlink["xlink:title"] = assay.assay_type_label
xlink["resourceType"] = "AssayType"
xlink
end
def technology_type_xlink assay
xlink = xlink_attributes(assay.technology_type_uri)
xlink["xlink:title"] = assay.technology_type_label
xlink["resourceType"] = "TechnologyType"
xlink
end
def core_xlink object,include_title=true
if (object.class.name.include?("::Version"))
xlink=xlink_attributes(uri_for_object(object.parent,{:params=>{:version=>object.version}}))
else
xlink=xlink_attributes(uri_for_object(object))
end
xlink["xlink:title"]=xlink_title(object) unless !include_title || display_name(object,false).nil?
xlink["id"]=object.id
xlink["uuid"]=object.uuid if object.respond_to?("uuid")
xlink["resourceType"] = object.class.name.include?("::Version") ? object.parent.class.name : object.class.name
return xlink
end
#requires a slightly different handling to core_xlink because the route is nested
def avatar_xlink avatar
return {"xsi:nil"=>"true"} if avatar.nil?
uri=uri_for_object(avatar.owner)
uri="#{uri}/avatars/#{avatar.id}"
xlink=xlink_attributes(uri)
xlink["id"]=avatar.id
xlink["resourceType"]=avatar.class.name
return xlink
end
def xlink_attributes(resource_uri, *args)
attribs = { }
attribs_in = args.extract_options!
attribs["xlink:href"] = resource_uri
attribs_in.each do |k,v|
attribs["xlink:#{k.to_s}"] = v
end
return attribs
end
def xlink_title(item, item_type_name=nil)
case item
when String
return item
else
if item_type_name.blank?
item_type_name = case item
when User
"User"
else
if (item.class.name.include?("::Version"))
item.parent.class.name
else
item.class.name
end
end
end
"#{display_name(item, false)}"
end
end
def display_name item,escape_html=false
result = nil
result = item.title if item.respond_to?("title")
result = item.name if item.respond_to?("name") && result.nil?
result = h(result) if escape_html && !result.nil?
return result
end
def dc_xml_tag(builder, term, value)
builder.tag! "dc:#{term}", value
end
def dcterms_xml_tag(builder, term, value)
# For dates...
if [ :created, :modified, "created", "modified" ].include?(term)
value = value.iso8601
end
builder.tag! "dcterms:#{term}", value
end
def core_xml builder,object
builder.tag! "id",object.id
dc_core_xml builder,object
builder.tag! "uuid",object.uuid if object.respond_to?("uuid")
end
def extended_xml builder,object
submitter = determine_submitter object
builder.tag! "submitter" do
api_partial(builder,submitter)
end if submitter
builder.tag! "organisms" do
organisms=[]
organisms=object.organisms if object.respond_to?("organisms")
organisms << object.organism if object.respond_to?("organism") && object.organism
api_partial_collection builder,organisms
end if object.respond_to?("organism") || object.respond_to?("organisms")
builder.tag! "creators" do
api_partial_collection builder,(object.creators || [])
end if !object.instance_of?(Publication) && object.respond_to?("creators")
unless hide_contact_details?
builder.tag! "email",object.email if object.respond_to?("email")
builder.tag! "webpage",object.webpage if object.respond_to?("webpage")
builder.tag! "internal_webpage",object.internal_webpage if object.respond_to?("internal_webpage")
builder.tag! "phone",object.phone if object.respond_to?("phone")
end
builder.tag! "bioportal_concepts" do
concepts=[]
concepts=object.bioportal_concepts if object.respond_to?("bioportal_concepts")
concept = object.bioportal_concept if object.respond_to?("bioportal_concept")
concepts.compact.each do |concept|
builder.tag! "bioportal_concept" do
builder.tag! "ontology_id",concept.ontology_id
builder.tag! "concept_uri",concept.concept_uri
end
end
end if object.respond_to?("bioportal_concept") || object.respond_to?("bioportal_concepts")
builder.tag! "version",object.version if object.respond_to?("version")
builder.tag! "revision_comments",object.revision_comments if object.respond_to?("revision_comments")
builder.tag! "latest_version",core_xlink(object.latest_version) if object.respond_to?("latest_version")
if (object.respond_to?("versions"))
builder.tag! "versions" do
object.versions.each do |v|
builder.tag! "version",core_xlink(v)
end
end
end
policy_xml builder,object if User.admin_logged_in? && object.respond_to?("policy")
if object.respond_to?("content_blobs")
builder.tag! "blobs" do
object.content_blobs.each do |cb|
blob_xml builder, cb
end
end
elsif object.respond_to?("content_blob")
blob_xml builder, object.content_blob
end
if object.respond_to?("avatar")
builder.tag! "avatars" do
builder.tag! "avatar",avatar_xlink(object.avatar) unless object.avatar.nil?
end
end
tags_xml builder,object
end
def tags_xml builder,object
object = object.parent if object.class.name.include?("::Version")
if object.respond_to?(:annotations_as_text_array)
builder.tag! "tags" do
object.annotations.each do |annotation|
builder.tag! "tag",annotation.value.text,{:context=>annotation.attribute.name}
end
end
end
end
def policy_xml builder,asset
policy = asset.policy
unless policy.nil?
builder.tag! "policy" do
dc_core_xml builder,policy
builder.tag! "sharing_scope",policy.sharing_scope
builder.tag! "access_type",policy.access_type
builder.tag! "use_blacklist",policy.use_blacklist ? policy.use_blacklist : false
builder.tag! "use_whitelist",policy.use_whitelist ? policy.use_whitelist : false
builder.tag! "permissions" do
policy.permissions.select{|p| p.contributor_type!="FavouriteGroup"}.each do |permission|
builder.tag! "permission" do
dc_core_xml builder,permission
builder.tag! "contributor",core_xlink(permission.contributor)
builder.tag! "access_type",permission.access_type
end
end
end
end
else
builder.tag! "policy",{"xsi:nil"=>"true"}
end
end
def resource_xml builder,resource
builder.tag! "resource",core_xlink(resource)
end
def blob_xml builder,blob
builder.tag! "blob",core_xlink(blob) do
builder.tag! "uuid",blob.uuid
builder.tag! "md5sum",blob.md5sum
builder.tag! "url",blob.url
builder.tag! "original_filename",blob.original_filename
builder.tag! "content_type",blob.content_type
builder.tag! "is_remote",!blob.file_exists?
end
end
def assets_list_xml builder,assets,tag="assets",include_core=true,include_resource=true
builder.tag! tag do
assets.each do |asset|
asset_xml builder,asset,include_core,include_resource
end
end
end
def associated_resources_xml builder, object
object=object.parent if (object.class.name.include?("::Version"))
associated = get_related_resources(object)
to_ignore = ignore_associated_types.collect{|t| t.name}
associated.delete_if {|k,v| to_ignore.include?(k)}
builder.tag! "associated" do
associated.keys.sort.each do |key|
attr={}
attr[:total]=associated[key][:items].count
if (associated[key][:hidden_count])
attr[:total]=attr[:total]+associated[key][:hidden_count]
attr[:hidden_count]=associated[key][:hidden_count]
end
generic_list_xml(builder, associated[key][:items],key.underscore.pluralize,attr)
end
end
end
#types that should be ignored from the related resources. It may be desirable to add items in this list to the schema
def ignore_associated_types
[Strain,TavernaPlayer::Run,Workflow,Sweep]
end
def generic_list_xml builder,list,tag,attr={}
builder.tag! tag,attr do
list.each do |item|
if (item.class.name.include?("::Version")) #versioned items need to be handled slightly differently.
parent=item.parent
builder.tag! parent.class.name.underscore,core_xlink(item)
else
builder.tag! item.class.name.underscore,core_xlink(item)
end
end
end
end
def api_partial builder,object, is_root=false
parent_object = object.class.name.include?("::Version") ? object.parent : object
path=api_partial_path_for_item(parent_object)
classname=parent_object.class.name.underscore
render :partial=>path,:locals=>{:parent_xml => builder,:is_root=>is_root,classname.to_sym=>object}
end
def api_partial_collection builder,objects,is_root=false
objects.each{|o| api_partial builder,o,is_root}
end
def parent_child_elements builder,object
builder.tag! "parents" do
api_partial_collection(builder, object.parents, is_root = false)
end
builder.tag! "children" do
api_partial_collection(builder, object.children, is_root = false)
end
end
def dc_core_xml builder,object
submitter = determine_submitter object
dc_xml_tag builder,:title,object.title if object.respond_to?("title")
dc_xml_tag builder,:description,object.description if object.respond_to?("description")
dcterms_xml_tag builder,:created,object.created_at if object.respond_to?("created_at")
dcterms_xml_tag builder,:modified,object.updated_at if object.respond_to?("updated_at")
dc_xml_tag builder,:creator,submitter.name if submitter
end
def determine_submitter object
#FIXME: needs to be the creators for assets
return object.owner if object.respond_to?("owner")
result = object.contributor if object.respond_to?("contributor") && !object.kind_of?(Permission)
if (result)
return result if result.instance_of?(Person)
return result.person if result.instance_of?(User)
end
return nil
end
def assay_data_relationships_xml builder,assay
relationships={}
assay.assay_assets.each do |aa|
if aa.relationship_type
relationships[aa.relationship_type.title] ||= []
relationships[aa.relationship_type.title] << aa.asset
end
end
builder.tag! "data_relationships" do
relationships.keys.each do |k|
generic_list_xml(builder, relationships[k],"data_relationship",{:type=>k})
end
end
end
end