glue 0.20.0 → 0.21.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/CHANGELOG +161 -110
  2. data/INSTALL +12 -12
  3. data/README +1 -1
  4. data/Rakefile +43 -45
  5. data/doc/AUTHORS +5 -5
  6. data/doc/LICENSE +3 -3
  7. data/doc/RELEASES +32 -24
  8. data/install.rb +7 -17
  9. data/lib/facet/object/alias_class.rb +12 -0
  10. data/lib/glue.rb +35 -35
  11. data/lib/glue/array.rb +46 -46
  12. data/lib/glue/aspects.rb +199 -209
  13. data/lib/glue/attribute.rb +15 -15
  14. data/lib/glue/autoreload.rb +1 -1
  15. data/lib/glue/builder.rb +48 -0
  16. data/lib/glue/builder/xml.rb +114 -0
  17. data/lib/glue/cache.rb +189 -0
  18. data/lib/glue/configuration.rb +108 -90
  19. data/lib/glue/flexob.rb +17 -17
  20. data/lib/glue/hash.rb +71 -71
  21. data/lib/glue/helper.rb +12 -12
  22. data/lib/glue/idgen.rb +9 -0
  23. data/lib/glue/idgen/md5.rb +24 -0
  24. data/lib/glue/idgen/sequential.rb +15 -0
  25. data/lib/glue/literal_method.rb +44 -0
  26. data/lib/glue/localization.rb +130 -0
  27. data/lib/glue/logger.rb +98 -98
  28. data/lib/glue/misc.rb +7 -7
  29. data/lib/glue/mixins.rb +19 -19
  30. data/lib/glue/number.rb +8 -8
  31. data/lib/glue/object.rb +2 -2
  32. data/lib/glue/pool.rb +43 -43
  33. data/lib/glue/property.rb +392 -392
  34. data/lib/glue/sanitize.rb +34 -34
  35. data/lib/glue/settings.rb +1 -1
  36. data/lib/glue/snapshot.rb +104 -0
  37. data/lib/glue/string.rb +129 -129
  38. data/lib/glue/time.rb +53 -53
  39. data/lib/glue/uri.rb +162 -162
  40. data/lib/glue/validation.rb +421 -421
  41. data/lib/vendor/blankslate.rb +53 -0
  42. data/test/glue/builder/tc_xml.rb +56 -0
  43. data/test/glue/tc_aspects.rb +90 -90
  44. data/test/glue/tc_attribute.rb +11 -11
  45. data/test/glue/tc_builder.rb +30 -0
  46. data/test/glue/tc_configuration.rb +97 -97
  47. data/test/glue/tc_flexob.rb +10 -10
  48. data/test/glue/tc_hash.rb +23 -23
  49. data/test/glue/tc_localization.rb +49 -0
  50. data/test/glue/tc_logger.rb +31 -31
  51. data/test/glue/tc_numbers.rb +9 -9
  52. data/test/glue/tc_property.rb +67 -67
  53. data/test/glue/tc_property_mixins.rb +17 -17
  54. data/test/glue/tc_property_type_checking.rb +13 -13
  55. data/test/glue/tc_strings.rb +94 -94
  56. data/test/glue/tc_uri.rb +65 -65
  57. data/test/glue/tc_validation.rb +196 -196
  58. metadata +26 -4
data/lib/glue/flexob.rb CHANGED
@@ -5,25 +5,25 @@ require 'ostruct'
5
5
 
6
6
  class Flexob < OpenStruct
7
7
 
8
- def update(hash)
9
- hash.each do |k, v|
10
- send("#{k}=", v)
11
- end
12
- end
13
- alias_method :set, :update
8
+ def update(hash)
9
+ hash.each do |k, v|
10
+ send("#{k}=", v)
11
+ end
12
+ end
13
+ alias_method :set, :update
14
14
 
15
- def []=(key, val)
16
- @table[key.to_sym] = val
17
- end
18
-
19
- def [](key)
20
- @table[key.to_sym]
21
- end
15
+ def []=(key, val)
16
+ @table[key.to_sym] = val
17
+ end
18
+
19
+ def [](key)
20
+ @table[key.to_sym]
21
+ end
22
22
 
