myexperiment-hackers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[myexperiment-hackers] [3569] branches/packs: root folders, better RDF h


From: noreply
Subject: [myexperiment-hackers] [3569] branches/packs: root folders, better RDF handling and some refactoring
Date: Fri, 24 May 2013 16:49:11 +0000 (UTC)

Revision
3569
Author
dgc
Date
2013-05-24 16:49:10 +0000 (Fri, 24 May 2013)

Log Message

root folders, better RDF handling and some refactoring

Modified Paths

Diff

Modified: branches/packs/app/controllers/research_objects_controller.rb (3568 => 3569)


--- branches/packs/app/controllers/research_objects_controller.rb	2013-05-23 14:38:23 UTC (rev 3568)
+++ branches/packs/app/controllers/research_objects_controller.rb	2013-05-24 16:49:10 UTC (rev 3569)
@@ -1,3 +1,8 @@
+# myExperiment: app/controllers/research_objects_controller.rb
+#
+# Copyright (c) 2007-2013 The University of Manchester, the University of
+# Oxford, and the University of Southampton.  See license.txt for details.
+
 require 'securerandom'
 
 class ResearchObjectsController < ActionController::Base

Modified: branches/packs/app/controllers/resources_controller.rb (3568 => 3569)


--- branches/packs/app/controllers/resources_controller.rb	2013-05-23 14:38:23 UTC (rev 3568)
+++ branches/packs/app/controllers/resources_controller.rb	2013-05-24 16:49:10 UTC (rev 3569)
@@ -1,3 +1,8 @@
+# myExperiment: app/controllers/resources_controller.rb
+#
+# Copyright (c) 2007-2013 The University of Manchester, the University of
+# Oxford, and the University of Southampton.  See license.txt for details.
+
 require 'securerandom'
 
 class ResourcesController < ActionController::Base
@@ -96,7 +101,7 @@
       graph = RDF::Graph.new
 
       changes.each do |change|
-        graph << research_object.resources.find_by_path(change).description
+        graph << change.description
       end
 
       body = pretty_rdf_xml(RDF::Writer.for(:rdfxml).buffer { |writer| writer << graph } )

Modified: branches/packs/app/helpers/research_objects_helper.rb (3568 => 3569)


--- branches/packs/app/helpers/research_objects_helper.rb	2013-05-23 14:38:23 UTC (rev 3568)
+++ branches/packs/app/helpers/research_objects_helper.rb	2013-05-24 16:49:10 UTC (rev 3569)
@@ -151,6 +151,8 @@
       ".ro/folders/#{SecureRandom.uuid}"
     when "application/vnd.wf4ever.folderentry"
       ".ro/entries/#{SecureRandom.uuid}"
+    when "application/vnd.wf4ever.folder"
+      ".ro/resource_maps/#{SecureRandom.uuid}"
     else
       SecureRandom.uuid
     end

Modified: branches/packs/app/models/annotation_resource.rb (3568 => 3569)


--- branches/packs/app/models/annotation_resource.rb	2013-05-23 14:38:23 UTC (rev 3568)
+++ branches/packs/app/models/annotation_resource.rb	2013-05-24 16:49:10 UTC (rev 3569)
@@ -1,5 +1,6 @@
 
 class AnnotationResource < ActiveRecord::Base
   belongs_to :annotation, :class_name => "Resource"
+  belongs_to :research_object
 end
 

Modified: branches/packs/app/models/content_blob.rb (3568 => 3569)


--- branches/packs/app/models/content_blob.rb	2013-05-23 14:38:23 UTC (rev 3568)
+++ branches/packs/app/models/content_blob.rb	2013-05-24 16:49:10 UTC (rev 3569)
@@ -10,21 +10,27 @@
 
   before_save :update_metadata
 
-  # validates_presence_of uses a function that assumes UTF-8 encoding and thus
-  # has issues with other encodings.  The following validation provides similar
-  # functionality to validates_presence_of on the content blob data.
-
   validate do |record|
-    if record.data.nil? || record.data.length == 0
-      record.errors.add(:data, 'cannot be empty.')
+    if record.data.nil?
+      record.errors.add(:data, 'cannot be undefined.')
     end
   end
 
   def update_metadata
+    calc_sha1
+    calc_md5
+    calc_size
+  end
 
-    self.md5  = Digest::MD5.hexdigest(data)
+  def calc_sha1
     self.sha1 = Digest::SHA1.hexdigest(data)
+  end
 
+  def calc_md5
+    self.md5  = Digest::MD5.hexdigest(data)
+  end
+
+  def calc_size
     case self.data
     when StringIO
       self.size = self.data.size

Modified: branches/packs/app/models/research_object.rb (3568 => 3569)


--- branches/packs/app/models/research_object.rb	2013-05-23 14:38:23 UTC (rev 3568)
+++ branches/packs/app/models/research_object.rb	2013-05-24 16:49:10 UTC (rev 3569)
@@ -1,3 +1,8 @@
+# myExperiment: app/models/research_object.rb
+#
+# Copyright (c) 2007-2013 The University of Manchester, the University of
+# Oxford, and the University of Southampton.  See license.txt for details.
+
 require 'rdf'
 require 'rdf/raptor'
 
@@ -13,6 +18,8 @@
 
   has_many :resources, :dependent => :destroy
 
+  has_many :annotation_resources
+
   validates_presence_of :slug
 
   def uri
