myexperiment-hackers
[Top][All Lists]
Advanced

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

[myexperiment-hackers] [3254] trunk: Merged components and snapshots bra


From: noreply
Subject: [myexperiment-hackers] [3254] trunk: Merged components and snapshots branches into trunk
Date: Wed, 12 Dec 2012 14:03:54 +0000 (UTC)

Revision
3254
Author
fbacall
Date
2012-12-12 14:03:54 +0000 (Wed, 12 Dec 2012)

Log Message

Merged components and snapshots branches into trunk

Modified Paths

Added Paths

Diff

Modified: trunk/Gemfile (3253 => 3254)


--- trunk/Gemfile	2012-12-12 11:49:45 UTC (rev 3253)
+++ trunk/Gemfile	2012-12-12 14:03:54 UTC (rev 3254)
@@ -17,8 +17,9 @@
 gem "passenger", "~> 2.2.15"
 gem "htmlentities", "~> 4.3.1"
 gem "taverna-scufl", "~> 0.7.2"
-gem "taverna-t2flow", "~> 0.3.0"
-gem "workflow-to-galaxy", "~> 0.3.4"
+gem "taverna-t2flow", "~> 0.4.0"
+gem "workflow-to-galaxy", "~> 0.3.5"
 gem "rdf", "~> 0.3.4.1"
 gem "rdf-raptor", "~> 0.4.1"
+gem "rdf-n3"
 

Modified: trunk/app/controllers/content_types_controller.rb (3253 => 3254)


--- trunk/app/controllers/content_types_controller.rb	2012-12-12 11:49:45 UTC (rev 3253)
+++ trunk/app/controllers/content_types_controller.rb	2012-12-12 14:03:54 UTC (rev 3254)
@@ -12,8 +12,13 @@
 
     params[:num] = 25 unless params[:num]
 
-    @content_types = ContentType.find(:all, :order => 'title ASC',
-        :page => { :size => params[:num], :current => params[:page] })
+    if params[:mime_type]
+      @content_types = ContentType.find_all_by_mime_type(params[:mime_type], :order => 'title ASC',
+          :page => { :size => params[:num], :current => params[:page] })
+    else
+      @content_types = ContentType.find(:all, :order => 'title ASC',
+          :page => { :size => params[:num], :current => params[:page] })
+    end
   end
 
   # GET /content_types/1

Modified: trunk/app/controllers/packs_controller.rb (3253 => 3254)


--- trunk/app/controllers/packs_controller.rb	2012-12-12 11:49:45 UTC (rev 3253)
+++ trunk/app/controllers/packs_controller.rb	2012-12-12 14:03:54 UTC (rev 3254)
@@ -403,6 +403,24 @@
     end
   end
   
+  def snapshot
+
+    success = @pack.snapshot!
+
+    respond_to do |format|
+      format.html {
+        if success
+          @pack.reload
+          flash[:notice] = 'Pack snapshot was successfully created.'
+          redirect_to pack_version_path(@pack, @pack.versions.last.version)
+        else
+          flash[:error] = 'There was a problem with creating the snapshot.'
+          redirect_to pack_path(@pack)
+        end
+      }
+    end
+  end
+
   protected
   
   # Check that a protocol is specified in the URI; prepend HTTP:// otherwise
@@ -438,7 +456,8 @@
       "statistics"       => "view",
       "tag"              => "view",
       "update"           => "edit",
-      "update_item"      => "edit"
+      "update_item"      => "edit",
+      "snapshot"         => "edit"
     }
 
     begin
@@ -447,6 +466,8 @@
       if Authorization.check(action_permissions[action_name], pack, current_user)
         @pack = pack
         
+        @version = @pack.find_version(params[:version]) if params[:version]
+
         @authorised_to_edit = logged_in? && Authorization.check("edit", @pack, current_user)
         @authorised_to_download = Authorization.check("download", @pack, current_user)
         

Modified: trunk/app/helpers/application_helper.rb (3253 => 3254)


--- trunk/app/helpers/application_helper.rb	2012-12-12 11:49:45 UTC (rev 3253)
+++ trunk/app/helpers/application_helper.rb	2012-12-12 14:03:54 UTC (rev 3254)
@@ -230,25 +230,14 @@
     link_to("Request Friendship", new_user_friendship_url(:user_id => user_id))
   end
   
-  def versioned_workflow_link(workflow_id, version_number, long_description=true)
-    if workflow_id.kind_of? Fixnum
-      workflow = Workflow.find(:first, :conditions => ["id = ?", workflow_id])
-      return nil unless workflow
-    elsif workflow_id.kind_of? Workflow
-      workflow = workflow_id
+  def versioned_resource_link(resource, version_number, long_description=true)
+    ver = resource.find_version(version_number)
+    if ver
+      url = "" :version => version_number)
     else
       return nil
     end
     
-    if (ver = workflow.find_version(version_number))
-      url = "" => 'workflows',
-                    :action ="" 'show',
-                    :id => workflow.id,
-                    :version => version_number)
-    else
-      return nil
-    end
-    
     return nil unless url
     
     if long_description
@@ -1485,7 +1474,7 @@
           next unless (workflow.contributor_type.to_s == restrict_contributor.class.to_s and workflow.contributor_id.to_i == restrict_contributor.id.to_i)
         end
         
-        rtn << [workflow.updated_at, "#{editor} edited the #{versioned_workflow_link(item.id, workflow.version, false)} Workflow."]
+        rtn << [workflow.updated_at, "#{editor} edited the #{versioned_resource_link(item, workflow.version, false)} Workflow."]
       end
     when "PictureSelection"
       return rtn if before and item.created_at > before

Modified: trunk/app/models/blob.rb (3253 => 3254)


--- trunk/app/models/blob.rb	2012-12-12 11:49:45 UTC (rev 3253)
+++ trunk/app/models/blob.rb	2012-12-12 14:03:54 UTC (rev 3254)
@@ -44,6 +44,7 @@
   validates_presence_of :content_type
 
   validates_presence_of :title
+  validates_presence_of :local_name
 
   validates_each :content_blob do |record, attr, value|
     if value.data.size > Conf.max_upload_size

Modified: trunk/app/models/pack.rb (3253 => 3254)


--- trunk/app/models/pack.rb	2012-12-12 11:49:45 UTC (rev 3253)
+++ trunk/app/models/pack.rb	2012-12-12 14:03:54 UTC (rev 3254)
@@ -24,6 +24,15 @@
 
   has_many :relationships, :dependent => :destroy, :as => :context
 
+  has_many :versions, :class_name => "PackVersion"
+
+  def find_version(version)
+    match = versions.find(:first, :conditions => ["version = ?", version])
+    return match if match
+
+    raise ActiveRecord::RecordNotFound.new("Couldn't find Pack with pack_id=#{id} and version=#{version}")
+  end
+
   validates_presence_of :title
   
   format_attribute :description
@@ -35,17 +44,19 @@
   has_many :contributable_entries,
            :class_name => "PackContributableEntry",
            :foreign_key => :pack_id,
+           :conditions => "version IS NULL",
            :order => "created_at DESC",
            :dependent => :destroy
   
   has_many :remote_entries,
            :class_name => "PackRemoteEntry",
            :foreign_key => :pack_id,
+           :conditions => "version IS NULL",
            :order => "created_at DESC",
            :dependent => :destroy
   
   def items_count
-    return contributable_entries.count + remote_entries.count
+    contributable_entries.count + remote_entries.count
   end
   
   # returns packs that have largest total number of items
@@ -631,6 +642,58 @@
     APIStatistics.statistics(self)
   end
  
