Removing .DS_Store and .pid files from repository.
[merb_radiant.git] / lib / radiant / extension_loader.rb_
blob0ab5980d1dc8aee6debcb560212147f04f700dbe
1 # FIXME Rails dependencies / use gem
3 require 'radiant/extension'
4 require 'method_observer'
6 module Radiant
7   class ExtensionLoader
8     
9     class DependenciesObserver < MethodObserver
10       attr_accessor :config
11       
12       def initialize(rails_config)
13         @config = rails_config
14       end
15       
16       def before_clear(*args)
17         ExtensionLoader.deactivate_extensions
18       end
19       
20       def after_clear(*args)
21         ExtensionLoader.load_extensions
22         ExtensionLoader.activate_extensions
23       end
24     end
26     include Simpleton
27     
28     attr_accessor :initializer, :extensions
29     
30     def initialize
31       self.extensions = []
32     end
33     
34     def configuration
35       initializer.configuration
36     end
37     
38     def extension_load_paths
39       load_extension_roots.map { |extension| load_paths_for(extension) }.flatten.select { |d| File.directory?(d) }
40     end
42     def plugin_paths
43       load_extension_roots.map {|extension| "#{extension}/vendor/plugins" }.select {|d| File.directory?(d) }
44     end
45     
46     def add_extension_paths
47       extension_load_paths.reverse_each do |path|
48         configuration.load_paths.unshift path
49         $LOAD_PATH.unshift path
50       end
51     end
52     
53     def add_plugin_paths
54       configuration.plugin_paths.concat plugin_paths
55     end
57     def controller_paths
58       extensions.map { |extension| "#{extension.root}/app/controllers" }.select { |d| File.directory?(d) }
59     end
60     
61     def add_controller_paths
62       configuration.controller_paths.concat(controller_paths)
63     end
64     
65     def view_paths
66       extensions.map { |extension| "#{extension.root}/app/views" }.select { |d| File.directory?(d) }
67     end
68     
69     # Load the extensions
70     def load_extensions
71       @observer ||= DependenciesObserver.new(configuration).observe(::Dependencies)
72       self.extensions = load_extension_roots.map do |root|
73         begin
74           extension_file = "#{File.basename(root).sub(/^\d+_/,'')}_extension"
75           extension = extension_file.camelize.constantize
76           extension.unloadable
77           extension.root = root
78           extension
79         rescue LoadError, NameError => e
80           $stderr.puts "Could not load extension from file: #{extension_file}.\n#{e.inspect}"
81           nil
82         end
83       end.compact
84     end
85     
86     def deactivate_extensions
87       extensions.each &:deactivate
88     end
89     
90     def activate_extensions
91       initializer.initialize_default_admin_tabs
92       # Reset the view paths after 
93       initializer.initialize_framework_views
94       extensions.each &:activate
95     end
96     alias :reactivate :activate_extensions
98     private
100       def load_paths_for(dir)
101         if File.directory?(dir)
102           %w(lib app/models app/controllers app/helpers test/helpers).collect do |p|
103             path = "#{dir}/#{p}"
104             path if File.directory?(path)
105           end.compact << dir
106         else
107           []
108         end
109       end
110       
111       def load_extension_roots
112         @load_extension_roots ||= unless configuration.extensions.empty?
113           select_extension_roots
114         else
115           []
116         end
117       end
118       
119       def select_extension_roots
120         all_roots = all_extension_roots.dup
121         
122         roots = configuration.extensions.map do |ext_name|
123           if :all === ext_name
124             :all
125           else
126             ext_path = all_roots.detect do |maybe_path|
127               File.basename(maybe_path).sub(/^\d+_/, '') == ext_name.to_s
128             end
129             raise LoadError, "Cannot find the extension '#{ext_name}'!" if ext_path.nil?
130             all_roots.delete(ext_path)
131           end
132         end
134         if placeholder = roots.index(:all)
135           # replace the :all symbol with any remaining paths
136           roots[placeholder, 1] = all_roots
137         end
138         roots
139       end
140       
141       def all_extension_roots
142         @all_extension_roots ||= configuration.extension_paths.map do |path|
143           Dir["#{path}/*"].map {|f| File.expand_path(f) if File.directory?(f) }.compact.sort
144         end.flatten
145       end
146   end