@@ -29,18 +36,22 @@
 
     graph = RDF::Graph.new
 
-    graph << [ro_uri, RDF.type, RDF::URI("http://purl.org/wf4ever/ro#ResearchObject")]
-    graph << [ro_uri, RDF.type, RDF::URI("http://www.openarchives.org/ore/terms/Aggregation")]
-    graph << [ro_uri, RDF::URI("http://www.openarchives.org/ore/terms/isDescribedBy"), ro_uri + MANIFEST_PATH]
+    graph << [ro_uri, RDF.type, RO.ResearchObject]
+    graph << [ro_uri, RDF.type, ORE.Aggregation]
+    graph << [ro_uri, ORE.isDescribedBy, ro_uri + MANIFEST_PATH]
     graph << [ro_uri, RDF::DC.created, created_at.to_datetime]
     graph << [ro_uri, RDF::DC.creator, RDF::URI(creator_uri)]
 
     graph << [RDF::URI(creator_uri), RDF.type, RDF::FOAF.Agent]
 
+    if root_folder
+      graph << [ro_uri, RO.rootFolder, RDF::URI(root_folder.uri)]
+    end
+
     resources.each do |resource|
 
       if resource.is_aggregated
-        graph << [ro_uri, RDF::URI("http://www.openarchives.org/ore/terms/aggregates"), RDF::URI(resource.resource_uri)]
+        graph << [ro_uri, ORE.aggregates, RDF::URI(resource.resource_uri)]
       end
 
       graph << resource.description
@@ -66,213 +77,123 @@
     resources.find(:first, :conditions => { :path => MANIFEST_PATH })
   end
 
+  def root_folder
+    resources.find(:first, :conditions => { :is_root_folder => true } )
+  end
+
   def new_or_update_resource(opts = {})
 
-    changed_descriptions = []
+    changed = []
     links = []
     location = nil
 
     content_type  = opts[:content_type]
     slug          = opts[:slug]
-    path          = opts[:slug]
+    path          = opts[:path]
     user_uri      = opts[:user_uri]
     data          = ""
     request_links = opts[:links] || {}
 
     if slug == ResearchObject::MANIFEST_PATH
 
-      path = calculate_path(slug, content_type, request_links)
-
       return [:forbidden, "Cannot overwrite the manifest", nil, []] unless opts[:force_write]
 
-      resource = resources.find_by_path(path)
-      resource = resources.new(:path => path) unless resource
+      manifest = create_resource(
+        :path          => calculate_path(slug, content_type, request_links),
+        :content_blob  => ContentBlob.new(:data ="" data),
+        :creator_uri   => user_uri,
+        :content_type  => content_type,
+        :is_resource   => false,
+        :is_aggregated => false,
+        :is_proxy      => false,
+        :is_annotation => false,
+        :is_folder     => false)
 
-      resource.content_blob.destroy if resource.content_blob
+      changed << manifest
 
-      resource.content_blob = ContentBlob.new(:data ="" data)
-      resource.creator_uri = user_uri
-      resource.content_type = content_type
-      resource.name = path.split("/").last if path
-
-      resource.is_resource   = false
-      resource.is_aggregated = false
-      resource.is_proxy      = false
-      resource.is_annotation = false
-      resource.is_folder     = false
-
-
-      resource.save
-
-      changed_descriptions << resource.path
-
     elsif content_type == "application/vnd.wf4ever.proxy"
 
-      path = calculate_path(slug, content_type, request_links)
-
-      # Obtain information to create the proxy.
-
       graph = load_graph(data)
 
       node           = graph.query([nil,  RDF.type,     ORE.proxy]).first_subject
-      proxy_for_uri  = graph.query([node, ORE.proxyFor, nil           ]).first_object
+      proxy_for_uri  = graph.query([node, ORE.proxyFor, nil      ]).first_object
 
-      # Contruct the proxy.
+      proxy = create_proxy(
+        :path           => calculate_path(slug, content_type, request_links),
+        :proxy_for_path => relative_uri(proxy_for_uri, uri),
+        :proxy_in_path  => ".",
+        :user_uri       => user_uri)
 
-      ro_uri         = RDF::URI(uri)
-      proxy_uri      = ro_uri + path
-      proxy_in_uri   = ro_uri
-      proxy_for_path = relative_uri(proxy_for_uri, uri)
-      proxy_in_path  = relative_uri(proxy_in_uri, uri)
+      proxy.update_graph!
 
-      proxy_body = create_rdf_xml do |graph|
-        graph << [proxy_uri, RDF.type,     ORE.Proxy]
-        graph << [proxy_uri, ORE.proxyIn,  proxy_in_uri]
-        graph << [proxy_uri, ORE.proxyFor, proxy_for_uri]
-      end
+      location =  proxy.uri
+      links    << { :link => proxy_for_uri, :rel => ORE.proxyFor }
+      changed  << proxy
 
-      proxy = resources.find_by_path(path)
-      proxy = resources.new(:path => path) unless proxy
-
-      proxy.content_blob.destroy if proxy.content_blob
-
-      proxy.is_proxy       = true
-      proxy.proxy_for_path = proxy_for_path
-      proxy.proxy_in_path  = proxy_in_path
-      proxy.content_blob   = ContentBlob.new(:data ="" proxy_body)
-      proxy.creator_uri    = user_uri
-      proxy.content_type   = content_type
-      proxy.name           = path.split("/").last
-
-      proxy.save
-
-      location = proxy.uri
-      links << { :link => proxy_for_uri, :rel => ORE.proxyFor }
-
-      changed_descriptions << proxy.path
-
     elsif content_type == "application/vnd.wf4ever.annotation"
 