+  def snapshot!
+  
+    self.current_version = self.current_version ? self.current_version + 1 : 1
+
+    inhibit_timestamps do
+ 
+      version = versions.build(
+          :version          => current_version,
+          :contributor      => contributor,
+          :title            => title,
+          :description      => description,
+          :description_html => description_html)
+
+      contributable_entries.each do |entry|
+
+        version.contributable_entries.build(
+            :pack => self,
+            :contributable_id => entry.contributable_id,
+            :contributable_type => entry.contributable_type,
+            :contributable_version => entry.contributable_version,
+            :comment => entry.comment,
+            :user_id => entry.user_id,
+            :version => current_version,
+            :created_at => entry.created_at,
+            :updated_at => entry.updated_at)
+      end
+
+      remote_entries.each do |entry|
+
+        tt = version.remote_entries.build(
+            :pack => self,
+            :title => entry.title,
+            :uri => entry.uri,
+            :alternate_uri => entry.alternate_uri,
+            :comment => entry.comment,
+            :user_id => entry.user_id,
+            :version => current_version,
+            :created_at => entry.created_at,
+            :updated_at => entry.updated_at)
+      end
+    end
+    
+    save
+  end
+
+  def describe_version(version_number)
+    return "" if versions.count < 2
+    return "(earliest)" if version_number == versions.first.version
+    return "(latest)" if version_number == versions.last.version
+    return ""
+  end
+
   protected
   
   # produces html string containing the required messaged, enclosed within left-padded P tag, belonging to 'none_text' class

Modified: trunk/app/models/pack_contributable_entry.rb (3253 => 3254)


--- trunk/app/models/pack_contributable_entry.rb	2012-12-12 11:49:45 UTC (rev 3253)
+++ trunk/app/models/pack_contributable_entry.rb	2012-12-12 14:03:54 UTC (rev 3254)
@@ -21,12 +21,26 @@
   after_destroy :touch_pack
 
   def check_unique
-    if self.contributable_version.blank?
-      i = PackContributableEntry.find(:first, :conditions => ["pack_id = ? AND contributable_type = ? AND contributable_id = ? AND contributable_version IS NULL", self.pack_id, self.contributable_type, self.contributable_id]) 
+
+    conditions = ["pack_id = ?", "version = ?", "contributable_type = ?", "contributable_id = ?"]
+    arguments = [self.pack_id, self.version, self.contributable_type, self.contributable_id]
+    
+    if self.contributable_version.nil?
+      conditions << "contributable_version IS NULL"
     else
-      i = PackContributableEntry.find(:first, :conditions => ["pack_id = ? AND contributable_type = ? AND contributable_id = ? AND contributable_version = ?", self.pack_id, self.contributable_type, self.contributable_id, self.contributable_version])
+      conditions << "contributable_version = ?"
+      arguments << self.contributable_version
     end
-    
+
+    if self.version.nil?
+      conditions << "version IS NULL"
+    else
+      conditions << "version = ?"
+      arguments << self.version
+    end
+
+    i = PackContributableEntry.find(:first, :conditions => [conditions.join(" AND ")] + arguments) 
+ 
     if i
       errors.add_to_base("This item already exists in the pack")
       return false

Modified: trunk/app/models/pack_remote_entry.rb (3253 => 3254)


--- trunk/app/models/pack_remote_entry.rb	2012-12-12 11:49:45 UTC (rev 3253)
+++ trunk/app/models/pack_remote_entry.rb	2012-12-12 14:03:54 UTC (rev 3254)
@@ -19,7 +19,7 @@
   after_destroy :touch_pack
 
   def check_unique
-    if PackRemoteEntry.find(:first, :conditions => ["pack_id = ? AND uri = ?", self.pack_id, self.uri])
+    if PackRemoteEntry.find(:first, :conditions => ["pack_id = ? AND version = ? AND uri = ?", self.pack_id, self.version, self.uri])
       errors.add_to_base("This external link already exists in the pack")
       return false
     else

Copied: trunk/app/models/pack_version.rb (from rev 3253, branches/components/app/models/pack_version.rb) (0 => 3254)


--- trunk/app/models/pack_version.rb	                        (rev 0)
+++ trunk/app/models/pack_version.rb	2012-12-12 14:03:54 UTC (rev 3254)
@@ -0,0 +1,50 @@
+# myExperiment: app/models/pack_version.rb
+#
+# Copyright (c) 2012 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+class PackVersion < ActiveRecord::Base
+
+  validates_presence_of :title
+
+  belongs_to :pack
+  belongs_to :contributor, :polymorphic => true
+
+  format_attribute :description
+
+  has_many :contributable_entries,
+           :class_name => "PackContributableEntry",
+           :dependent => :destroy,
+           :finder_sql =>
+              'SELECT *
+               FROM pack_contributable_entries
+               WHERE pack_id = #{pack_id} AND version = #{version}
+               ORDER BY created_at DESC'
+  
+  has_many :remote_entries,
+           :class_name => "PackRemoteEntry",
+           :dependent => :destroy,
+           :finder_sql =>
+              'SELECT *
+               FROM pack_remote_entries
+               WHERE pack_id = #{pack_id} AND version = #{version}
+               ORDER BY created_at DESC'
+
+  def items_count
+    contributable_entries.count + remote_entries.count
+  end
+  
+  def versioned_resource
+    pack
+  end
+
+  def items_count
+    return contributable_entries.count + remote_entries.count
+  end
+
+  def contributables
+    contributable_entries.map do |e| e.contributable end
+  end
+  
+end
+

Copied: trunk/app/models/semantic_annotation.rb (from rev 3253, branches/components/app/models/semantic_annotation.rb) (0 => 3254)


--- trunk/app/models/semantic_annotation.rb	                        (rev 0)
+++ trunk/app/models/semantic_annotation.rb	2012-12-12 14:03:54 UTC (rev 3254)
@@ -0,0 +1,3 @@
+class SemanticAnnotation < ActiveRecord::Base
+  belongs_to :subject, :polymorphic => true
+end

Modified: trunk/app/models/workflow.rb (3253 => 3254)


--- trunk/app/models/workflow.rb	2012-12-12 11:49:45 UTC (rev 3253)
+++ trunk/app/models/workflow.rb	2012-12-12 14:03:54 UTC (rev 3254)
@@ -26,6 +26,8 @@
   belongs_to :license
 
   has_many :workflow_processors, :dependent => :destroy
+  has_many :workflow_ports, :dependent => :destroy
+  has_many :semantic_annotations, :as => :subject, :dependent => :destroy
 
   before_validation :check_unique_name
   before_validation :apply_extracted_metadata
@@ -325,7 +327,7 @@
     if processor_class
       delete_metadata
       begin
-        processor_class.new(content_blob.data).extract_metadata(id)
+        processor_class.new(content_blob.data).extract_metadata(self)
       rescue
       end
     end

Copied: trunk/app/models/workflow_port.rb (from rev 3253, branches/components/app/models/workflow_port.rb) (0 => 3254)


--- trunk/app/models/workflow_port.rb	                        (rev 0)
+++ trunk/app/models/workflow_port.rb	2012-12-12 14:03:54 UTC (rev 3254)
@@ -0,0 +1,5 @@
+class WorkflowPort < ActiveRecord::Base
+  validates_inclusion_of :port_type, :in => ["input", "output"]
+  belongs_to :workflow
+  has_many :semantic_annotations, :as => :subject, :dependent => :destroy
+end

Modified: trunk/app/models/workflow_processor.rb (3253 => 3254)


--- trunk/app/models/workflow_processor.rb	2012-12-12 11:49:45 UTC (rev 3253)
+++ trunk/app/models/workflow_processor.rb	2012-12-12 14:03:54 UTC (rev 3254)
@@ -5,5 +5,6 @@
 
 class WorkflowProcessor < ActiveRecord::Base
   belongs_to :workflow
+  has_many :semantic_annotations, :as => :subject, :dependent => :destroy
 end
 

Modified: trunk/app/views/gadgets/_asset_manager.rhtml (3253 => 3254)


