changed properties and the name of hyperchad to selectricity
[selectricity] / vendor / plugins / engines / lib / engines / dependencies_extensions.rb
1 module ::Dependencies
2   
3   # we're going to intercept the require_or_load method; lets
4   # make an alias for the current method so we can use it as the basis
5   # for loading from engines.
6   alias :rails_pre_engines_require_or_load :require_or_load
7   
8   def require_or_load(file_name)
9     if Engines.config(:edge)
10       rails_edge_require_or_load(file_name)
11     
12     elsif Rails::VERSION::STRING =~ /^1.1/
13       # otherwise, assume we're on trunk (1.1 at the moment)
14       rails_1_1_require_or_load(file_name)
15     
16     elsif Rails::VERSION::STRING =~ /^1.0/
17       # use the old dependency load method
18       rails_1_0_require_or_load(file_name)
19     end
20   end
21   
22   def rails_edge_require_or_load(file_name)
23     rails_1_1_require_or_load(file_name)
24   end
25   
26   def rails_1_1_require_or_load(file_name)
27     Engines.log.debug("Engines 1.1 require_or_load: #{file_name}")
28
29     found = false
30
31     # try and load the engine code first
32     # can't use model, as there's nothing in the name to indicate that the file is a 'model' file
33     # rather than a library or anything else.
34     ['controller', 'helper'].each do |type| 
35       # if we recognise this type
36       # (this regexp splits out the module/filename from any instances of app/#{type}, so that
37       #  modules are still respected.)
38       if file_name =~ /^(.*app\/#{type}s\/)?(.*_#{type})(\.rb)?$/
39  
40         # ... go through the active engines from first started to last, so that
41         # code with a high precidence (started later) will override lower precidence
42         # implementations
43         Engines.each(:load_order) do |engine|
44  
45           engine_file_name = File.expand_path(File.join(engine.root, 'app', "#{type}s", $2))
46           #engine_file_name = $1 if engine_file_name =~ /^(.*)\.rb$/
47           Engines.log.debug("checking engine '#{engine.name}' for '#{engine_file_name}'")
48           if File.exist?("#{engine_file_name}.rb")
49             Engines.log.debug("==> loading from engine '#{engine.name}'")
50             rails_pre_engines_require_or_load(engine_file_name)
51             found = true
52           end
53         end
54       end 
55     end
56     
57     # finally, load any application-specific controller classes using the 'proper'
58     # rails load mechanism, EXCEPT when we're testing engines and could load this file
59     # from an engine
60     rails_pre_engines_require_or_load(file_name) unless Engines.disable_app_code_mixing && found
61   end
62   
63   def rails_1_0_require_or_load(file_name)
64     file_name = $1 if file_name =~ /^(.*)\.rb$/
65
66     Engines.log.debug "Engines 1.0.0 require_or_load '#{file_name}'"
67
68     # if the file_name ends in "_controller" or "_controller.rb", strip all
69     # path information out of it except for module context, and load it. Ditto
70     # for helpers.
71     found = if file_name =~ /_controller(.rb)?$/
72       require_engine_files(file_name, 'controller')
73     elsif file_name =~ /_helper(.rb)?$/ # any other files we can do this with?
74       require_engine_files(file_name, 'helper')
75     end
76     
77     # finally, load any application-specific controller classes using the 'proper'
78     # rails load mechanism, EXCEPT when we're testing engines and could load this file
79     # from an engine
80     Engines.log.debug("--> loading from application: '#{file_name}'")
81     rails_pre_engines_require_or_load(file_name) unless Engines.disable_app_code_mixing && found
82     Engines.log.debug("--> Done loading.")
83   end
84   
85   # Load the given file (which should be a path to be matched from the root of each
86   # engine) from all active engines which have that file.
87   # NOTE! this method automagically strips file_name up to and including the first
88   # instance of '/app/controller'. This should correspond to the app/controller folder
89   # under RAILS_ROOT. However, if you have your Rails application residing under a
90   # path which includes /app/controller anyway, such as:
91   #
92   #   /home/username/app/controller/my_web_application # == RAILS_ROOT
93   #
94   # then you might have trouble. Sorry, just please don't have your web application
95   # running under a path like that.
96   def require_engine_files(file_name, type='')
97     found = false
98     Engines.log.debug "requiring #{type} file '#{file_name}'"
99     processed_file_name = file_name.gsub(/[\w\W\/\.]*app\/#{type}s\//, '')    
100     Engines.log.debug "--> rewrote to '#{processed_file_name}'"
101     Engines.each(:load_order) do |engine|
102       engine_file_name = File.join(engine.root, 'app', "#{type}s", processed_file_name)
103       engine_file_name += '.rb' unless ! load? || engine_file_name[-3..-1] == '.rb'
104       Engines.log.debug "--> checking '#{engine.name}' for #{engine_file_name}"
105       if File.exist?(engine_file_name) || 
106         (engine_file_name[-3..-1] != '.rb' && File.exist?(engine_file_name + '.rb'))
107         Engines.log.debug "--> found, loading from engine '#{engine.name}'"
108         rails_pre_engines_require_or_load(engine_file_name)
109         found = true
110       end
111     end
112     found
113   end
114 end
115
116
117 # We only need to deal with LoadingModules in Rails 1.0.0
118 if Rails::VERSION::STRING =~ /^1.0/ && !Engines.config(:edge)
119   module ::Dependencies
120     class RootLoadingModule < LoadingModule
121       # hack to allow adding to the load paths within the Rails Dependencies mechanism.
122       # this allows Engine classes to be unloaded and loaded along with standard
123       # Rails application classes.
124       def add_path(path)
125         @load_paths << (path.kind_of?(ConstantLoadPath) ? path : ConstantLoadPath.new(path))
126       end
127     end
128   end
129 end

Benjamin Mako Hill || Want to submit a patch?