-      path = calculate_path(slug, content_type, request_links)
+      # Get information.
 
-      resource = resources.find_by_path(path)
-      resource = resources.new(:path => path) unless resource
+      graph = load_graph(data)
 
-      resource.content_blob.destroy if resource.content_blob
+      aggregated_annotations = graph.query([nil, RDF.type, RO.AggregatedAnnotation])
 
-      resource.content_blob = ContentBlob.new(:data ="" data)
-      resource.creator_uri = user_uri
-      resource.content_type = content_type
-      resource.name = path.split("/").last if path
-
-      # Creation of an annotation stub directly
-
-      resource.is_resource   = false
-      resource.is_aggregated = true
-      resource.is_proxy      = false
-      resource.is_annotation = true
-      resource.is_folder     = false
-
-      graph = load_graph(resource.content_blob.data)
-
-      aggregated_annotations = graph.query([nil, RDF.type, RDF::URI("http://purl.org/wf4ever/ro#AggregatedAnnotation")])
-
       if aggregated_annotations.count != 1 # FIXME - add test case
         return [:unprocessable_entity, "The annotation must contain exactly one aggregated annotation", nil, []]
       end
 
       aggregated_annotation = aggregated_annotations.first_subject
 
-      ao_body_statements = graph.query([aggregated_annotation, RDF::URI("http://purl.org/ao/body"), nil])
+      ao_body_statements = graph.query([aggregated_annotation, AO.body, nil])
 
       if ao_body_statements.count != 1 # FIXME - add test case
         return [:unprocessable_entity, "Annotations must contain exactly one annotation body", nil, []]
       end
 
-      ao_body_uri = ao_body_statements.first_object.to_s
+      annotated_resources_statements = graph.query([aggregated_annotation, AO.annotatesResource, nil])
 
-      resource.ao_body_path = relative_uri(ao_body_uri, uri)
-
-      annotated_resources_statements = graph.query([aggregated_annotation, RDF::URI("http://purl.org/ao/annotatesResource"), nil])
-
       if annotated_resources_statements.count == 0 # FIXME - add test case
         return [:unprocessable_entity, "Annotations must annotate one or more resources", nil, []]
       end
 
+      ao_body_uri = ao_body_statements.first_object.to_s
+
+      stub = create_annotation_stub(
+        :user_uri       => user_uri,
+        :ao_body_path   => relative_uri(ao_body_uri, uri),
+        :resource_paths => annotated_resources_statements.map { |a| relative_uri(a.object, uri) } )
+
       annotated_resources_statements.each do |annotated_resource|
-        resource.annotation_resources.build(:resource_path => relative_uri(annotated_resource.object, uri))
-        links << { :link => annotated_resource.object.to_s, :rel => "http://purl.org/ao/annotatesResource" }
+        links << { :link => annotated_resource.object, :rel => AO.annotatesResource }
       end
 
-      links << { :link => ao_body_uri, :rel => "http://purl.org/ao/body" }
+      stub.update_graph!
 
+      links   << { :link => ao_body_uri, :rel => AO.body }
+      changed << stub
 
-      resource.save
-
-      changed_descriptions << resource.path
-
     elsif content_type == "application/vnd.wf4ever.folder"
 
-      path = calculate_path(slug, content_type, request_links)
+      folder = create_folder(
+        :path     => slug,
+        :user_uri => user_uri)
 
-      resource = resources.find_by_path(path)
-      resource = resources.new(:path => path) unless resource
+      proxy = create_proxy(
+        :proxy_for_path => folder.path,
+        :proxy_in_path  => ".",
+        :user_uri       => user_uri)
 
-      resource.content_blob.destroy if resource.content_blob
+      location = proxy.uri
 
-      resource.content_blob = ContentBlob.new(:data ="" data)
-      resource.creator_uri = user_uri
-      resource.content_type = content_type
-      resource.name = path.split("/").last if path
+      links << { :link => folder.resource_map.uri, :rel => ORE.isDescribedBy }
+      links << { :link => folder.uri,              :rel => ORE.proxyFor      }
 
+      changed << proxy
+      changed << folder.resource_map
+      changed << folder
 
-      resource.is_resource   = false
-      resource.is_aggregated = true
-      resource.is_proxy      = false
-      resource.is_annotation = false
-      resource.is_folder     = true
-      
-      # Create a resource map for this folder
-
-      resource_uri = resource.resource_uri.to_s
-
-      resource_map_path = ".ro/resource_maps/#{SecureRandom.uuid}"
-      resource_map_uri  = uri + resource_map_path
-
-      resource_map_graph = RDF::Graph.new
-      resource_map_graph << [RDF::URI(resource_map_uri), RDF.type, RDF::URI("http://www.openarchives.org/ore/terms/ResourceMap")]
-      resource_map_graph << [RDF::URI(resource_map_uri), RDF::URI("http://www.openarchives.org/ore/terms/describes"), RDF::URI(resource_uri)]
-
-      resource_map_body = pretty_rdf_xml(RDF::Writer.for(:rdfxml).buffer { |writer| writer << resource_map_graph } )
-
-      # FIXME - this should be a recursive call
-
-      resource_map_attributes = {
-        :content_blob    => ContentBlob.new(:data ="" resource_map_body),
-        :creator_uri     => user_uri,
-        :content_type    => 'application/vnd.wf4ever.folder',
-        :is_resource_map => true,
-        :path            => resource_map_path
-      }
-
-      resources.create(resource_map_attributes)
-
-      resource.resource_map_path = resource_map_path
-
-      links << { :link => resource_map_uri, :rel => "http://www.openarchives.org/ore/terms/isDescribedBy" }
-      links << { :link => resource_uri,     :rel => "http://www.openarchives.org/ore/terms/proxyFor"      }
-
-      changed_descriptions << resource_map_path
-
-
-      resource.save
-
-      changed_descriptions << resource.path
-
     elsif content_type == "application/vnd.wf4ever.folderentry"
 