--- trunk/app/views/gadgets/_asset_manager.rhtml	2012-12-12 11:49:45 UTC (rev 3253)
+++ trunk/app/views/gadgets/_asset_manager.rhtml	2012-12-12 14:03:54 UTC (rev 3254)
@@ -11,7 +11,7 @@
 				<%= link_to(pluralize(current_user.networks_owned.length + current_user.networks.length, "Group"), currentusers_things_url('groups')) %>
 				<% filter_contributables(current_user.contributions).each do |klass,contributables| %>
 					<span style="color:#999999;">|</span> 
-					<%= link_to(pluralize(contributables.length, controller_visible_name(klass.humanize.pluralize)), currentusers_things_url(controller_visible_name(klass.humanize.pluralize).downcase)) %>
+					<%= link_to(pluralize(contributables.length, controller_visible_name(klass.humanize.pluralize).singularize), currentusers_things_url(controller_visible_name(klass.humanize.pluralize).downcase)) %>
 				<% end %>
       </small>
      </p>

Modified: trunk/app/views/packs/_items.rhtml (3253 => 3254)


--- trunk/app/views/packs/_items.rhtml	2012-12-12 11:49:45 UTC (rev 3253)
+++ trunk/app/views/packs/_items.rhtml	2012-12-12 14:03:54 UTC (rev 3254)
@@ -10,7 +10,7 @@
 		<ul id="packItemsList">
 			
 			<!-- Contributable Item Entries -->
-			<% pack.contributable_entries.each do |e| %>
+			<% contributable_entries.each do |e| %>
 				<% show = e.available? ? Authorization.check("view", e.contributable, current_user) : false -%>
 				<li>
 					<table>
@@ -37,8 +37,7 @@
 									
 										<b><%= visible_name(e.contributable_type) -%>:</b>
 										<% unless e.contributable_version.blank? -%>
-											<% # HACK: only workflows are versioned at the moment -%>
-											<%= versioned_workflow_link e.contributable_id, e.contributable_version, false -%>
+											<%= versioned_resource_link e.contributable, e.contributable_version, false -%>
 											<% if false %><span style="color: #666666;">(version <%= e.contributable_version -%>)</span><% end %>
 										<% else -%>
 											<%= contributable(e.contributable_id, e.contributable_type) %>
@@ -98,7 +97,7 @@
 			<% end -%>
 			
 			<!-- Remote Item Entries -->
-			<% pack.remote_entries.each do |e| %>
+			<% remote_entries.each do |e| %>
 				<li>
 					<table>
 						<tr>

Copied: trunk/app/views/packs/_version_selector.rhtml (from rev 3253, branches/components/app/views/packs/_version_selector.rhtml) (0 => 3254)


--- trunk/app/views/packs/_version_selector.rhtml	                        (rev 0)
+++ trunk/app/views/packs/_version_selector.rhtml	2012-12-12 14:03:54 UTC (rev 3254)
@@ -0,0 +1,82 @@
+<script type="text/_javascript_">
+  function showVersion(form) {
+    var url = ""
+		location.href = ""
+		form.submit
+  }
+</script>
+
+<div class="contribution_version_selector_box">
+
+  <table>
+    <tbody>
+      <tr>
+        <td class="heading" style="vertical-align: top;">
+          <% if version %>
+            <%= info_icon_with_tooltip("This box shows version #{version.version.to_s} for this entry") -%>
+            <span><%= "Version #{version.version.to_s} #{resource.describe_version(version.version)}" -%></span>
+            <span class="count_text">(of <%= resource.versions.length -%>)</span>
+          <% else %>
+            <%= info_icon_with_tooltip("This box shows the live version for this entry") -%>
+            <span>Live view</span>
+            <% if resource.versions.length > 0 %>
+              <span class="count_text">(<%= resource.versions.length -%> versions available)</span>
+            <% end %>
+          <% end %>
+          <a name="versions"></a>
+        </td>
+        <td>
+          <% if resource.versions.length > 0 %>
+             <form  return false;" style="text-align: right;">
+              <b>View version: </b>
+              <select id="resource_versions" 
+                <option value="<%= polymorphic_path(resource) %>" <%= "selected" if version.nil? -%>>Live view</option>
+                <% resource.versions.reverse.each do |v| %>
+                  <option value="<%= send(path, resource, v.version.to_s) %>" <%= "selected" if !version.nil? && v.version == version.version -%>>
+                      <%= "#{v.version.to_s} #{resource.describe_version(v.version)}" %>
+                  </option>
+                <% end %>
+              </select>
+            </form>
+          <% end %>
+        </td>
+      </tr>
+    </tbody>
+  </table>
+      
+  <% if version %>
+    <div id="version_info_box" style="color: #666666;  font-size: 85%; margin: 0.6em 0.5em 0.2em 0.5em; border-top: 1px solid #DDDDDD; padding-top: 0.4em;">
+      <p style="text-align: center;">
+        <b>Version created on:</b>
+        <span><%= datetime version.created_at, false %></span>
+        <% if version.respond_to?(:contributor_id) && version.respond_to?(:contributor_type) %>
+          <b>by:</b>
+          <span><%= contributor(version.contributor_id, version.contributor_type) %></span>
+        <% end %>
+        <% if !version.revision_comments.blank? %>
+          <span>&nbsp;&nbsp;|&nbsp;&nbsp;</span>
+          <span><%= link_to_function "Revision comment " + expand_image, visual_effect(:toggle_blind, "version_info_box_comments", :duration => 0.3) %></span>
+        <% end %>
+      </p>
+      
+      <% unless version.created_at == version.updated_at %>
+        <p style="text-align: center;">
+          <b>Last edited on:</b>
+          <span><%= datetime version.updated_at, false %></span>
+          <% if version.respond_to?(:last_edited_by) %>
+            <b>by:</b>
+            <span><%= contributor(version.last_edited_by, "User") %></span>
+          <% end %>
+        </p>
+      <% end %>
+    </div>
+  <% end %>
+  
+  <% if version && !version.revision_comments.blank? -%>
+    <div id="version_info_box_comments" style="display: none; border: 1px dotted #CCCCCC; padding: 0.3em 0.5em;">
+      <%= white_list version.revision_comments %>
+    </div>
+  <% end %>
+
+</div>
+

Modified: trunk/app/views/packs/show.rhtml (3253 => 3254)


--- trunk/app/views/packs/show.rhtml	2012-12-12 11:49:45 UTC (rev 3253)
+++ trunk/app/views/packs/show.rhtml	2012-12-12 14:03:54 UTC (rev 3254)
@@ -1,10 +1,17 @@
 <% t "#{contributable_name(@pack.id, 'Pack')} (#{h @pack.contributor_name})" -%>
 
+<% items_count = @version ? @version.items_count : @pack.items_count %>
+<% contributable_entries = @version ? @version.contributable_entries : @pack.contributable_entries %>
+<% remote_entries        = @version ? @version.remote_entries        : @pack.remote_entries        %>
+
 <% if @authorised_to_edit %>
 	<ul class="sectionIcons">
 		<% if mine?(@pack) -%>
 			<li><%= icon('manage', edit_pack_path(@pack), nil, nil, 'Manage Pack') -%></li>
 		<% end -%>
+    <% if @authorised_to_edit -%>
+			<li><%= icon('new', snapshot_pack_path(@pack), nil, { :confirm => 'Are you sure that you would like to create a new snapshot of this Pack?', :method => :post }, 'Create snapshot') %></li>
+    <% end -%>	
 		<% if Authorization.check("destroy", @pack, current_user) %>
 			<li><%= icon('destroy', pack_path(@pack), nil, { :confirm => 'This deletes the Pack and all metadata such as tags and comments, BUT does not delete the actual items pointed to in the Pack. Are you sure you would like to delete this Pack?', :method => :delete }, 'Delete Pack') %></li>
 		<% end %>
@@ -37,6 +44,9 @@
 
 <div class="contribution_left_box">
 	<div class="contribution_version_box">
+
+    <%= render(:partial => "packs/version_selector", :locals => { :resource => @pack, :version => @version, :path => :pack_version_path }) %>
+
 		<div class="contribution_version_inner_box">
 			<p>
 		    <b>Title:</b>
