Class: Rubyfocus::Patch
- Inherits:
- 
      Object
      
        - Object
- Rubyfocus::Patch
 
- Includes:
- Comparable
- Defined in:
- lib/rubyfocus/patch.rb
Overview
The patch class represents a text-file patch, storing update, delete, and creation operations. It should also be able to apply itself to an existing document.
Instance Attribute Summary collapse
- 
  
    
      #create  ⇒ Object 
    
    
  
  
  
  
    
    
  
  
  
  
  
  
    Operations to be performed on a document. 
- 
  
    
      #delete  ⇒ Object 
    
    
  
  
  
  
    
    
  
  
  
  
  
  
    Operations to be performed on a document. 
- 
  
    
      #fetcher  ⇒ Object 
    
    
  
  
  
  
    
    
  
  
  
  
  
  
    The fetcher this patch belongs to. 
- 
  
    
      #file  ⇒ Object 
    
    
  
  
  
  
    
    
  
  
  
  
  
  
    The file the patch loads from. 
- 
  
    
      #from_ids  ⇒ Object 
    
    
  
  
  
  
    
    
  
  
  
  
  
  
    These record the transformation in terms of patch ID values. 
- 
  
    
      #time  ⇒ Object 
    
    
  
  
  
  
    
    
  
  
  
  
  
  
    The time the file was submitted. 
- 
  
    
      #to_id  ⇒ Object 
    
    
  
  
  
  
    
    
  
  
  
  
  
  
    These record the transformation in terms of patch ID values. 
- 
  
    
      #update  ⇒ Object 
    
    
  
  
  
  
    
    
  
  
  
  
  
  
    Update, delete and create methods. 
- 
  
    
      #version  ⇒ Object 
    
    
  
  
  
  
    
    
  
  
  
  
  
  
    What version of patch file is this? Determined from XML file. 
Class Method Summary collapse
- 
  
    
      .from_string(fetcher, str)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    Load from a string. 
Instance Method Summary collapse
- #<=>(o) ⇒ Object
- 
  
    
      #apply_to(document)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    Apply this patch to a document. 
- 
  
    
      #apply_to!(document)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    Apply this patch to a document. 
- 
  
    
      #can_patch?(document)  ⇒ Boolean 
    
    
  
  
  
  
  
  
  
  
  
    Can we apply this patch to a given document?. 
- 
  
    
      #initialize(fetcher = nil, file = nil)  ⇒ Patch 
    
    
  
  
  
    constructor
  
  
  
  
  
  
  
    By default we initialize patches from a file. 
- 
  
    
      #load_data(str = nil)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    Loads data from the file. 
- 
  
    
      #to_s  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    String representation. 