-      path = calculate_path(nil, 'application/vnd.wf4ever.folderentry')
-
       # Obtain information to create the folder entry.
 
       graph = load_graph(data)
@@ -280,178 +201,219 @@
       node           = graph.query([nil,  RDF.type,     RO.FolderEntry]).first_subject
       proxy_for_uri  = graph.query([node, ORE.proxyFor, nil           ]).first_object
 
+      # FIXME - need to check if proxy_in and proxy_for actually exists and error if not
+
       proxy_for_path = relative_uri(proxy_for_uri, uri)
       proxy_in_path  = opts[:path]
-      proxy_in_uri   = uri + proxy_in_path
 
       # Create the folder entry
 
-      folder_entry = resources.new(:path => path)
+      folder_entry = create_resource(
+        :path            => calculate_path(nil, 'application/vnd.wf4ever.folderentry'),
+        :is_folder_entry => true,
+        :proxy_in_path   => proxy_in_path,
+        :proxy_for_path  => proxy_for_path,
+        :content_type    => content_type,
+        :creator_uri     => user_uri)
 
-      folder_entry_uri = RDF::URI(folder_entry.uri)
-
-      folder_entry_body = create_rdf_xml do |graph|
-        graph << [folder_entry_uri, RDF.type, ORE.Proxy]
-        graph << [folder_entry_uri, RDF.type, RO.FolderEntry]
-        graph << [folder_entry_uri, ORE.proxyIn, RDF::URI(proxy_in_uri)]
-        graph << [folder_entry_uri, ORE.proxyFor, RDF::URI(proxy_for_uri)]
-      end
-
-      folder_entry.is_folder_entry = true
-      folder_entry.content_blob    = ContentBlob.new(:data ="" folder_entry_body)
-      folder_entry.proxy_in_path   = proxy_in_path
-      folder_entry.proxy_for_path  = proxy_for_path
-      folder_entry.content_type    = content_type
-      folder_entry.creator_uri     = user_uri
-      folder_entry.name            = path.split("/").last if path
-
-      folder_entry.save
-
       folder_entry.proxy_for.update_attribute(:aggregated_by_path, proxy_in_path)
 
+      folder_entry.update_graph!
+      folder_entry.proxy_for.update_graph!
+
       location = folder_entry.uri
 
-      links << { :link => proxy_for_uri, :rel => "http://www.openarchives.org/ore/terms/proxyFor" }
+      links << { :link => proxy_for_uri, :rel => ORE.proxyFor }
 
-    elsif request_links["http://purl.org/ao/annotatesResource"]
+      changed << folder_entry
 
+    elsif request_links[AO.annotatesResource.to_s]
+
       path           = calculate_path(nil, content_type)
       ro_uri         = RDF::URI(uri)
       annotation_uri = ro_uri + path
 
-
       # Create an annotation body using the provided graph
 
-      # Process ao:annotatesResource links by creating annotation stubs using the
-      # given resource as an ao:body.
+      ao_body = create_aggregated_resource(
+        :path         => calculate_path(slug, content_type, request_links),
+        :data         ="" data,
+        :content_type => content_type,
+        :user_uri     => user_uri)
 
-      ao_body_path = calculate_path(slug, content_type, request_links)
+      stub = create_annotation_stub(
+        :user_uri       => user_uri,
+        :ao_body_path   => ao_body.path,
+        :resource_paths => request_links[AO.annotatesResource.to_s].each { |resource| relative_uri(resource, uri) } )
 
-      ao_body = resources.find_by_path(path)
-      ao_body = resources.new(:path => path) unless ao_body
+      ao_body.update_graph!
+      stub.update_graph!
 
-      ao_body.content_blob.destroy if ao_body.content_blob
+      request_links[AO.annotatesResource.to_s].each do |annotated_resource_uri|
+        links << { :link => annotated_resource_uri, :rel => AO.annotatesResource }
+      end
 
-      ao_body.content_blob  = ContentBlob.new(:data ="" data)
-      ao_body.creator_uri   = user_uri
-      ao_body.content_type  = content_type
-      ao_body.name          = ao_body_path.split("/").last
-      ao_body.is_resource   = true
-      ao_body.is_aggregated = true
+      changed << stub
+      changed << ao_body
+      changed << ao_body.proxy
 
-      ao_body.save
-      # FIXME - no proxy is created for this ao:body resource
+      links << { :link => stub.uri, :rel => AO.body }
 
-      changed_descriptions << ao_body.path
+      location = stub.uri
 
-      annotation_rdf = create_rdf_xml do |graph|
-        graph << [annotation_uri, RDF.type, RO.AggregatedAnnotation]
-        graph << [annotation_uri, RDF.type, AO.Annotation]
-        graph << [annotation_uri, AO.body,  RDF::URI(ao_body.uri)]
+    else
 
