~michaelforrest/use-case-mapper/trunk

« back to all changes in this revision

Viewing changes to vendor/rails/actionpack/lib/action_view/reloadable_template.rb

  • Committer: Richard Lee (Canonical)
  • Date: 2010-10-15 15:17:58 UTC
  • mfrom: (190.1.3 use-case-mapper)
  • Revision ID: richard.lee@canonical.com-20101015151758-wcvmfxrexsongf9d
Merge

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
module ActionView #:nodoc:
2
 
  class ReloadableTemplate < Template
3
 
 
4
 
    class TemplateDeleted < ActionView::ActionViewError
5
 
    end
6
 
 
7
 
    class ReloadablePath < Template::Path
8
 
 
9
 
      def initialize(path)
10
 
        super
11
 
        @paths = {}
12
 
        new_request!
13
 
      end
14
 
 
15
 
      def new_request!
16
 
        @disk_cache = {}
17
 
      end
18
 
      alias_method :load!, :new_request!
19
 
 
20
 
      def [](path)
21
 
        if found_template = @paths[path]
22
 
          begin
23
 
            found_template.reset_cache_if_stale!
24
 
          rescue TemplateDeleted
25
 
            unregister_template(found_template)
26
 
            self[path]
27
 
          end
28
 
        else
29
 
          load_all_templates_from_dir(templates_dir_from_path(path))
30
 
          # don't ever hand out a template without running a stale check
31
 
          (new_template = @paths[path]) && new_template.reset_cache_if_stale!
32
 
        end
33
 
      end
34
 
 
35
 
      private
36
 
        def register_template_from_file(template_full_file_path)
37
 
          if !@paths[relative_path = relative_path_for_template_file(template_full_file_path)] && File.file?(template_full_file_path)
38
 
            register_template(ReloadableTemplate.new(relative_path, self))
39
 
          end
40
 
        end
41
 
 
42
 
        def register_template(template)
43
 
          template.accessible_paths.each do |path|
44
 
            @paths[path] = template
45
 
          end
46
 
        end
47
 
 
48
 
        # remove (probably deleted) template from cache
49
 
        def unregister_template(template)
50
 
          template.accessible_paths.each do |template_path|
51
 
            @paths.delete(template_path) if @paths[template_path] == template
52
 
          end
53
 
          # fill in any newly created gaps
54
 
          @paths.values.uniq.each do |template|
55
 
            template.accessible_paths.each {|path| @paths[path] ||= template}
56
 
          end
57
 
        end
58
 
 
59
 
        # load all templates from the directory of the requested template
60
 
        def load_all_templates_from_dir(dir)
61
 
          # hit disk only once per template-dir/request
62
 
          @disk_cache[dir] ||= template_files_from_dir(dir).each {|template_file| register_template_from_file(template_file)}
63
 
        end
64
 
 
65
 
        def templates_dir_from_path(path)
66
 
          dirname = File.dirname(path)
67
 
          File.join(@path, dirname == '.' ? '' : dirname)
68
 
        end
69
 
 
70
 
        # get all the template filenames from the dir
71
 
        def template_files_from_dir(dir)
72
 
          Dir.glob(File.join(dir, '*'))
73
 
        end
74
 
    end
75
 
 
76
 
    module Unfreezable
77
 
      def freeze; self; end
78
 
    end
79
 
 
80
 
    def initialize(*args)
81
 
      super
82
 
      
83
 
      # we don't ever want to get frozen
84
 
      extend Unfreezable
85
 
    end
86
 
 
87
 
    def mtime
88
 
      File.mtime(filename)
89
 
    end
90
 
 
91
 
    attr_accessor :previously_last_modified
92
 
 
93
 
    def stale?
94
 
      previously_last_modified.nil? || previously_last_modified < mtime
95
 
    rescue Errno::ENOENT => e
96
 
      undef_my_compiled_methods!
97
 
      raise TemplateDeleted
98
 
    end
99
 
 
100
 
    def reset_cache_if_stale!
101
 
      if stale?
102
 
        flush_cache 'source', 'compiled_source'
103
 
        undef_my_compiled_methods!
104
 
        @previously_last_modified = mtime
105
 
      end
106
 
      self
107
 
    end
108
 
 
109
 
    # remove any compiled methods that look like they might belong to me
110
 
    def undef_my_compiled_methods!
111
 
      ActionView::Base::CompiledTemplates.public_instance_methods.grep(/#{Regexp.escape(method_name_without_locals)}(?:_locals_)?/).each do |m|
112
 
        ActionView::Base::CompiledTemplates.send(:remove_method, m)
113
 
      end
114
 
    end
115
 
 
116
 
  end
117
 
end