@@ -76,10 +86,10 @@
 				<% end %>
 				
 				<%= info_icon_with_tooltip("This section shows all the items that are pointed to in this pack. This can be a combination of internal and external items.") -%>
-				Items <span class="count_text">(<%= @pack.items_count -%>)</span>
+				Items <span class="count_text">(<%= items_count -%>)</span>
 			</h4>
 			
-			<%= render :partial => "items", :locals => { :pack => @pack, :authorised_to_edit => @authorised_to_edit } -%>
+			<%= render :partial => "items", :locals => { :pack => @pack, :contributable_entries => contributable_entries, :remote_entries => remote_entries, :authorised_to_edit => @authorised_to_edit } -%>
 
 			<br/><br/>
 			<h4>
@@ -133,7 +143,7 @@
 	
 	<div class="contribution_section_box">
 		<p style="font-size: 108%;">
-		 	<b><%= pluralize @pack.items_count, "item" %> in this pack</b>
+		 	<b><%= pluralize items_count, "item" %> in this pack</b>
 		</p>
 	</div>
 	

Modified: trunk/config/default_settings.yml (3253 => 3254)


--- trunk/config/default_settings.yml	2012-12-12 11:49:45 UTC (rev 3253)
+++ trunk/config/default_settings.yml	2012-12-12 14:03:54 UTC (rev 3254)
@@ -544,6 +544,7 @@
     topic_workflow_map: INNER JOIN topic_workflow_map ON contributions.id = topic_workflow_map.workflow_id
     users: INNER JOIN users ON contributions.contributor_type = 'User' AND contributions.contributor_id = users.id
     licences: LEFT OUTER JOIN licenses ON contributions.license_id = licenses.id
+    component_profiles: LEFT OUTER JOIN workflows ON RESULT_TYPE = 'Workflow' AND workflows.id = RESULT_ID LEFT OUTER JOIN component_profiles ON workflows.component_profile_id = component_profiles.id
 
   order:
 
@@ -667,5 +668,11 @@
     label_column: services.monitor_label
     joins: [services]
 
+  - query_option: COMPONENT_PROFILE_ID
+    title: component profile
+    id_column: component_profiles.id
+    label_column: component_profiles.name
+    joins: [component_profiles]
+
   num_options: ["10", "20", "25", "50", "100"]
 

Modified: trunk/config/routes.rb (3253 => 3254)


--- trunk/config/routes.rb	2012-12-12 11:49:45 UTC (rev 3253)
+++ trunk/config/routes.rb	2012-12-12 14:03:54 UTC (rev 3254)
@@ -99,6 +99,7 @@
                  :download => :get,
                  :quick_add => :post,
                  :resolve_link => :post,
+                 :snapshot => :post,
                  :items => :get } do |pack|
     pack.resources :comments, :collection => { :timeline => :get }
     pack.resources :relationships, :collection => { :edit_relationships => :get }
@@ -136,6 +137,10 @@
   map.blob_version           '/files/:id/versions/:version',         :conditions => { :method => :get }, :controller => 'blobs', :action ="" 'show'
   map.formatted_blob_version '/files/:id/versions/:version.:format', :conditions => { :method => :get }, :controller => 'blobs', :action ="" 'show'
 
+  # pack redirect for linked data model
+  map.pack_version           '/packs/:id/versions/:version',         :conditions => { :method => :get }, :controller => 'packs', :action ="" 'show'
+  map.formatted_pack_version '/packs/:id/versions/:version.:format', :conditions => { :method => :get }, :controller => 'packs', :action ="" 'show'
+
   map.blob_version_suggestions '/files/:id/versions/:version/suggestions', :conditions => { :method => :get }, :controller => 'blobs', :action ="" 'suggestions'
   map.blob_version_process_suggestions '/files/:id/versions/:version/process_suggestions', :conditions => { :method => :post }, :controller => 'blobs', :action ="" 'process_suggestions'
 

Modified: trunk/config/schema.d/packs.xml (3253 => 3254)


--- trunk/config/schema.d/packs.xml	2012-12-12 11:49:45 UTC (rev 3253)
+++ trunk/config/schema.d/packs.xml	2012-12-12 14:03:54 UTC (rev 3254)
@@ -10,6 +10,7 @@
     <column type="text"     name="description_html"/>
     <column type="datetime" name="created_at"/>
     <column type="datetime" name="updated_at"/>
+    <column type="integer"  name="current_version"/>
 
   </table>
 
@@ -23,6 +24,7 @@
     <column type="integer"  name="user_id"               null="false"/>
     <column type="datetime" name="created_at"/>
     <column type="datetime" name="updated_at"/>
+    <column type="integer"  name="version"/>
 
   </table>
 
@@ -36,6 +38,7 @@
     <column type="integer"  name="user_id"       null="false"/>
     <column type="datetime" name="created_at"/>
     <column type="datetime" name="updated_at"/>
+    <column type="integer"  name="version"/>
 
   </table>
 

Modified: trunk/config/tables.xml


(Binary files differ)

Copied: trunk/db/migrate/098_create_pack_versions.rb (from rev 3253, branches/components/db/migrate/098_create_pack_versions.rb) (0 => 3254)


--- trunk/db/migrate/098_create_pack_versions.rb	                        (rev 0)
+++ trunk/db/migrate/098_create_pack_versions.rb	2012-12-12 14:03:54 UTC (rev 3254)
@@ -0,0 +1,33 @@
+# myExperiment: db/migrate/097_create_pack_versions.rb
+#
+# Copyright (c) 2012 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+class CreatePackVersions < ActiveRecord::Migration
+
+  def self.up
+    create_table :pack_versions do |t|
+      t.integer  "pack_id"
+      t.integer  "version"
+      t.text     "revision_comments"
+      t.string   "title"
+      t.text     "description"
+      t.text     "description_html"
+      t.datetime "created_at"
+      t.datetime "updated_at"
+    end
+
+    add_column :packs, :current_version, :integer
+    add_column :pack_contributable_entries, :version, :integer
+    add_column :pack_remote_entries, :version, :integer
+  end
+
+  def self.down
+    remove_column :packs, :current_version
+    remove_column :pack_contributable_entries, :version
+    remove_column :pack_remote_entries, :version
+
+    drop_table :pack_versions
+  end
+end
+

Copied: trunk/db/migrate/20121126093655_create_semantic_annotations.rb (from rev 3253, branches/components/db/migrate/20121126093655_create_semantic_annotations.rb) (0 => 3254)


--- trunk/db/migrate/20121126093655_create_semantic_annotations.rb	                        (rev 0)
+++ trunk/db/migrate/20121126093655_create_semantic_annotations.rb	2012-12-12 14:03:54 UTC (rev 3254)
@@ -0,0 +1,14 @@
+class CreateSemanticAnnotations < ActiveRecord::Migration
+  def self.up
+    create_table :semantic_annotations do |t|
+      t.integer :subject_id
+      t.string :subject_type
+      t.string :predicate
+      t.string :object
+    end
+  end
+
+  def self.down
+    drop_table :semantic_annotations
+  end
+end

Copied: trunk/db/migrate/20121126095828_create_workflow_ports.rb (from rev 3253, branches/components/db/migrate/20121126095828_create_workflow_ports.rb) (0 => 3254)


--- trunk/db/migrate/20121126095828_create_workflow_ports.rb	                        (rev 0)
+++ trunk/db/migrate/20121126095828_create_workflow_ports.rb	2012-12-12 14:03:54 UTC (rev 3254)
@@ -0,0 +1,13 @@
+class CreateWorkflowPorts < ActiveRecord::Migration
+  def self.up
+    create_table :workflow_ports do |t|
+      t.string :name
+      t.string :port_type
+      t.integer :workflow_id
+    end
+  end
+
+  def self.down
+    drop_table :workflow_ports
+  end
+end

Modified: trunk/db/schema.rb (3253 => 3254)