-        request_links["http://purl.org/ao/annotatesResource"].each do |annotated_resource_uri|
-          graph << [annotation_uri, AO.annotatesResource, RDF::URI(annotated_resource_uri)]
-        end
-      end
+      resource = create_aggregated_resource(
+        :path         => calculate_path(slug, content_type, request_links),
+        :data         ="" data,
+        :content_type => content_type,
+        :user_uri     => user_uri)
 
-      annotation_stub = resources.new({
-        :creator_uri   => user_uri,
-        :path          => calculate_path(nil, 'application/vnd.wf4ever.annotation'),
-        :content_blob  => ContentBlob.new(:data ="" annotation_rdf),
-        :content_type  => 'application/vnd.wf4ever.annotation',
-        :is_annotation => true,
-        :ao_body_path  => ao_body.path
-      })
+      changed << resource
+    end
 
-      request_links["http://purl.org/ao/annotatesResource"].each do |annotated_resource_uri|
-        annotation_stub.annotation_resources.build(:resource_path => relative_uri(annotated_resource_uri, uri))
-        links << { :link => annotated_resource_uri, :rel => "http://purl.org/ao/annotatesResource" }
+    if resource && content_type != "application/vnd.wf4ever.proxy" && !resource.is_manifest? && !request_links[AO.annotatesResource.to_s]
+
+      proxy = resources.find(:first,
+          :conditions => { :content_type   => 'application/vnd.wf4ever.proxy',
+                           :proxy_in_path  => '.',
+                           :proxy_for_path => resource.path })
+
+      # Create a proxy for this resource if it doesn't exist.
+
+      unless proxy
+        proxy = create_proxy(
+          :proxy_for_path => resource.path,
+          :proxy_in_path  => ".",
+          :user_uri       => user_uri)
+
+        proxy.update_graph!
       end
 
-      annotation_stub.save
+      links << { :link => resource.uri, :rel => ORE.proxyFor }
+      location = proxy.uri
 
-      changed_descriptions << annotation_stub.path
+      changed << proxy
+    end
 
-      links << { :link => annotation_stub.uri, :rel => "http://purl.org/ao/body" }
+    location ||= resource.uri if resource
 
-      location = uri + annotation_stub.path
+    [:created, nil, location, links, path, changed]
+  end
 
-    else
+  # opts[:path] - optional path to use for the proxy
+  # opts[:proxy_for_path] - required
+  # opts[:proxy_in_path] - required
+  # opts[:user_uri] - optional
 
-      path = calculate_path(slug, content_type, request_links)
+  def create_proxy(opts)
 
-      resource = resources.find_by_path(path)
-      resource = resources.new(:path => path) unless resource
+    # FIXME - these should be validations on the resource model
+    throw "proxy_for_path required" unless opts[:proxy_for_path]
+    throw "proxy_in_path required"  unless opts[:proxy_in_path]
 
-      resource.content_blob.destroy if resource.content_blob
+    create_resource(
+      :path           => opts[:path] || calculate_path(nil, 'application/vnd.wf4ever.proxy'),
+      :is_proxy       => true,
+      :proxy_for_path => opts[:proxy_for_path],
+      :proxy_in_path  => opts[:proxy_in_path],
+      :creator_uri    => opts[:user_uri],
+      :content_type   => "application/vnd.wf4ever.proxy")
+  end
 
-      resource.content_blob  = ContentBlob.new(:data ="" data)
-      resource.creator_uri   = user_uri
-      resource.content_type  = content_type
-      resource.name          = path.split("/").last
-      resource.is_resource   = true
-      resource.is_aggregated = true
+  def create_annotation_stub(opts)
 
-      resource.save
+    # FIXME - these should be validations on the resource model
+    throw "ao_body_path required"   unless opts[:ao_body_path]
+    throw "resource_paths required" unless opts[:resource_paths]
+    
+    stub = create_resource(
+      :path          => opts[:path] || calculate_path(nil, 'application/vnd.wf4ever.annotation'),
+      :creator_uri   => opts[:user_uri],
+      :content_type  => 'application/rdf+xml',
+      :is_aggregated => true,
+      :is_annotation => true,
+      :ao_body_path  => opts[:ao_body_path])
 
-      changed_descriptions << resource.path
+    opts[:resource_paths].map do |resource_path|
+      stub.annotation_resources.create(:resource_path => resource_path, :research_object => self)
     end
 
-    if resource && content_type != "application/vnd.wf4ever.proxy" && !resource.is_manifest? && !request_links["http://purl.org/ao/annotatesResource"]
+    stub
+  end
 
-      resource_uri = resource.resource_uri.to_s
+  def create_aggregated_resource(opts)
 
-      relative_resource_uri = relative_uri(resource_uri, uri)
+    # Create a proxy for this resource.
 
-      proxy = resources.find(:first,
-          :conditions => { :content_type   => 'application/vnd.wf4ever.proxy',
-                           :proxy_in_path  => '.',
-                           :proxy_for_path => relative_resource_uri })
+    proxy = create_proxy(
+      :proxy_for_path => opts[:path],
+      :proxy_in_path  => ".",
+      :user_uri       => opts[:user_uri])
 
-      if proxy.nil?
-        proxy_slug = ".ro/proxies/#{SecureRandom.uuid}"
-      else
-        proxy_slug = proxy.path
-      end
+    proxy.update_graph!
 