23
- def each(&block)
24
- @table.each(&block)
25
- end
26
-
23
+ def each(&block)
24
+ @table.each(&block)
25
+ end
26
+
27
27
  end
28
28
 
29
29
  # * George Moschovitis <gm@navel.gr>
data/lib/glue/hash.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # * George Moschovitis <gm@navel.gr>
2
2
  # (c) 2004-2005 Navel, all rights reserved.
3
- # $Id: hash.rb 1 2005-04-11 11:04:30Z gmosx $
3
+ # $Id: hash.rb 182 2005-07-22 10:07:50Z gmosx $
4
4
 
5
5
  require 'sync'
6
6
 
@@ -13,41 +13,41 @@ module Glue
13
13
  # implementations!
14
14
 
15
15
  class SafeHash < Hash
16
- attr :sync
16
+ attr :sync
17
17
 
18
- # gmosx: delegator is not used.
19
- #
20
- def initialize(delegator = nil)
21
- @sync = ::Sync.new
22
- end
18
+ # gmosx: delegator is not used.
19
+ #
20
+ def initialize(delegator = nil)
21
+ @sync = ::Sync.new
22
+ end
23
23
 
24
- def [](key)
25
- @sync.synchronize(::Sync::SH) { super }
26
- end
24
+ def [](key)
25
+ @sync.synchronize(::Sync::SH) { super }
26
+ end
27
27
 
28
- def []=(key, value)
29
- @sync.synchronize(::Sync::EX) { super }
30
- end
28
+ def []=(key, value)
29
+ @sync.synchronize(::Sync::EX) { super }
30
+ end
31
31
 
32
- def delete(key)
33
- @sync.synchronize(::Sync::EX) { super }
34
- end
32
+ def delete(key)
33
+ @sync.synchronize(::Sync::EX) { super }
34
+ end
35
35
 
36
- def clear
37
- @sync.synchronize(::Sync::EX) { super }
38
- end
36
+ def clear
37
+ @sync.synchronize(::Sync::EX) { super }
38
+ end
39
39
 
40
- def size
41
- @sync.synchronize(::Sync::SH) { super }
42
- end
40
+ def size
41
+ @sync.synchronize(::Sync::SH) { super }
42
+ end
43
43
 
44
- def values
45
- @sync.synchronize(::Sync::SH) { super }
46
- end
44
+ def values
45
+ @sync.synchronize(::Sync::SH) { super }
46
+ end
47
47
 
48
- def keys
49
- @sync.synchronize(::Sync::SH) { super }
50
- end
48
+ def keys
49
+ @sync.synchronize(::Sync::SH) { super }
50
+ end
51
51
 
52
52
  end
53
53
 
@@ -68,54 +68,54 @@ end
68
68
  # hash = SafeHashDelegator.new(Hash.new)
69
69
 
70
70
  class SafeHashDelegator < Hash
71
- attr :delegate, :sync
71
+ attr :delegate, :sync
72
72
 
73
- def initialize(delegate)
74
- @delegate = delegate
75
- @sync = ::Sync.new
76
- end
73
+ def initialize(delegate)
74
+ @delegate = delegate
75
+ @sync = ::Sync.new
76
+ end
77
77
 
78
- def [](key)
79
- @sync.synchronize(::Sync::SH) {
80
- @delegate[key]
81
- }
78
+ def [](key)
79
+ @sync.synchronize(::Sync::SH) {
80
+ @delegate[key]
81
+ }
82
82
  end
83
83
 
84
84
  def []=(key, value)