Constructor Details
#initialize(fetcher = nil, file = nil) ⇒ Patch
By default we initialize patches from a file. To initialize from a string, use the .from_string method. This class will lazily load data from the file proper
| 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | # File 'lib/rubyfocus/patch.rb', line 25 def initialize(fetcher=nil, file=nil) @fetcher = fetcher @file = file @update = [] @create = [] @delete = [] if file if File.basename(file) =~ /^(\d+)=(.*)\./ time_string = $1 self.time = if (time_string == "00000000000000") Time.at(0) else Time.parse(time_string) end ids = $2.split("+") self.to_id = ids.pop self.from_ids = ids else raise ArgumentError, "Constructed patch from a malformed patch file: #{file}." end end end | 
Instance Attribute Details
#create ⇒ Object
Operations to be performed on a document
| 9 10 11 | # File 'lib/rubyfocus/patch.rb', line 9 def create @create end | 
#delete ⇒ Object
Operations to be performed on a document
| 9 10 11 | # File 'lib/rubyfocus/patch.rb', line 9 def delete @delete end | 
#fetcher ⇒ Object
The fetcher this patch belongs to. We mainly use this to work out how to fetch content for the patch proper
| 6 7 8 | # File 'lib/rubyfocus/patch.rb', line 6 def fetcher @fetcher end | 
#file ⇒ Object
The file the patch loads from
| 12 13 14 | # File 'lib/rubyfocus/patch.rb', line 12 def file @file end | 
#from_ids ⇒ Object
These record the transformation in terms of patch ID values.
| 18 19 20 | # File 'lib/rubyfocus/patch.rb', line 18 def from_ids @from_ids end | 
#time ⇒ Object
The time the file was submitted
| 21 22 23 | # File 'lib/rubyfocus/patch.rb', line 21 def time @time end | 
#to_id ⇒ Object
These record the transformation in terms of patch ID values.
| 18 19 20 | # File 'lib/rubyfocus/patch.rb', line 18 def to_id @to_id end | 
#update ⇒ Object
Update, delete and create methods
| 9 10 11 | # File 'lib/rubyfocus/patch.rb', line 9 def update @update end | 
#version ⇒ Object
What version of patch file is this? Determined from XML file
| 15 16 17 | # File 'lib/rubyfocus/patch.rb', line 15 def version @version end | 
Class Method Details
.from_string(fetcher, str) ⇒ Object
Load from a string.
| 51 52 53 54 55 | # File 'lib/rubyfocus/patch.rb', line 51 def self.from_string(fetcher, str) n = new(fetcher) n.load_data(str) n end | 
Instance Method Details
#<=>(o) ⇒ Object
| 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | # File 'lib/rubyfocus/patch.rb', line 153 def <=> o if self.time.nil? if o.time.nil? 0 else -1 end else if o.time.nil? 1 else self.time <=> o.time end end end | 
#apply_to(document) ⇒ Object
Apply this patch to a document. Check to make sure ids match
| 111 112 113 114 115 116 117 | # File 'lib/rubyfocus/patch.rb', line 111 def apply_to(document) if can_patch?(document) apply_to!(document) else raise RuntimeError, "Patch ID mismatch (patch from_ids: [#{self.from_ids.join(", ")}], document.patch_id: #{document.patch_id}" end end | 
#apply_to!(document) ⇒ Object
Apply this patch to a document.
| 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | # File 'lib/rubyfocus/patch.rb', line 120 def apply_to!(document) load_data # Updates depend on version! if version == 1 #V1 updates overwrite elements self.update.each{ |node| document.overwrite_element(node) } elsif version == 2 #V2 updates actually update elements self.update.each{ |node| document.update_element(node) } else raise RuntimeError, "Cannot run updates using Version #{version.inspect} OF patches!" end # Deletes remove elements self.delete.each{ |node| document.remove_element(node["id"]) } # Creates make new elements self.create.each{ |node| document.update_element(node) } # Modify current patch_id to show new value document.patch_id = self.to_id end | 
#can_patch?(document) ⇒ Boolean
Can we apply this patch to a given document?
| 106 107 108 | # File 'lib/rubyfocus/patch.rb', line 106 def can_patch?(document) self.from_ids.include?(document.patch_id) end | 
#load_data(str = nil) ⇒ Object
Loads data from the file. Optional argument str if you want to supply your own data, otherwise will load file data
| 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | # File 'lib/rubyfocus/patch.rb', line 59 def load_data(str=nil) return if @data_loaded @data_loaded = true str ||= fetcher.patch(self.file) doc = Nokogiri::XML(str) # Root should be an <omnifocus> and have an XMLNS # XMLNS should be one of: # * http://www.omnigroup.com/namespace/OmniFocus/v1 # * http://www.omnigroup.com/namespace/OmniFocus/v2 omnifocus = doc.root if omnifocus.name == "omnifocus" xmlns = omnifocus.namespace && omnifocus.namespace.href case xmlns when "http://www.omnigroup.com/namespace/OmniFocus/v1" self.version = 1 when "http://www.omnigroup.com/namespace/OmniFocus/v2" self.version = 2 else raise ArgumentError, "Unrecognised namespace #{xmlns.inspect} for Omnifocus patch file." end else raise ArgumentError, "Root element should be <omnifocus>, instead was <#{omnifocus.name}>." end doc.root.children.select{ |n| !n.text?}.each do |child| case child["op"] when "update" @update << child when "delete" @delete << child when "reference" # Ignore! when nil @create << child else raise RuntimeError, "Rubyfocus::Patch encountered unknown operation type #{child["op"]}." end end end | 
#to_s ⇒ Object
String representation
| 145 146 147 148 149 150 151 | # File 'lib/rubyfocus/patch.rb', line 145 def to_s if from_ids.size == 1 "(#{from_ids.first} -> #{to_id})" else "([#{from_ids.join(", ")}] -> #{to_id})" end end |