-      proxy_body = pretty_rdf_xml(RDF::Writer.for(:rdfxml).buffer { |writer| writer << resource.generate_proxy(proxy_slug) } )
+    # Create the resource.
 
-      # FIXME - this should be a recursive call
+    create_resource(
+      :path          => opts[:path],
+      :content_blob  => ContentBlob.new(:data ="" opts[:data]),
+      :creator_uri   => opts[:user_uri],
+      :content_type  => opts[:content_type],
+      :is_resource   => true,
+      :is_aggregated => true)
+  end
 
-      proxy_attributes = {
-        :content_blob   => ContentBlob.new(:data ="" proxy_body),
-        :proxy_in_path  => '.',
-        :proxy_for_path => relative_resource_uri,
-        :creator_uri    => user_uri,
-        :content_type   => 'application/vnd.wf4ever.proxy',
-        :is_proxy       => true,
-        :path           => proxy_slug
-      }
+  def create_resource_map(opts)
 
-      if proxy.nil?
-        proxy = resources.create(proxy_attributes)
-      else
-        proxy.content_blob.destroy
-        proxy.update_attributes(proxy_attributes)
-      end
+    create_resource(
+      :path            => opts[:path] || calculate_path(nil, "application/vnd.wf4ever.folder"),
+      :creator_uri     => opts[:user_uri],
+      :content_type    => 'application/rdf+xml',
+      :is_resource_map => true)
 
-      links << { :link => resource_uri, :rel => "http://www.openarchives.org/ore/terms/proxyFor" }
-      location = proxy.uri
+  end
 
-      changed_descriptions << proxy_slug
-    end
+  def create_folder(opts)
 
-    location ||= resource_uri
+    # Create a resource map for this folder
 
-    [:created, nil, location, links, path, changed_descriptions]
+    resource_map = create_resource_map(:user_uri => opts[:user_uri])
+
+    # Create the folder entry
+
+    folder = create_resource(
+      :path              => opts[:path],
+      :creator_uri       => opts[:user_uri],
+      :content_type      => "application/vnd.wf4ever.folder",
+      :resource_map_path => resource_map.path,
+      :is_aggregated     => true,
+      :is_root_folder    => root_folder.nil?,
+      :is_folder         => true)
+
+    folder.update_graph!
+    resource_map.update_graph!
+
+    folder
   end
 
+  def create_resource(attributes)
+
+    resource = resources.find_by_path(attributes[:path]) || resources.new
+
+    # FIXME - We need to know when we should be allowed to overwrite a
+    # resource.  The RO structure needs to remain consistent.
+
+    resource.attributes = attributes
+    resource.save
+    resource
+  end
+
 private
 
   def create_manifest
 
     resources.create(:path => ResearchObject::MANIFEST_PATH,
-                     :content_blob => ContentBlob.new(:data ="" "Dummy content"),
                      :content_type => 'application/rdf+xml')
 
     update_manifest!

Modified: branches/packs/app/models/resource.rb (3568 => 3569)


--- branches/packs/app/models/resource.rb	2013-05-23 14:38:23 UTC (rev 3568)
+++ branches/packs/app/models/resource.rb	2013-05-24 16:49:10 UTC (rev 3569)
@@ -1,3 +1,8 @@
+# myExperiment: app/models/resource.rb
+#
+# Copyright (c) 2007-2013 The University of Manchester, the University of
+# Oxford, and the University of Southampton.  See license.txt for details.
+
 require 'securerandom'
 
 class Resource < ActiveRecord::Base
@@ -4,6 +9,8 @@
 
   include ResearchObjectsHelper
 
+  before_save :copy_metadata
+
   belongs_to :research_object
 
   belongs_to :content_blob, :dependent => :destroy
@@ -28,7 +35,6 @@
   validates_uniqueness_of :path, :scope => :research_object_id
   validates_presence_of :content_type
   validates_presence_of :path
-  validates_presence_of :content_blob
 
   def is_manifest?
     path == ResearchObject::MANIFEST_PATH
@@ -42,32 +48,32 @@
     uri    = resource_uri
 
     if is_manifest?
-      graph << [uri, RDF.type, RDF::URI("http://purl.org/wf4ever/ro#Manifest")]
-      graph << [uri, RDF.type, RDF::URI("http://www.openarchives.org/ore/terms/ResourceMap")]
-      graph << [uri, RDF::URI("http://www.openarchives.org/ore/terms/describes"), ro_uri]
+      graph << [uri, RDF.type,      RO.Manifest]
+      graph << [uri, RDF.type,      ORE.ResourceMap]
+      graph << [uri, ORE.describes, ro_uri]
     end
 
     if is_resource
-      graph << [uri, RDF.type, RDF::URI("http://purl.org/wf4ever/ro#Resource")]
+      graph << [uri, RDF.type, RO.Resource]
     end
 
     if is_aggregated
-      graph << [uri, RDF.type, RDF::URI("http://www.openarchives.org/ore/terms/AggregatedResource")]
+      graph << [uri, RDF.type, ORE.AggregatedResource]
     end
 
     if is_proxy