--- trunk/db/schema.rb	2012-12-12 11:49:45 UTC (rev 3253)
+++ trunk/db/schema.rb	2012-12-12 14:03:54 UTC (rev 3254)
@@ -9,7 +9,7 @@
 #
 # It's strongly recommended to check this file into your version control system.
 
-ActiveRecord::Schema.define(:version => 20121112134053) do
+ActiveRecord::Schema.define(:version => 20121126095828) do
 
   create_table "activity_limits", :force => true do |t|
     t.string   "contributor_type", :null => false
@@ -144,18 +144,18 @@
   add_index "comments", ["user_id"], :name => "index_comments_on_user_id"
 
   create_table "concept_relations", :force => true do |t|
+    t.string  "relation_type"
     t.integer "subject_concept_id"
     t.integer "object_concept_id"
-    t.string  "relation_type"
   end
 
   create_table "concepts", :force => true do |t|
-    t.text     "description"
     t.string   "phrase"
+    t.datetime "updated_at"
     t.text     "description_html"
     t.integer  "vocabulary_id"
+    t.text     "description"
     t.datetime "created_at"
-    t.datetime "updated_at"
   end
 
   create_table "content_blobs", :force => true do |t|
@@ -168,34 +168,34 @@
   add_index "content_blobs", ["sha1"], :name => "index_content_blobs_on_sha1"
 
   create_table "content_types", :force => true do |t|
+    t.string   "category"
+    t.string   "mime_type"
+    t.datetime "updated_at"
+    t.text     "description_html"
     t.integer  "user_id"
+    t.string   "title"
     t.text     "description"
-    t.string   "title"
-    t.string   "mime_type"
-    t.string   "category"
-    t.text     "description_html"
     t.datetime "created_at"
-    t.datetime "updated_at"
   end
 
   create_table "contributions", :force => true do |t|
+    t.integer  "site_downloads_count", :default => 0
     t.float    "rating"
-    t.integer  "site_viewings_count",  :default => 0
+    t.string   "contributable_type"
     t.integer  "contributable_id"
-    t.integer  "contributor_id"
-    t.integer  "policy_id"
-    t.float    "rank"
-    t.string   "label"
-    t.integer  "site_downloads_count", :default => 0
-    t.integer  "downloads_count",      :default => 0
     t.integer  "content_type_id"
+    t.integer  "site_viewings_count",  :default => 0
     t.integer  "viewings_count",       :default => 0
-    t.string   "contributable_type"
-    t.datetime "created_at"
+    t.datetime "updated_at"
+    t.string   "contributor_type"
+    t.integer  "downloads_count",      :default => 0
+    t.string   "label"
     t.string   "layout"
+    t.integer  "policy_id"
     t.integer  "license_id"
-    t.datetime "updated_at"
-    t.string   "contributor_type"
+    t.float    "rank"
+    t.integer  "contributor_id"
+    t.datetime "created_at"
   end
 
   add_index "contributions", ["contributable_id", "contributable_type"], :name => "index_contributions_on_contributable_id_and_contributable_type"
@@ -229,11 +229,11 @@
 
   create_table "downloads", :force => true do |t|
     t.integer  "user_id"
+    t.string   "kind"
     t.integer  "contribution_id"
-    t.string   "kind"
     t.boolean  "accessed_from_site", :default => false
+    t.string   "user_agent"
     t.datetime "created_at"
-    t.string   "user_agent"
   end
 
   add_index "downloads", ["contribution_id"], :name => "index_downloads_on_contribution_id"
@@ -307,10 +307,10 @@
 
   create_table "labels", :force => true do |t|
     t.integer "concept_id"
-    t.string  "label_type"
     t.string  "language"
     t.integer "vocabulary_id"
     t.string  "text"
+    t.string  "label_type"
   end
 
   create_table "license_attributes", :force => true do |t|
@@ -405,46 +405,60 @@
   add_index "oauth_tokens", ["token"], :name => "index_oauth_tokens_on_token", :unique => true
 
   create_table "ontologies", :force => true do |t|
+    t.datetime "updated_at"
+    t.text     "description_html"
+    t.integer  "user_id"
+    t.string   "title"
     t.string   "uri"
-    t.integer  "user_id"
     t.text     "description"
-    t.string   "title"
-    t.text     "description_html"
+    t.datetime "created_at"
     t.string   "prefix"
-    t.datetime "created_at"
-    t.datetime "updated_at"
   end
 
   create_table "pack_contributable_entries", :force => true do |t|
+    t.string   "contributable_type"
+    t.integer  "contributable_id",      :null => false
+    t.integer  "pack_id",               :null => false
+    t.datetime "updated_at"
+    t.integer  "contributable_version"
     t.integer  "user_id",               :null => false
-    t.integer  "contributable_id",      :null => false
     t.text     "comment"
-    t.string   "contributable_type"
+    t.integer  "version"
     t.datetime "created_at"
-    t.datetime "updated_at"
-    t.integer  "contributable_version"
-    t.integer  "pack_id",               :null => false
   end
 
   create_table "pack_remote_entries", :force => true do |t|
+    t.integer  "pack_id",       :null => false
+    t.datetime "updated_at"
     t.integer  "user_id",       :null => false
+    t.string   "alternate_uri"
     t.string   "uri"
-    t.string   "alternate_uri"
     t.string   "title"
     t.text     "comment"
+    t.integer  "version"
     t.datetime "created_at"
-    t.datetime "updated_at"
-    t.integer  "pack_id",       :null => false
   end
 
-  create_table "packs", :force => true do |t|
-    t.integer  "contributor_id"
+  create_table "pack_versions", :force => true do |t|
+    t.integer  "pack_id"
+    t.integer  "version"
+    t.text     "revision_comments"
+    t.string   "title"
     t.text     "description"
-    t.string   "title"
     t.text     "description_html"
     t.datetime "created_at"
     t.datetime "updated_at"
+  end
+
+  create_table "packs", :force => true do |t|
+    t.datetime "updated_at"
     t.string   "contributor_type"
+    t.text     "description_html"
+    t.integer  "current_version"
+    t.string   "title"
+    t.text     "description"
+    t.integer  "contributor_id"
+    t.datetime "created_at"
   end
 
   create_table "pending_invitations", :force => true do |t|
@@ -482,32 +496,32 @@
   end
 
   create_table "policies", :force => true do |t|
-    t.boolean  "public_download",  :default => false
-    t.integer  "contributor_id"
     t.string   "name"
+    t.integer  "share_mode"
+    t.datetime "updated_at"
+    t.string   "contributor_type"
     t.integer  "update_mode"
-    t.integer  "share_mode"
+    t.boolean  "public_download",  :default => false
     t.boolean  "public_view",      :default => false
+    t.integer  "contributor_id"
     t.datetime "created_at"
-    t.datetime "updated_at"
-    t.string   "contributor_type"
   end
 
   create_table "predicates", :force => true do |t|
+    t.string   "phrase"
+    t.datetime "updated_at"
+    t.text     "equivalent_to"
+    t.text     "description_html"
     t.integer  "ontology_id"
-    t.text     "equivalent_to"
+    t.string   "title"
     t.text     "description"
-    t.string   "title"
-    t.string   "phrase"
-    t.text     "description_html"
     t.datetime "created_at"
-    t.datetime "updated_at"
   end
 
   create_table "previews", :force => true do |t|
-    t.integer  "svg_blob_id"
     t.integer  "image_blob_id"
     t.datetime "created_at"
+    t.integer  "svg_blob_id"
   end
 
   create_table "profiles", :force => true do |t|
@@ -541,14 +555,14 @@
   add_index "ratings", ["user_id"], :name => "index_ratings_on_user_id"
 
   create_table "relationships", :force => true do |t|
+    t.string   "context_type"
+    t.integer  "context_id"
     t.string   "subject_type"
+    t.integer  "subject_id"
+    t.integer  "predicate_id"
     t.integer  "user_id"
     t.integer  "objekt_id"