85
- @sync.synchronize(::Sync::EX) {
86
- @delegate[key] = value
87
- }
88
- end
89
-
90
- def delete(key)
91
- @sync.synchronize(::Sync::EX) {
92
- @delegate.delete(key)
93
- }
94
- end
95
-
96
- def clear
97
- @sync.synchronize(::Sync::EX) {
98
- @delegate.clear
99
- }
100
- end
101
-
102
- def size
103
- @sync.synchronize(::Sync::SH) {
104
- @delegate.size()
105
- }
106
- end
107
-
108
- def values
109
- @sync.synchronize(::Sync::SH) {
110
- @delegate.values()
111
- }
112
- end
113
-
114
- def keys
115
- @sync.synchronize(::Sync::SH) {
116
- @delegate.keys()
117
- }
118
- end
85
+ @sync.synchronize(::Sync::EX) {
86
+ @delegate[key] = value
87
+ }
88
+ end
89
+
90
+ def delete(key)
91
+ @sync.synchronize(::Sync::EX) {
92
+ @delegate.delete(key)
93
+ }
94
+ end
95
+
96
+ def clear
97
+ @sync.synchronize(::Sync::EX) {
98
+ @delegate.clear
99
+ }
100
+ end
101
+
102
+ def size
103
+ @sync.synchronize(::Sync::SH) {
104
+ @delegate.size()
105
+ }
106
+ end
107
+
108
+ def values
109
+ @sync.synchronize(::Sync::SH) {
110
+ @delegate.values()
111
+ }
112
+ end
113
+
114
+ def keys
115
+ @sync.synchronize(::Sync::SH) {
116
+ @delegate.keys()
117
+ }
118
+ end
119
119
 
120
120
  end
121
121
 
data/lib/glue/helper.rb CHANGED
@@ -12,18 +12,18 @@ module Glue
12
12
 
13
13
  module Helpers
14
14
 
15
- def self.append_features(base)
16
- base.module_eval do
17
- def self.helper(*modules)
18
- for mod in modules
19
- symbols = mod.instance_methods.collect { |m| m.to_sym }
20
- self.send(:include, mod)
21
- self.send(:private, *symbols)
22
- end
23
- end
24
- end
25
- end
26
-
15
+ def self.append_features(base)
16
+ base.module_eval do
17
+ def self.helper(*modules)
18
+ for mod in modules
19
+ symbols = mod.instance_methods.collect { |m| m.to_sym }
20
+ self.send(:include, mod)
21
+ self.send(:private, *symbols)
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
27
  end
28
28
 
29
29
  end
