glue 0.20.0 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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>