-    t.integer  "predicate_id"
-    t.integer  "context_id"
     t.string   "objekt_type"
-    t.string   "context_type"
-    t.integer  "subject_id"
     t.datetime "created_at"
   end
 
@@ -571,85 +585,92 @@
 
   add_index "reviews", ["user_id"], :name => "index_reviews_on_user_id"
 
+  create_table "semantic_annotations", :force => true do |t|
+    t.integer "subject_id"
+    t.string  "subject_type"
+    t.string  "predicate"
+    t.string  "object"
+  end
+
   create_table "service_categories", :force => true do |t|
+    t.datetime "updated_at"
+    t.datetime "retrieved_at"
+    t.string   "label"
     t.string   "uri"
     t.integer  "service_id"
-    t.string   "label"
-    t.datetime "retrieved_at"
     t.datetime "created_at"
-    t.datetime "updated_at"
   end
 
   create_table "service_deployments", :force => true do |t|
-    t.integer  "service_id"
+    t.string   "endpoint"
+    t.datetime "created"
+    t.string   "submitter_uri"
+    t.string   "iso3166_country_code"
     t.string   "submitter_label"
-    t.string   "uri"
-    t.string   "iso3166_country_code"
-    t.integer  "service_provider_id"
+    t.string   "flag_url"
+    t.datetime "updated_at"
     t.string   "country"
-    t.datetime "created"
-    t.string   "flag_url"
-    t.string   "endpoint"
     t.string   "city"
     t.datetime "retrieved_at"
-    t.string   "submitter_uri"
+    t.integer  "service_provider_id"
+    t.string   "uri"
+    t.integer  "service_id"
     t.datetime "created_at"
-    t.datetime "updated_at"
   end
 
   create_table "service_providers", :force => true do |t|
+    t.datetime "created"
+    t.string   "name"
+    t.datetime "updated_at"
+    t.datetime "retrieved_at"
     t.string   "uri"
-    t.string   "name"
-    t.datetime "created"
     t.text     "description"
-    t.datetime "retrieved_at"
     t.datetime "created_at"
-    t.datetime "updated_at"
   end
 
   create_table "service_tags", :force => true do |t|
+    t.datetime "updated_at"
+    t.datetime "retrieved_at"
+    t.string   "label"
     t.string   "uri"
     t.integer  "service_id"
-    t.string   "label"
-    t.datetime "retrieved_at"
     t.datetime "created_at"
-    t.datetime "updated_at"
   end
 
   create_table "service_types", :force => true do |t|
+    t.datetime "updated_at"
+    t.datetime "retrieved_at"
+    t.string   "label"
     t.integer  "service_id"
-    t.string   "label"
-    t.datetime "retrieved_at"
     t.datetime "created_at"
-    t.datetime "updated_at"
   end
 
   create_table "services", :force => true do |t|
-    t.string   "submitter_label"
-    t.string   "uri"
+    t.string   "endpoint"
     t.string   "provider_label"
-    t.integer  "contributor_id"
+    t.string   "monitor_label"
     t.string   "iso3166_country_code"
+    t.string   "wsdl"
+    t.string   "submitter_uri"
+    t.datetime "created"
     t.string   "name"
-    t.string   "country"
     t.string   "monitor_small_symbol_url"
-    t.string   "monitor_symbol_url"
+    t.string   "documentation_uri"
+    t.string   "submitter_label"
+    t.datetime "monitor_last_checked"
+    t.string   "flag_url"
+    t.datetime "updated_at"
+    t.string   "contributor_type"
     t.text     "monitor_message"
+    t.string   "country"
+    t.string   "city"
+    t.datetime "retrieved_at"
+    t.string   "uri"
     t.text     "description"
-    t.string   "flag_url"
-    t.datetime "created"
-    t.string   "wsdl"
-    t.datetime "monitor_last_checked"
-    t.string   "monitor_label"
-    t.string   "endpoint"
-    t.string   "city"
+    t.integer  "contributor_id"
+    t.string   "monitor_symbol_url"
     t.string   "provider_uri"
-    t.datetime "retrieved_at"
-    t.string   "documentation_uri"
-    t.string   "submitter_uri"
     t.datetime "created_at"
-    t.datetime "updated_at"
-    t.string   "contributor_type"
   end
 
   create_table "sessions", :force => true do |t|
@@ -700,10 +721,10 @@
   end
 
   create_table "topic_feedbacks", :force => true do |t|
+    t.integer  "score"
+    t.integer  "topic_id"
+    t.datetime "submit_dt"
     t.integer  "user_id"
-    t.datetime "submit_dt"
-    t.integer  "topic_id"
-    t.integer  "score"
   end
 
   create_table "topic_runs", :force => true do |t|
@@ -712,31 +733,31 @@
   end
 
   create_table "topic_tag_map", :force => true do |t|
-    t.float   "probability"
     t.boolean "display_flag"
     t.integer "topic_id"
     t.integer "tag_id"
+    t.float   "probability"
   end
 
   create_table "topic_workflow_map", :force => true do |t|
+    t.boolean "display_flag"
+    t.integer "topic_id"
     t.integer "workflow_id"
     t.float   "probability"
-    t.boolean "display_flag"
-    t.integer "topic_id"
   end
 
   create_table "topics", :force => true do |t|
+    t.string  "name"
+    t.integer "orig_run_id"
     t.integer "run_id"
-    t.integer "orig_run_id"
-    t.string  "name"
   end
 
   create_table "user_reports", :force => true do |t|
+    t.text     "content"
     t.string   "subject_type"
+    t.integer  "subject_id"
     t.integer  "user_id"
-    t.text     "content"
     t.text     "report"
-    t.integer  "subject_id"
     t.datetime "created_at"
   end
 
@@ -775,21 +796,27 @@
   add_index "viewings", ["contribution_id"], :name => "index_viewings_on_contribution_id"
 
   create_table "vocabularies", :force => true do |t|
+    t.datetime "updated_at"
+    t.text     "description_html"
+    t.integer  "user_id"
+    t.string   "title"
     t.string   "uri"
-    t.integer  "user_id"
     t.text     "description"
-    t.string   "title"
-    t.text     "description_html"
+    t.datetime "created_at"
     t.string   "prefix"
-    t.datetime "created_at"
-    t.datetime "updated_at"
   end
 
+  create_table "workflow_ports", :force => true do |t|
+    t.string  "name"
+    t.string  "port_type"
+    t.integer "workflow_id"
+  end
+
   create_table "workflow_processors", :force => true do |t|
+    t.string  "wsdl_operation"
+    t.string  "wsdl"
+    t.string  "name"
     t.integer "workflow_id"
-    t.string  "name"
-    t.string  "wsdl"
-    t.string  "wsdl_operation"
   end
 
   create_table "workflow_versions", :force => true do |t|

Modified: trunk/lib/authorization.rb (3253 => 3254)


--- trunk/lib/authorization.rb	2012-12-12 11:49:45 UTC (rev 3253)
+++ trunk/lib/authorization.rb	2012-12-12 14:03:54 UTC (rev 3254)
@@ -85,6 +85,24 @@
             return true
         end
       
+      when "PackVersion"
+        case action
+          when "create"
+
+            # If a user can edit a pack, they can create a version of it.
+            is_authorized = Authorization.check('edit', context, user)
+
+          when "view"
+
+            # If a user can view a pack, they can view versions of it.
+            is_authorized = Authorization.check('view', context, user)
+
+          else
+            
+            # Editing or deleting versions of a pack is not allowed.
+            is_authorized = false
+        end
+
       when "Comment"
         case action
           when "create"

Modified: trunk/lib/rest.rb (3253 => 3254)


--- trunk/lib/rest.rb	2012-12-12 11:49:45 UTC (rev 3253)
+++ trunk/lib/rest.rb	2012-12-12 14:03:54 UTC (rev 3254)
@@ -190,7 +190,11 @@
           list_element[key] = value
         end
 
