aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_controller/support
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2004-11-24 01:04:44 +0000
committerDavid Heinemeier Hansson <david@loudthinking.com>2004-11-24 01:04:44 +0000
commitdb045dbbf60b53dbe013ef25554fd013baf88134 (patch)
tree257830e3c76458c8ff3d1329de83f32b23926028 /actionpack/lib/action_controller/support
downloadrails-db045dbbf60b53dbe013ef25554fd013baf88134.tar.gz
rails-db045dbbf60b53dbe013ef25554fd013baf88134.tar.bz2
rails-db045dbbf60b53dbe013ef25554fd013baf88134.zip
Initial
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'actionpack/lib/action_controller/support')
-rw-r--r--actionpack/lib/action_controller/support/class_attribute_accessors.rb57
-rw-r--r--actionpack/lib/action_controller/support/class_inheritable_attributes.rb37
-rw-r--r--actionpack/lib/action_controller/support/clean_logger.rb10
-rw-r--r--actionpack/lib/action_controller/support/cookie_performance_fix.rb121
-rw-r--r--actionpack/lib/action_controller/support/inflector.rb78
5 files changed, 303 insertions, 0 deletions
diff --git a/actionpack/lib/action_controller/support/class_attribute_accessors.rb b/actionpack/lib/action_controller/support/class_attribute_accessors.rb
new file mode 100644
index 0000000000..786dcf98cb
--- /dev/null
+++ b/actionpack/lib/action_controller/support/class_attribute_accessors.rb
@@ -0,0 +1,57 @@
+# Extends the class object with class and instance accessors for class attributes,
+# just like the native attr* accessors for instance attributes.
+class Class # :nodoc:
+ def cattr_reader(*syms)
+ syms.each do |sym|
+ class_eval <<-EOS
+ if ! defined? @@#{sym.id2name}
+ @@#{sym.id2name} = nil
+ end
+
+ def self.#{sym.id2name}
+ @@#{sym}
+ end
+
+ def #{sym.id2name}
+ @@#{sym}
+ end
+
+ def call_#{sym.id2name}
+ case @@#{sym.id2name}
+ when Symbol then send(@@#{sym})
+ when Proc then @@#{sym}.call(self)
+ when String then @@#{sym}
+ else nil
+ end
+ end
+ EOS
+ end
+ end
+
+ def cattr_writer(*syms)
+ syms.each do |sym|
+ class_eval <<-EOS
+ if ! defined? @@#{sym.id2name}
+ @@#{sym.id2name} = nil
+ end
+
+ def self.#{sym.id2name}=(obj)
+ @@#{sym.id2name} = obj
+ end
+
+ def self.set_#{sym.id2name}(obj)
+ @@#{sym.id2name} = obj
+ end
+
+ def #{sym.id2name}=(obj)
+ @@#{sym} = obj
+ end
+ EOS
+ end
+ end
+
+ def cattr_accessor(*syms)
+ cattr_reader(*syms)
+ cattr_writer(*syms)
+ end
+end \ No newline at end of file
diff --git a/actionpack/lib/action_controller/support/class_inheritable_attributes.rb b/actionpack/lib/action_controller/support/class_inheritable_attributes.rb
new file mode 100644
index 0000000000..7f061fdf1b
--- /dev/null
+++ b/actionpack/lib/action_controller/support/class_inheritable_attributes.rb
@@ -0,0 +1,37 @@
+# Allows attributes to be shared within an inheritance hierarchy, but where each descendant gets a copy of
+# their parents' attributes, instead of just a pointer to the same. This means that the child can add elements
+# to, for example, an array without those additions being shared with either their parent, siblings, or
+# children, which is unlike the regular class-level attributes that are shared across the entire hierarchy.
+module ClassInheritableAttributes # :nodoc:
+ def self.append_features(base)
+ super
+ base.extend(ClassMethods)
+ end
+
+ module ClassMethods # :nodoc:
+ @@classes ||= {}
+
+ def inheritable_attributes
+ @@classes[self] ||= {}
+ end
+
+ def write_inheritable_attribute(key, value)
+ inheritable_attributes[key] = value
+ end
+
+ def write_inheritable_array(key, elements)
+ write_inheritable_attribute(key, []) if read_inheritable_attribute(key).nil?
+ write_inheritable_attribute(key, read_inheritable_attribute(key) + elements)
+ end
+
+ def read_inheritable_attribute(key)
+ inheritable_attributes[key]
+ end
+
+ private
+ def inherited(child)
+ @@classes[child] = inheritable_attributes.dup
+ end
+
+ end
+end
diff --git a/actionpack/lib/action_controller/support/clean_logger.rb b/actionpack/lib/action_controller/support/clean_logger.rb
new file mode 100644
index 0000000000..1a36562892
--- /dev/null
+++ b/actionpack/lib/action_controller/support/clean_logger.rb
@@ -0,0 +1,10 @@
+require 'logger'
+
+class Logger #:nodoc:
+ private
+ remove_const "Format"
+ Format = "%s\n"
+ def format_message(severity, timestamp, msg, progname)
+ Format % [msg]
+ end
+end \ No newline at end of file
diff --git a/actionpack/lib/action_controller/support/cookie_performance_fix.rb b/actionpack/lib/action_controller/support/cookie_performance_fix.rb
new file mode 100644
index 0000000000..225cea1905
--- /dev/null
+++ b/actionpack/lib/action_controller/support/cookie_performance_fix.rb
@@ -0,0 +1,121 @@
+CGI.module_eval { remove_const "Cookie" }
+
+class CGI #:nodoc:
+ # This is a cookie class that fixes the performance problems with the default one that ships with 1.8.1 and below.
+ # It replaces the inheritance on SimpleDelegator with DelegateClass(Array) following the suggestion from Matz on
+ # http://groups.google.com/groups?th=e3a4e68ba042f842&seekm=c3sioe%241qvm%241%40news.cybercity.dk#link14
+ class Cookie < DelegateClass(Array)
+ # Create a new CGI::Cookie object.
+ #
+ # The contents of the cookie can be specified as a +name+ and one
+ # or more +value+ arguments. Alternatively, the contents can
+ # be specified as a single hash argument. The possible keywords of
+ # this hash are as follows:
+ #
+ # name:: the name of the cookie. Required.
+ # value:: the cookie's value or list of values.
+ # path:: the path for which this cookie applies. Defaults to the
+ # base directory of the CGI script.
+ # domain:: the domain for which this cookie applies.
+ # expires:: the time at which this cookie expires, as a +Time+ object.
+ # secure:: whether this cookie is a secure cookie or not (default to
+ # false). Secure cookies are only transmitted to HTTPS
+ # servers.
+ #
+ # These keywords correspond to attributes of the cookie object.
+ def initialize(name = "", *value)
+ options = if name.kind_of?(String)
+ { "name" => name, "value" => value }
+ else
+ name
+ end
+ unless options.has_key?("name")
+ raise ArgumentError, "`name' required"
+ end
+
+ @name = options["name"]
+ @value = Array(options["value"])
+ # simple support for IE
+ if options["path"]
+ @path = options["path"]
+ else
+ %r|^(.*/)|.match(ENV["SCRIPT_NAME"])
+ @path = ($1 or "")
+ end
+ @domain = options["domain"]
+ @expires = options["expires"]
+ @secure = options["secure"] == true ? true : false
+
+ super(@value)
+ end
+
+ def __setobj__(obj)
+ @_dc_obj = obj
+ end
+
+ attr_accessor("name", "value", "path", "domain", "expires")
+ attr_reader("secure")
+
+ # Set whether the Cookie is a secure cookie or not.
+ #
+ # +val+ must be a boolean.
+ def secure=(val)
+ @secure = val if val == true or val == false
+ @secure
+ end
+
+ # Convert the Cookie to its string representation.
+ def to_s
+ buf = ""
+ buf += @name + '='
+
+ if @value.kind_of?(String)
+ buf += CGI::escape(@value)
+ else
+ buf += @value.collect{|v| CGI::escape(v) }.join("&")
+ end
+
+ if @domain
+ buf += '; domain=' + @domain
+ end
+
+ if @path
+ buf += '; path=' + @path
+ end
+
+ if @expires
+ buf += '; expires=' + CGI::rfc1123_date(@expires)
+ end
+
+ if @secure == true
+ buf += '; secure'
+ end
+
+ buf
+ end
+
+ # Parse a raw cookie string into a hash of cookie-name=>Cookie
+ # pairs.
+ #
+ # cookies = CGI::Cookie::parse("raw_cookie_string")
+ # # { "name1" => cookie1, "name2" => cookie2, ... }
+ #
+ def self.parse(raw_cookie)
+ cookies = Hash.new([])
+ return cookies unless raw_cookie
+
+ raw_cookie.split(/; /).each do |pairs|
+ name, values = pairs.split('=',2)
+ next unless name and values
+ name = CGI::unescape(name)
+ values ||= ""
+ values = values.split('&').collect{|v| CGI::unescape(v) }
+ unless cookies.has_key?(name)
+ cookies[name] = new({ "name" => name, "value" => values })
+ end
+ end
+
+ cookies
+ end
+ end # class Cookie
+end \ No newline at end of file
diff --git a/actionpack/lib/action_controller/support/inflector.rb b/actionpack/lib/action_controller/support/inflector.rb
new file mode 100644
index 0000000000..05ff4fede9
--- /dev/null
+++ b/actionpack/lib/action_controller/support/inflector.rb
@@ -0,0 +1,78 @@
+# The Inflector transforms words from singular to plural, class names to table names, modulized class names to ones without,
+# and class names to foreign keys.
+module Inflector
+ extend self
+
+ def pluralize(word)
+ result = word.dup
+ plural_rules.each do |(rule, replacement)|
+ break if result.gsub!(rule, replacement)
+ end
+ return result
+ end
+
+ def singularize(word)
+ result = word.dup
+ singular_rules.each do |(rule, replacement)|
+ break if result.gsub!(rule, replacement)
+ end
+ return result
+ end
+
+ def camelize(lower_case_and_underscored_word)
+ lower_case_and_underscored_word.gsub(/(^|_)(.)/){$2.upcase}
+ end
+
+ def underscore(camel_cased_word)
+ camel_cased_word.gsub(/([A-Z]+)([A-Z])/,'\1_\2').gsub(/([a-z])([A-Z])/,'\1_\2').downcase
+ end
+
+ def demodulize(class_name_in_module)
+ class_name_in_module.gsub(/^.*::/, '')
+ end
+
+ def tableize(class_name)
+ pluralize(underscore(class_name))
+ end
+
+ def classify(table_name)
+ camelize(singularize(table_name))
+ end
+
+ def foreign_key(class_name, separate_class_name_and_id_with_underscore = true)
+ Inflector.underscore(Inflector.demodulize(class_name)) +
+ (separate_class_name_and_id_with_underscore ? "_id" : "id")
+ end
+
+ private
+ def plural_rules #:doc:
+ [
+ [/(x|ch|ss)$/, '\1es'], # search, switch, fix, box, process, address
+ [/([^aeiouy]|qu)y$/, '\1ies'], # query, ability, agency
+ [/(?:([^f])fe|([lr])f)$/, '\1\2ves'], # half, safe, wife
+ [/sis$/, 'ses'], # basis, diagnosis
+ [/([ti])um$/, '\1a'], # datum, medium
+ [/person$/, 'people'], # person, salesperson
+ [/man$/, 'men'], # man, woman, spokesman
+ [/child$/, 'children'], # child
+ [/s$/, 's'], # no change (compatibility)
+ [/$/, 's']
+ ]
+ end
+
+ def singular_rules #:doc:
+ [
+ [/(x|ch|ss)es$/, '\1'],
+ [/([^aeiouy]|qu)ies$/, '\1y'],
+ [/([lr])ves$/, '\1f'],
+ [/([^f])ves$/, '\1fe'],
+ [/(analy|ba|diagno|parenthe|progno|synop|the)ses$/, '\1sis'],
+ [/([ti])a$/, '\1um'],
+ [/people$/, 'person'],
+ [/men$/, 'man'],
+ [/status$/, 'status'],
+ [/children$/, 'child'],
+ [/s$/, '']
+ ]
+ end
+end \ No newline at end of file