data/lib/glue/idgen.rb ADDED
@@ -0,0 +1,9 @@
1
+ # Abstract base class of all id generators.
2
+
3
+ class Glue::IdGenerator
4
+ def next
5
+ raise "subclass responsibility"
6
+ end
7
+ end
8
+
9
+ # * Michael Neumann <mneumann@ntecs.de>
@@ -0,0 +1,24 @@
1
+ # Returned ids might not be unique, but it should be very hard to guess the
2
+ # next id.
3
+
4
+ require 'glue/idgen'
5
+ require 'digest/md5'
6
+
7
+ class Glue::Md5IdGenerator < Glue::IdGenerator
8
+ def initialize(salt='ruby')
9
+ @salt = salt
10
+ end
11
+
12
+ def next
13
+ now = Time.now
14
+ md5 = Digest::MD5.new
15
+ md5.update(now.to_s)
16
+ md5.update(now.usec.to_s)
17
+ md5.update(rand(0).to_s)
18
+ md5.update($$.to_s)
19
+ md5.update(@salt.to_s)
20
+ md5.hexdigest
21
+ end
22
+ end
23
+
24
+ # * Michael Neumann <mneumann@ntecs.de>
@@ -0,0 +1,15 @@
1
+ # Returned ids are guaranteed to be unique, but they are easily guessable.
2
+
3
+ require 'glue/idgen'
4
+
5
+ class Glue::SequentialIdGenerator < Glue::IdGenerator
6
+ def initialize(initial_value=0)
7
+ @value = initial_value
8
+ end
9
+
10
+ def next
11
+ @value += 1
12
+ end
13
+ end
14
+
15
+ # * Michael Neumann <mneumann@ntecs.de>
@@ -0,0 +1,44 @@
1
+ module Glue
2
+
3
+ # A serializable method.
4
+ #
5
+ # For example, you can't marshal:
6
+ #
7
+ # "ruby".method(:to_s)
8
+ #
9
+ # But you can:
10
+ #
11
+ # Glue::LiteralMethodCallback.new("ruby", :to_s)
12
+ #
13
+ # or it's equivalent:
14
+ #
15
+ # "ruby".literal_method(:to_s)
16
+
17
+ class LiteralMethod
18
+ attr_reader :obj
19
+
20
+ def initialize(obj, method_id=:call, *args)
21
+ @obj, @method_id = obj, method_id
22
+ @args = args unless args.empty?
23
+ end
24
+
25
+ def call(*args, &block)
26
+ if @args
27
+ @obj.send(@method_id, *(@args+args), &block)
28
+ else
29
+ @obj.send(@method_id, *args, &block)
30
+ end
31
+ end
32
+
33
+ alias [] call
34
+ end
35
+
36
+ end # module Glue
37
+
38
+ class Object
39
+ def literal_method(method_id, *args)
40
+ Glue::LiteralMethodCallback.new(self, method_id, *args)
41
+ end
42
+ end
43
+
44
+ # * Michael Neumann <mneumann@ntecs.de>
@@ -0,0 +1,130 @@
1
+ require 'yaml'
2
+
3
+ require 'glue/aspects'
4
+
5
+ module Glue
6
+
7
+ # Represents a locale.
8
+ #--
9
+ # TODO: initialize translation map from a yaml file.
10
+ #++
11
+
12
+ class Locale
13
+
14
+ # The localization map.
15
+
16
+ attr_accessor :map
17
+
18
+ def initialize(map)
19
+ parse_hash(map)
20
+ end
21
+
22
+ # Transalte the given key.
23
+ #
24
+ # [+args+]
25
+ # An array of arguments. The first argument
26
+ # is the translation key. If additional arguments
27
+ # are provided they are used for sprintf
28
+ # interpolation.
29
+ #--
30
+ # THINK: Possibly avoid the creation of the
31
+ # array by making the api less elegant.
32
+ #++
33
+
34
+ def translate(*args)
35
+ if xlated = @map[args.shift]
36
+ if xlated.is_a?(String)
37
+ args.empty? ? xlated : sprintf(xlated, *args)
38
+ else
39
+ xlated.call(*args)
40
+ end
41
+ end
42
+ end
43
+ alias_method :[], :translate
44
+
45
+ private
46
+
47
+ def parse_hash(map)
48
+ @map = map
49
+ end
50
+
51
+ def parse_yaml(yaml)
52
+ raise 'Not implemented'
53
+ end
54
+
55
+ end
56
+
57
+ # Localization support.
58
+ #
59
+ # === Example
60
+ #
61
+ # locale_en = {
62
+ # 'See you' => 'See you',
63
+ # :long_paragraph => 'The best new books, up to 30% reduced price',
64
+ # :price => 'Price: %d %s',
65
+ # :proc_price => proc { |value, cur| "Price: #{value} #{cur}" }
66
+ # }
67
+ #
68
+ # locale_de = {
69
+ # 'See you' => 'Auf wieder sehen',
70
+ # :long_paragraph => 'Die besten neuer buecher, bis zu 30% reduziert',
71
+ # ...
72
+ # }
73
+ #
74
+ # Localization.add(:en => locale_en, :de => locale_de)
75
+ #
76
+ # lc = Localization.get
77
+ # lc['See you'] -> See you
78
+ # lc[:price, 100, 'euro'] -> Price: 100 euro
79
+ # lc = Localization.get[:de]
80
+ # lc['See you'] -> Auf wiedersehen
81
+ #
82
+ # To make localization even more easier, a LocalizationAspect
83
+ # is provide provided. Additional transformation macros are
84
+ # provided if you require 'nitro/compiler/localization'
85
+
86
+ class Localization
87
+
88
+ class << self
89
+
90
+ # A hash of the available locales.
91
+
92
+ attr_accessor :locales
93
+
94
+ def add(map = {})
95
+ for key, locale in map
96
+ if locale.is_a?(String)
97
+ # this is the name of the localization file.
98
+ locale = YAML.load(File.read(locale))
99
+ end
100
+ @locales[key.to_s] = Locale.new(locale)
101
+ end
102
+ end
103
+
104
+ # Return the localization hash for the given
105
+ # locale.
106
+
107
+ def get(locale = :en)
108
+ locale ||= 'en'
109
+ @locales[locale.to_s]
110
+ end
111
+ alias_method :locale, :get
112
+ alias_method :[], :get
113
+
114
+ end
115
+
116
+ @locales = {}
117
+
118
+ end
119
+
120
+ # Localization Aspect for Nitro controllers.
121
+
122
+ module LocalizationAspect
123
+ def localize
124
+ @lc = Localization[@context.session[:LOCALE]]
125
+ end
126
+ end
127
+
128
+ end
129
+
130
+ # * George Moschovitis <gm@navel.gr>