-        collection = eval("ob.#{model_data['Accessor'][i]}")
+        if query['version'] and model_data['Versioned'][i] == 'yes'
+          collection = eval(sprintf("ob.find_version(%d).%s", query['version'], model_data['Accessor'][i]))
+        else
+          collection = eval("ob.#{model_data['Accessor'][i]}")
+        end
 
         collection = [collection] if model_data['Encoding'][i] == 'item as list'
 
@@ -341,7 +345,7 @@
 end
 
 def find_entity_name_from_object(ob)
-  ob = ob.versioned_resource if ob.respond_to?(:version)
+  ob = ob.versioned_resource if ob.respond_to?(:versioned_resource)
   OBJECT_CLASS_TO_ENTITY_NAME[ob.class.name.underscore]
 end
 
@@ -383,6 +387,7 @@
   if query['version']
     return rest_response(400, :reason => "Object does not support versioning") unless ob.respond_to?('versions')
     return rest_response(404, :reason => "Specified version does not exist") if query['version'].to_i < 1
+    return rest_response(404, :reason => "Specified version does not exist") if query['version'].to_i > ob.versions.last.version
   end
 
   # Work out which elements to include in the response.
@@ -675,7 +680,7 @@
     when 'Experiment';             return experiment_url(ob)
     when 'TavernaEnactor';         return runner_url(ob)
     when 'Job';                    return experiment_job_url(ob.experiment, ob)
-    when 'PackContributableEntry'; return ob.contributable ? rest_resource_uri(ob.contributable) : nil
+    when 'PackContributableEntry'; return ob.contributable ? rest_resource_uri(ob.get_contributable_version) : nil
     when 'PackRemoteEntry';        return ob.uri
     when 'ContentType';            return content_type_url(ob)
     when 'License';                return license_url(ob)
@@ -683,12 +688,14 @@
     when 'Ontology';               return ontology_url(ob)
     when 'Predicate';              return predicate_url(ob)
     when 'Relationship';           return nil
+    when 'PackVersion';            return pack_version_url(ob, ob.version)
 
     when 'Creditation';     return nil
     when 'Attribution';     return nil
     when 'Tagging';         return nil
 
     when 'WorkflowVersion'; return "#{rest_resource_uri(ob.workflow)}?version=#{ob.version}"
+    when 'BlobVersion'; return "#{rest_resource_uri(ob.blob)}?version=#{ob.version}"
   end
 
   raise "Class not processed in rest_resource_uri: #{ob.class.to_s}"
@@ -733,6 +740,7 @@
     when 'Attribution';     return nil
 
     when 'WorkflowVersion'; return "#{base}/workflow.xml?id=#{ob.workflow.id}&version=#{ob.version}"
+    when 'PackVersion';     return "#{base}/pack.xml?id=#{ob.pack.id}&version=#{ob.version}"
   end
 
   raise "Class not processed in rest_access_uri: #{ob.class.to_s}"
@@ -955,21 +963,44 @@
 
       # handle public privileges
 
-      if permission.find_first('category/text()').to_s == 'public'
+      case permission.find_first('category/text()').to_s
+        when 'public'
+          privileges = {}
 
-        privileges = {}
+          permission.find('privilege').each do |el|
+            privileges[el['type']] = true
+          end
 
-        permission.find('privilege').each do |el|
-          privileges[el['type']] = true
-        end
+          if privileges["view"] && privileges["download"]
+            share_mode = 0
+          elsif privileges["view"]
+            share_mode = 2
+          else
+            share_mode = 7
+          end
+        when 'group'
+          id = permission.find_first('id/text()').to_s.to_i
+          privileges = {}
 
-        if privileges["view"] && privileges["download"]
-          share_mode = 0
-        elsif privileges["view"]
-          share_mode = 2
-        else
-          share_mode = 7
-        end
+          permission.find('privilege').each do |el|
+            privileges[el['type']] = true
+          end
+
+          network = Network.find_by_id(id)
+          if network.nil?
+            ob.errors.add_to_base("Couldn't share with group #{id} - Not found")
+            raise
+          else
+            Permission.create(:contributor => network,
+                              :policy => ob.contribution.policy,
+                              :view => privileges["view"],
+                              :download => privileges["download"],
+                              :edit => privileges["edit"])
+            unless (use_layout = permission.find_first('use-layout/text()')).nil?
+              ob.contribution.layout = network.layout_name if use_layout.to_s == 'true'
+              ob.contribution.save
+            end
+          end
       end
     end
 
@@ -1189,6 +1220,7 @@
     description      = parse_element(data, :text,   '/file/description')
     license_type     = parse_element(data, :text,   '/file/license-type')
     type             = parse_element(data, :text,   '/file/type')
+    filename         = parse_element(data, :text,   '/file/filename')
     content_type     = parse_element(data, :text,   '/file/content-type')
     content          = parse_element(data, :binary, '/file/content')
     revision_comment = parse_element(data, :text,   '/file/revision-comment')
@@ -1212,6 +1244,17 @@
         end
       end
     end
+
+    # file name
+
+    if filename && !filename.blank?
+      ob.local_name = filename
+    else
+      if ob.local_name.blank?
+        ob.errors.add("Filename", "missing")
+        return rest_response(400, :object => ob)
+      end
+    end
    
     # handle type
 
@@ -1290,7 +1333,22 @@
   case action
     when 'create':
       return rest_response(401, :reason => "Not authorised to create a pack") unless Authorization.check('create', Pack, opts[:user], nil)
-      ob = Pack.new(:contributor => opts[:user])
+      if id = opts[:query]['id']
+        ob = Pack.find_by_id(id)
+        if ob.nil?
+          return rest_response(404, :reason => "Couldn't find a Pack with id #{id}")
+        else
+          if Authorization.check('edit', ob, opts[:user])
+            ob.snapshot!
+            return rest_get_request(ob, opts[:user], { "id" => ob.id.to_s })
+          else
+            return rest_response(401, :reason => "Not authorised to snapshot pack #{id}")
+          end
+        end
+      else
+        ob = Pack.new(:contributor => opts[:user])
+      end
+
     when 'view', 'edit', 'destroy':
       ob, error = obtain_rest_resource('Pack', opts[:query]['id'], opts[:query]['version'], opts[:user], action)
     else
@@ -1427,6 +1485,9 @@
     pack          = parse_element(data, :resource, '/internal-pack-item/pack')
     item          = parse_element(data, :resource, '/internal-pack-item/item')
     comment       = parse_element(data, :text,     '/internal-pack-item/comment')
+
+    version_node  = data.find_first('/internal-pack-item/item/@version')
+    version       = version_node ? version_node.value.to_i : nil
   end
 
   # Obtain object
@@ -1440,7 +1501,8 @@
       ob = PackContributableEntry.new(:user => opts[:user],
           :pack          => pack,
           :contributable => item,
-          :comment       => comment)
+          :comment       => comment,
+          :contributable_version => version)
 
     when 'view', 'edit', 'destroy':
 
@@ -2289,7 +2351,99 @@
   begin
     send(opts[:rules]['Function'], opts)
   rescue
-    return rest_response(500)
+    if Rails.env == "production"
+      return rest_response(500)
+    else
+      raise
+    end
   end
 end
 