-      graph << [uri, RDF.type, RDF::URI("http://www.openarchives.org/ore/terms/Proxy")]
-      graph << [uri, RDF::URI("http://www.openarchives.org/ore/terms/proxyIn"), ro_uri.join(proxy_in_path)]
-      graph << [uri, RDF::URI("http://www.openarchives.org/ore/terms/proxyFor"), ro_uri.join(proxy_for_path)]
+      graph << [uri, RDF.type,     ORE.Proxy]
+      graph << [uri, ORE.proxyIn,  ro_uri.join(proxy_in_path)]
+      graph << [uri, ORE.proxyFor, ro_uri.join(proxy_for_path)]
     end
 
     if is_annotation
-      graph << [uri, RDF.type, RDF::URI("http://purl.org/wf4ever/ro#AggregatedAnnotation")]
-      graph << [uri, RDF.type, RDF::URI("http://purl.org/ao/Annotation")]
-      graph << [uri, RDF::URI("http://purl.org/ao/body"), ro_uri.join(ao_body_path)]
+      graph << [uri, RDF.type, RO.AggregatedAnnotation]
+      graph << [uri, RDF.type, AO.Annotation]
+      graph << [uri, AO.body,  ro_uri.join(ao_body_path)]
 
       annotation_resources.each do |resource|
-        graph << [uri, RDF::URI("http://purl.org/wf4ever/ro#annotatesAggregatedResource"), ro_uri.join(resource.resource_path)]
+        graph << [uri, RO.annotatesAggregatedResource, ro_uri.join(resource.resource_path)]
       end
     end
 
@@ -83,8 +89,6 @@
       graph << [folder_uri, RDF.type, RO.folder]
       graph << [folder_uri, RDF.type, ORE.Aggregation]
       graph << [folder_uri, ORE.isDescribedBy, uri]
-      graph << [folder_uri, RDF::DC.created, folder.created_at.to_datetime]
-      graph << [folder_uri, RDF::DC.creator, RDF::URI(folder.creator_uri)]
       graph << [folder_uri, ORE.isAggregatedBy, RDF::URI(folder.aggregated_by.uri)] if folder.aggregated_by_path
 
       folder.aggregates.each do |aggregate|
@@ -94,23 +98,32 @@
     end
 
     if is_folder
-      graph << [uri, RDF.type, RDF::URI("http://purl.org/wf4ever/ro#Resource")]
-      graph << [uri, RDF.type, RDF::URI("http://purl.org/wf4ever/ro#Folder")]
-      graph << [uri, RDF.type, RDF::URI("http://www.openarchives.org/ore/terms/AggregatedResource")]
-      graph << [uri, RDF.type, RDF::URI("http://www.openarchives.org/ore/terms/Aggregation")]
+      graph << [uri, RDF.type, RO.Resource]
+      graph << [uri, RDF.type, RO.Folder]
+      graph << [uri, RDF.type, ORE.AggregatedResource]
+      graph << [uri, RDF.type, ORE.Aggregation]
 
       resource_map = Resource.find(:first, :conditions => { :path => resource_map_path })
 
-      graph << [uri, RDF::URI("http://www.openarchives.org/ore/terms/isDescribedBy"), ro_uri.join(resource_map_path)]
+      graph << [uri, ORE.isDescribedBy, ro_uri.join(resource_map_path)]
     end
 
-    graph << [uri, RDF::DC.created, created_at.to_datetime]
-    graph << [uri, RDF::DC.creator, RDF::URI(creator_uri)] if creator_uri
-    graph << [uri, RDF::URI("http://purl.org/wf4ever/ro#name"), name] if name
+    if is_folder_entry
+      graph << [uri, RDF.type,     ORE.Proxy]
+      graph << [uri, RDF.type,     RO.FolderEntry]
+      graph << [uri, ORE.proxyIn,  ro_uri.join(proxy_in_path)]
+      graph << [uri, ORE.proxyFor, ro_uri.join(proxy_for_path)]
+    end
 
+    name = path.split("/").last if path
+
+    graph << [uri, RDF::DC.created, created_at.to_datetime] if created_at
+    graph << [uri, RDF::DC.creator, RDF::URI(creator_uri)]  if creator_uri
+    graph << [uri, RO["name"],      name]                   if name
+
     if content_blob && !is_manifest?
-      graph << [uri, RDF::URI("http://purl.org/wf4ever/ro#filesize"), content_blob.size]
-      graph << [uri, RDF::URI("http://purl.org/wf4ever/ro#checksum"), RDF::URI("urn:MD5:#{content_blob.md5}")]
+      graph << [uri, RO.filesize, content_blob.size] if content_blob.size
+      graph << [uri, RO.checksum, RDF::URI("urn:MD5:#{content_blob.md5}")]
     end
 
     graph
@@ -124,25 +137,21 @@
     RDF::URI(research_object.uri) + path
   end
 
-  def generate_proxy(proxy_path = ".ro/proxies/#{SecureRandom.uuid}")
-
-    ro_uri    = RDF::URI(research_object.uri)
-    proxy_uri = RDF::URI(research_object.uri) + proxy_path
-
-    graph = RDF::Graph.new
-    graph << [proxy_uri, RDF.type,     ORE.Proxy]
-    graph << [proxy_uri, ORE.proxyIn,  ro_uri]
-    graph << [proxy_uri, ORE.proxyFor, resource_uri]
-
-    graph
-  end
-
   def update_graph!
 
     new_description = create_rdf_xml { |graph| graph << description }
 
     content_blob.destroy if content_blob
-    content_blob = ContentBlob.new(:data ="" new_description)
-    content_blob.save
+    update_attribute(:content_blob, ContentBlob.new(:data ="" new_description))
   end