+
+# Component Querying
+def get_components(opts)
+  query = opts[:query]
+
+  annotations = (query['annotations'] || "").split('","').collect {|a| a.gsub('"','')} # annotations on workflow itself
+  # annotations on workflow features
+  inputs = query["input"] || {}#(query["inputs"] || "").split('),')
+  outputs = query["output"] || {} #(query["outputs"] || "").split('),')
+  processors = query["processor"] || {} #(query["processors"] || "").split('),')
+
+
+  workflows = Workflow.all # This should be filtered first
+
+  def get_workflow_feature_matches(workflows, features, model, query_conditions, query_conditions_excluding)
+    # "features" is an array of sets of annotations to be queried, in the form ['"<ann1>,"<ann2>"','"<ann3>"']
+    # The above example states that the workflow must have a <feature> that has annotations "pred1 obj1" and "pred2 obj2", AND
+    # another, different <feature> with "<ann3>".
+    #
+    # The annotations are in the form "<predicate> <object>".
+
+    # This method returns an array of arrays of workflows
+    selected = []
+    features.collect do |key,set|
+      raise "Bad Syntax" unless set =~ /^("[^ ]+ [^"]+")(,"[^ ]+ [^"]+")*$/
+
+      feature_annotations = set.split('","').collect {|a| a.gsub('"','')}
+      # "<ann1>", "<ann2>" (example)
+      matching_features = feature_annotations.collect { |a|
+        # Find all <features> with semantic annotation "<predicate> <object>" (example)
+        predicate, object = a.split(" ", 2)
+        unless selected.empty?
+          model.find(:all, :include => :semantic_annotations,
+                            :conditions => [query_conditions, workflows, predicate, object, selected])
+        else
+          model.find(:all, :include => :semantic_annotations,
+                            :conditions => [query_conditions_excluding, workflows, predicate, object])
+        end
+
+      }.inject {|f, matches| matches & f} # Get the intersection of <features> that have each annotation.
+                                          #   ie. the set of <features> that have ALL the required annotations
+      selected += matching_features
+      matching_features.collect {|wp| wp.workflow} # Get the workflows that those features belong to
+    end
+  end
+
+  begin
+    # Workflows that have the required inputs
+    matches_input_requirements = get_workflow_feature_matches(workflows, inputs, WorkflowPort,
+                                  "workflow_id IN (?) AND semantic_annotations.predicate = ? AND semantic_annotations.object = ? AND port_type = 'input' AND workflow_ports.id NOT IN (?)",
+                                  "workflow_id IN (?) AND semantic_annotations.predicate = ? AND semantic_annotations.object = ? AND port_type = 'input'")
+
+    # Workflows that have the required outputs
+    matches_output_requirements = get_workflow_feature_matches(workflows, outputs, WorkflowPort,
+                                  "workflow_id IN (?) AND semantic_annotations.predicate = ? AND semantic_annotations.object = ? AND port_type = 'output' AND workflow_ports.id NOT IN (?)",
+                                  "workflow_id IN (?) AND semantic_annotations.predicate = ? AND semantic_annotations.object = ? AND port_type = 'output'")
+
+    # Workflows that have the required processors
+    matches_processor_requirements = get_workflow_feature_matches(workflows, processors, WorkflowProcessor,
+                                  "workflow_id IN (?) AND semantic_annotations.predicate = ? AND semantic_annotations.object = ? AND workflow_processors.id NOT IN (?)",
+                                  "workflow_id IN (?) AND semantic_annotations.predicate = ? AND semantic_annotations.object = ?")
+
+    # Workflows that have the required semantic annotations
+    matches_semantic_annotation_requirements = annotations.collect do |p|
+      [Workflow.find(:all, :include => :semantic_annotations,
+                     :conditions => {:id => workflows,
+                                     :semantic_annotations => {:value => p}})]
+    end
+  rescue RuntimeError => e
+    if e.message == "Bad Syntax"
+      return rest_response(400)
+    else
+      raise e
+    end
+  end
+
+  # Create an array containing arrays of each set of matches
+  matches = matches_input_requirements +
+            matches_output_requirements +
+            matches_processor_requirements +
+            matches_semantic_annotation_requirements
+
+  # Workflows that match ALL the requirements - the intersection of all the sub arrays.
+  matches = matches.inject {|matches, matches_all| matches_all & matches}
+
+  # Render
+  produce_rest_list(opts[:uri], opts[:rules], query, matches, "workflows", [], opts[:user])
+end

Modified: trunk/lib/workflow_processors/interface.rb (3253 => 3254)


--- trunk/lib/workflow_processors/interface.rb	2012-12-12 11:49:45 UTC (rev 3253)
+++ trunk/lib/workflow_processors/interface.rb	2012-12-12 14:03:54 UTC (rev 3254)
@@ -117,7 +117,7 @@
       XML::Node.new("components")
     end
 
-    def extract_metadata(workflow_id)
+    def extract_metadata(workflow)
     end
 
     # End Instance Methods

Modified: trunk/lib/workflow_processors/taverna2.rb (3253 => 3254)


--- trunk/lib/workflow_processors/taverna2.rb	2012-12-12 11:49:45 UTC (rev 3253)
+++ trunk/lib/workflow_processors/taverna2.rb	2012-12-12 14:03:54 UTC (rev 3254)
@@ -9,6 +9,8 @@
   require 't2flow/parser'
   require 't2flow/dot'
   require 'libxml'
+  require 'rdf'
+  require 'rdf/n3'
   
   require 'file_upload'
 
@@ -373,16 +375,49 @@
       aux(@t2flow_model, @t2flow_model, 'components')
     end
     
-    def extract_metadata(workflow_id)
+    def extract_metadata(workflow)
 
       @t2flow_model.all_processors.each do |processor|
-        WorkflowProcessor.create(:workflow_id => workflow_id,
+        workflow_processor = WorkflowProcessor.create(:workflow => workflow,
             :name           => processor.name,
             :wsdl           => processor.wsdl,
             :wsdl_operation => processor.wsdl)
+        create_semantic_annotations(workflow_processor, processor.semantic_annotation)
       end
+
+      @t2flow_model.sources.each do |source|
+        port = WorkflowPort.create(:workflow => workflow,
+                            :port_type => "input",
+                            :name => source.name)
+        create_semantic_annotations(port, source.semantic_annotation)
+      end
+
+      @t2flow_model.sinks.each do |sink|
+        port = WorkflowPort.create(:workflow => workflow,
+                            :port_type => "output",
+                            :name => sink.name)
+        create_semantic_annotations(port, sink.semantic_annotation)
+      end
+
+      create_semantic_annotations(workflow, @t2flow_model.main.annotations.semantic_annotation)
+
     end
 
+    def create_semantic_annotations(subject, semantic_annotations)
+      if semantic_annotations.type == "text/rdf+n3"
+        g = RDF::Graph.new
+        g << RDF::Reader.for(:n3).new(semantic_annotations.content)
+
+        g.each_statement do |statement|
+          predicate = statement.predicate.to_s
+          object = statement.object.to_s
+          SemanticAnnotation.create(:subject => subject, :predicate => predicate, :object => object)
+        end
+      else
+        raise "Unsupported annotation content type (#{semantic_annotations.type}) for #{subject}."
+      end
+    end
+
     # End Instance Methods
   end
 end

Modified: trunk/lib/workflow_processors/taverna_scufl.rb (3253 => 3254)


--- trunk/lib/workflow_processors/taverna_scufl.rb	2012-12-12 11:49:45 UTC (rev 3253)
+++ trunk/lib/workflow_processors/taverna_scufl.rb	2012-12-12 14:03:54 UTC (rev 3254)
@@ -289,10 +289,10 @@
       aux(@scufl_model, 'components')
     end
 
-    def extract_metadata(workflow_id)
+    def extract_metadata(workflow)
 
       @scufl_model.all_processors.each do |processor|
-        WorkflowProcessor.create(:workflow_id => workflow_id,
+        WorkflowProcessor.create(:workflow => workflow,
             :name           => processor.name,
             :wsdl           => processor.wsdl,
             :wsdl_operation => processor.wsdl_operation)

Modified: trunk/test/functional/api_controller_test.rb (3253 => 3254)


--- trunk/test/functional/api_controller_test.rb	2012-12-12 11:49:45 UTC (rev 3253)
+++ trunk/test/functional/api_controller_test.rb	2012-12-12 14:03:54 UTC (rev 3254)
@@ -191,6 +191,7 @@
         <title>#{title}</title>
         <description>#{description}</description>
         <license-type>#{license_type}</license-type>
+        <filename>test.txt</filename>
         <content-type>#{content_type}</content-type>
         <content>#{content}</content>
       </file>")

reply via email to

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