+
+  def copy_metadata
+    if content_blob
+      self.sha1 = content_blob.calc_sha1
+      self.size = content_blob.calc_size
+    else
+      self.sha1 = nil
+      self.size = nil
+    end
+  end
 end

Modified: branches/packs/db/migrate/20130520145900_create_research_objects.rb (3568 => 3569)


--- branches/packs/db/migrate/20130520145900_create_research_objects.rb	2013-05-23 14:38:23 UTC (rev 3568)
+++ branches/packs/db/migrate/20130520145900_create_research_objects.rb	2013-05-24 16:49:10 UTC (rev 3569)
@@ -16,11 +16,9 @@
     end
 
     create_table "resources" do |t|
-      t.string  "name"
       t.integer "research_object_id"
       t.integer "content_blob_id"
       t.string  "sha1", :limit => 40
-      t.binary  "data", :limit => 2147483647
       t.integer "size"
       t.string  "content_type"
       t.text    "path"
@@ -44,6 +42,7 @@
     end
 
     create_table "annotation_resources" do |t|
+      t.integer "research_object_id"
       t.integer "annotation_id"
       t.string  "resource_path"
     end

Modified: branches/packs/db/schema.rb (3568 => 3569)


--- branches/packs/db/schema.rb	2013-05-23 14:38:23 UTC (rev 3568)
+++ branches/packs/db/schema.rb	2013-05-24 16:49:10 UTC (rev 3569)
@@ -43,6 +43,7 @@
   end
 
   create_table "annotation_resources", :force => true do |t|
+    t.integer "research_object_id"
     t.integer "annotation_id"
     t.string  "resource_path"
   end
@@ -65,6 +66,11 @@
     t.datetime "updated_at"
   end
 
+  create_table "auto_tables", :force => true do |t|
+    t.string "name"
+    t.text   "schema"
+  end
+
   create_table "blob_versions", :force => true do |t|
     t.integer  "blob_id"
     t.integer  "version"
@@ -522,6 +528,11 @@
     t.integer "user_id"
   end
 
+  create_table "plugin_schema_info", :id => false, :force => true do |t|
+    t.string  "plugin_name"
+    t.integer "version"
+  end
+
   create_table "policies", :force => true do |t|
     t.integer  "contributor_id"
     t.string   "contributor_type"
@@ -611,7 +622,6 @@
   end
 
   create_table "resources", :force => true do |t|
-    t.string   "name"
     t.integer  "research_object_id"
     t.integer  "content_blob_id"
     t.string   "sha1",               :limit => 40
@@ -899,8 +909,6 @@
     t.text     "body_html"
     t.datetime "created_at"
     t.datetime "updated_at"
-    t.string   "license"
-    t.integer  "preview_id"
     t.string   "image"
     t.string   "svg"
     t.text     "revision_comments"
@@ -908,6 +916,8 @@
     t.string   "file_ext"
     t.string   "last_edited_by"
     t.integer  "content_type_id"
+    t.string   "license"
+    t.integer  "preview_id"
   end
 
   add_index "workflow_versions", ["workflow_id"], :name => "index_workflow_versions_on_workflow_id"
@@ -921,15 +931,15 @@
     t.string   "unique_name"
     t.text     "body"
     t.text     "body_html"
-    t.integer  "current_version"
-    t.integer  "preview_id"
     t.datetime "created_at"
     t.datetime "updated_at"
+    t.integer  "current_version"
     t.integer  "content_blob_id"
     t.string   "file_ext"
     t.string   "last_edited_by"
     t.integer  "content_type_id"
     t.integer  "license_id"
+    t.integer  "preview_id"
   end
 
   create_table "wsdl_deprecations", :force => true do |t|

Modified: branches/packs/test/functional/research_objects_test.rb (3568 => 3569)


--- branches/packs/test/functional/research_objects_test.rb	2013-05-23 14:38:23 UTC (rev 3568)
+++ branches/packs/test/functional/research_objects_test.rb	2013-05-24 16:49:10 UTC (rev 3569)
@@ -1,3 +1,8 @@
+# myExperiment: test/functional/research_objects_test.rb
+#
+# Copyright (c) 2007-2013 The University of Manchester, the University of
+# Oxford, and the University of Southampton.  See license.txt for details.
+
 require_relative '../test_helper'
 
 class ResearchObjectsTest < ActionController::IntegrationTest
@@ -185,7 +190,7 @@
         ])
   end
 
-  test "Disallow overwriting of the manifest" do
+  test "disallow overwriting of the manifest" do
 
     # Create the test RO.
 
@@ -198,7 +203,7 @@
     assert_response :forbidden
   end
 
-  test "Creation of a proxy for an external resource" do
+  test "creation of a proxy for an external resource" do
 
     # Create the test RO.
 
@@ -258,7 +263,7 @@
     assert_equal 1, manifest_graph.query([RDF::URI(proxy_uri), ORE.proxyIn, RDF::URI(ro_uri)]).count
   end
 
-  test "Creation of a folder" do
+  test "creation of a folder" do
 
     # Create the test RO.
 
@@ -320,7 +325,7 @@
     assert_equal 1, manifest_graph.query([resource_map_uri, ORE.describes, test_folder_uri]).count
   end
 
-  test "Creation of a folder entry" do
+  test "creation of a folder entry" do
 
     # Create the test RO.
 

reply via email to

[Prev in Thread] Current Thread [Next in Thread]