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.
- data/CHANGELOG +161 -110
 - data/INSTALL +12 -12
 - data/README +1 -1
 - data/Rakefile +43 -45
 - data/doc/AUTHORS +5 -5
 - data/doc/LICENSE +3 -3
 - data/doc/RELEASES +32 -24
 - data/install.rb +7 -17
 - data/lib/facet/object/alias_class.rb +12 -0
 - data/lib/glue.rb +35 -35
 - data/lib/glue/array.rb +46 -46
 - data/lib/glue/aspects.rb +199 -209
 - data/lib/glue/attribute.rb +15 -15
 - data/lib/glue/autoreload.rb +1 -1
 - data/lib/glue/builder.rb +48 -0
 - data/lib/glue/builder/xml.rb +114 -0
 - data/lib/glue/cache.rb +189 -0
 - data/lib/glue/configuration.rb +108 -90
 - data/lib/glue/flexob.rb +17 -17
 - data/lib/glue/hash.rb +71 -71
 - data/lib/glue/helper.rb +12 -12
 - data/lib/glue/idgen.rb +9 -0
 - data/lib/glue/idgen/md5.rb +24 -0
 - data/lib/glue/idgen/sequential.rb +15 -0
 - data/lib/glue/literal_method.rb +44 -0
 - data/lib/glue/localization.rb +130 -0
 - data/lib/glue/logger.rb +98 -98
 - data/lib/glue/misc.rb +7 -7
 - data/lib/glue/mixins.rb +19 -19
 - data/lib/glue/number.rb +8 -8
 - data/lib/glue/object.rb +2 -2
 - data/lib/glue/pool.rb +43 -43
 - data/lib/glue/property.rb +392 -392
 - data/lib/glue/sanitize.rb +34 -34
 - data/lib/glue/settings.rb +1 -1
 - data/lib/glue/snapshot.rb +104 -0
 - data/lib/glue/string.rb +129 -129
 - data/lib/glue/time.rb +53 -53
 - data/lib/glue/uri.rb +162 -162
 - data/lib/glue/validation.rb +421 -421
 - data/lib/vendor/blankslate.rb +53 -0
 - data/test/glue/builder/tc_xml.rb +56 -0
 - data/test/glue/tc_aspects.rb +90 -90
 - data/test/glue/tc_attribute.rb +11 -11
 - data/test/glue/tc_builder.rb +30 -0
 - data/test/glue/tc_configuration.rb +97 -97
 - data/test/glue/tc_flexob.rb +10 -10
 - data/test/glue/tc_hash.rb +23 -23
 - data/test/glue/tc_localization.rb +49 -0
 - data/test/glue/tc_logger.rb +31 -31
 - data/test/glue/tc_numbers.rb +9 -9
 - data/test/glue/tc_property.rb +67 -67
 - data/test/glue/tc_property_mixins.rb +17 -17
 - data/test/glue/tc_property_type_checking.rb +13 -13
 - data/test/glue/tc_strings.rb +94 -94
 - data/test/glue/tc_uri.rb +65 -65
 - data/test/glue/tc_validation.rb +196 -196
 - metadata +26 -4
 
    
        data/lib/glue/autoreload.rb
    CHANGED
    
    
    
        data/lib/glue/builder.rb
    ADDED
    
    | 
         @@ -0,0 +1,48 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Glue
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # A Builder integrates a number of Modules containing text 
         
     | 
| 
      
 4 
     | 
    
         
            +
            # manipulation utilities and provides an alternative
         
     | 
| 
      
 5 
     | 
    
         
            +
            # 'accomulation' interface.
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            class Builder
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              # The builder output is accomulated in the buffer.
         
     | 
| 
      
 10 
     | 
    
         
            +
              
         
     | 
| 
      
 11 
     | 
    
         
            +
              attr_accessor :buffer
         
     | 
| 
      
 12 
     | 
    
         
            +
              
         
     | 
| 
      
 13 
     | 
    
         
            +
              class << self 
         
     | 
| 
      
 14 
     | 
    
         
            +
              
         
     | 
| 
      
 15 
     | 
    
         
            +
                def include_builder(*modules)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  for mod in modules
         
     | 
| 
      
 17 
     | 
    
         
            +
                    include mod      
         
     | 
| 
      
 18 
     | 
    
         
            +
                    for meth in mod.public_instance_methods
         
     | 
| 
      
 19 
     | 
    
         
            +
                      self.module_eval %{
         
     | 
| 
      
 20 
     | 
    
         
            +
                        alias_method :_mixin_#{meth}, :#{meth}
         
     | 
| 
      
 21 
     | 
    
         
            +
                        def #{meth}(*args)
         
     | 
| 
      
 22 
     | 
    
         
            +
                          @buffer << _mixin_#{meth}(*args)
         
     | 
| 
      
 23 
     | 
    
         
            +
                          return self
         
     | 
| 
      
 24 
     | 
    
         
            +
                        end
         
     | 
| 
      
 25 
     | 
    
         
            +
                      }
         
     | 
| 
      
 26 
     | 
    
         
            +
                    end      
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
                alias_method :builder, :include_builder
         
     | 
| 
      
 30 
     | 
    
         
            +
                
         
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
              # Provide the target where the builder output will be
         
     | 
| 
      
 34 
     | 
    
         
            +
              # accomulated. The builder utilizes duck typing to make it
         
     | 
| 
      
 35 
     | 
    
         
            +
              # compatible with anly target responding to <<.
         
     | 
| 
      
 36 
     | 
    
         
            +
              
         
     | 
| 
      
 37 
     | 
    
         
            +
              def initialize(buffer = '', *modules)
         
     | 
| 
      
 38 
     | 
    
         
            +
                @buffer = buffer
         
     | 
| 
      
 39 
     | 
    
         
            +
                
         
     | 
| 
      
 40 
     | 
    
         
            +
              end  
         
     | 
| 
      
 41 
     | 
    
         
            +
              
         
     | 
| 
      
 42 
     | 
    
         
            +
            end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
            end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
            # * George Moschovitis <gm@navel.gr>
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            __END__
         
     | 
| 
         @@ -0,0 +1,114 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'glue/builder'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'nitro/mixin/xhtml'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'nitro/mixin/form'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'nitro/mixin/table'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            module Glue
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            # A Builder for programmatically building XML blocks. 
         
     | 
| 
      
 10 
     | 
    
         
            +
            #--
         
     | 
| 
      
 11 
     | 
    
         
            +
            # TODO: move to nitro or move mixins here.
         
     | 
| 
      
 12 
     | 
    
         
            +
            #++
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            class XmlBuilder < Builder
         
     | 
| 
      
 15 
     | 
    
         
            +
              include_builder Nitro::XhtmlMixin
         
     | 
| 
      
 16 
     | 
    
         
            +
              include_builder Nitro::TableMixin
         
     | 
| 
      
 17 
     | 
    
         
            +
              include_builder Nitro::FormMixin
         
     | 
| 
      
 18 
     | 
    
         
            +
              
         
     | 
| 
      
 19 
     | 
    
         
            +
              def method_missing(tag, *args, &block)
         
     | 
| 
      
 20 
     | 
    
         
            +
                self.class.module_eval <<-"end_eval", __FILE__, __LINE__
         
     | 
| 
      
 21 
     | 
    
         
            +
                  def #{tag}(*args)
         
     | 
| 
      
 22 
     | 
    
         
            +
                    attrs = args.last.is_a?(Hash) ? args.pop : nil
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                    if block_given?
         
     | 
| 
      
 25 
     | 
    
         
            +
                      start_tag!('#{tag}', attrs)
         
     | 
| 
      
 26 
     | 
    
         
            +
                      yield
         
     | 
| 
      
 27 
     | 
    
         
            +
                      end_tag!('#{tag}')
         
     | 
| 
      
 28 
     | 
    
         
            +
                    elsif (!args.empty?)
         
     | 
| 
      
 29 
     | 
    
         
            +
                      start_tag!('#{tag}', attrs)
         
     | 
| 
      
 30 
     | 
    
         
            +
                      @buffer << args.first 
         
     | 
| 
      
 31 
     | 
    
         
            +
                      end_tag!('#{tag}')
         
     | 
| 
      
 32 
     | 
    
         
            +
                    else
         
     | 
| 
      
 33 
     | 
    
         
            +
                      start_tag!('#{tag}', attrs, false)
         
     | 
| 
      
 34 
     | 
    
         
            +
                      @buffer << ' />'
         
     | 
| 
      
 35 
     | 
    
         
            +
                    end
         
     | 
| 
      
 36 
     | 
    
         
            +
                    
         
     | 
| 
      
 37 
     | 
    
         
            +
                    return self
         
     | 
| 
      
 38 
     | 
    
         
            +
                  end
         
     | 
| 
      
 39 
     | 
    
         
            +
                end_eval
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                self.send(tag, *args, &block)
         
     | 
| 
      
 42 
     | 
    
         
            +
              end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
              # Emit the start (opening) tag of an element.
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
              def start_tag!(tag, attributes = nil, close = true)
         
     | 
| 
      
 47 
     | 
    
         
            +
                unless attributes
         
     | 
| 
      
 48 
     | 
    
         
            +
                  if close
         
     | 
| 
      
 49 
     | 
    
         
            +
                    @buffer << "<#{tag}>"
         
     | 
| 
      
 50 
     | 
    
         
            +
                  else
         
     | 
| 
      
 51 
     | 
    
         
            +
                    @buffer << "<#{tag}"
         
     | 
| 
      
 52 
     | 
    
         
            +
                  end
         
     | 
| 
      
 53 
     | 
    
         
            +
                else
         
     | 
| 
      
 54 
     | 
    
         
            +
                  @buffer << "<#{tag}"
         
     | 
| 
      
 55 
     | 
    
         
            +
                  for name, value in attributes
         
     | 
| 
      
 56 
     | 
    
         
            +
                    if value
         
     | 
| 
      
 57 
     | 
    
         
            +
                      @buffer << %| #{name}="#{value}"|
         
     | 
| 
      
 58 
     | 
    
         
            +
                    else
         
     | 
| 
      
 59 
     | 
    
         
            +
                      @buffer << %| #{name}="1"|
         
     | 
| 
      
 60 
     | 
    
         
            +
                    end
         
     | 
| 
      
 61 
     | 
    
         
            +
                  end
         
     | 
| 
      
 62 
     | 
    
         
            +
                  @buffer << ">" if close
         
     | 
| 
      
 63 
     | 
    
         
            +
                end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                return self
         
     | 
| 
      
 66 
     | 
    
         
            +
              end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
              # Emit the end (closing) tag of an element.
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
              def end_tag!(tag)
         
     | 
| 
      
 71 
     | 
    
         
            +
                @buffer << "</#{tag}>" 
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                return self
         
     | 
| 
      
 74 
     | 
    
         
            +
              end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
              # Emit a text string.
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
              def text!(str)
         
     | 
| 
      
 79 
     | 
    
         
            +
                @buffer << str
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                return self
         
     | 
| 
      
 82 
     | 
    
         
            +
              end
         
     | 
| 
      
 83 
     | 
    
         
            +
              alias_method :print, :text!
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
              # Emit a comment.
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
              def comment!(str)
         
     | 
| 
      
 88 
     | 
    
         
            +
                @buffer << "<!-- #{str} -->" 
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                return self
         
     | 
| 
      
 91 
     | 
    
         
            +
              end
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
              # Emit a processing instruction.
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
              def processing_instruction!(name, attributes = nil)
         
     | 
| 
      
 96 
     | 
    
         
            +
                unless attributes
         
     | 
| 
      
 97 
     | 
    
         
            +
                  @buffer << "<?#{name} ?>"
         
     | 
| 
      
 98 
     | 
    
         
            +
                else
         
     | 
| 
      
 99 
     | 
    
         
            +
                  @buffer << "<?#{name} "
         
     | 
| 
      
 100 
     | 
    
         
            +
                  attributes.each do |a, v|
         
     | 
| 
      
 101 
     | 
    
         
            +
                    @buffer << %[#{a}="#{v}" ]
         
     | 
| 
      
 102 
     | 
    
         
            +
                  end
         
     | 
| 
      
 103 
     | 
    
         
            +
                  @buffer << "?>"
         
     | 
| 
      
 104 
     | 
    
         
            +
                end
         
     | 
| 
      
 105 
     | 
    
         
            +
                
         
     | 
| 
      
 106 
     | 
    
         
            +
                return self
         
     | 
| 
      
 107 
     | 
    
         
            +
              end
         
     | 
| 
      
 108 
     | 
    
         
            +
              alias_method :pi!, :processing_instruction!
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
            end
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
            end
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
            # * George Moschovitis <gm@navel.gr>
         
     | 
    
        data/lib/glue/cache.rb
    ADDED
    
    | 
         @@ -0,0 +1,189 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            unless Enumerable.instance_methods.include?("min_by")
         
     | 
| 
      
 2 
     | 
    
         
            +
              # for Ruby 1.8
         
     | 
| 
      
 3 
     | 
    
         
            +
              module Enumerable
         
     | 
| 
      
 4 
     | 
    
         
            +
                def min_by(&block)
         
     | 
| 
      
 5 
     | 
    
         
            +
                  min {|i,j| block.call(i) <=> block.call(j) }
         
     | 
| 
      
 6 
     | 
    
         
            +
                end
         
     | 
| 
      
 7 
     | 
    
         
            +
              end
         
     | 
| 
      
 8 
     | 
    
         
            +
            end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            module Glue
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            # Abstract super class of all cache implementations.
         
     | 
| 
      
 13 
     | 
    
         
            +
            class Cache; end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            # Abstract super class of all caching strategies.
         
     | 
| 
      
 16 
     | 
    
         
            +
            class Cache::Strategy; end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            # Implements an unbounded cache strategy. The cache size can 
         
     | 
| 
      
 19 
     | 
    
         
            +
            # grow to infinity.
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            class Cache::Strategy::Unbounded < Cache::Strategy
         
     | 
| 
      
 22 
     | 
    
         
            +
              class Item < Struct.new(:value); end
         
     | 
| 
      
 23 
     | 
    
         
            +
              def item_class() Item end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
              def access(item) end
         
     | 
| 
      
 26 
     | 
    
         
            +
              def delete(item) end
         
     | 
| 
      
 27 
     | 
    
         
            +
              def insert_or_extrude(item, enum) end
         
     | 
| 
      
 28 
     | 
    
         
            +
            end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            # Abstract class for a capacity bounded strategy. Only up to 
         
     | 
| 
      
 31 
     | 
    
         
            +
            # _capacity_ items are allowed to be stored in the cache 
         
     | 
| 
      
 32 
     | 
    
         
            +
            # at any time.
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            class Cache::Strategy::CapacityBounded < Cache::Strategy
         
     | 
| 
      
 35 
     | 
    
         
            +
              attr_accessor :capacity
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
              def initialize(capacity)
         
     | 
| 
      
 38 
     | 
    
         
            +
                @capacity = capacity
         
     | 
| 
      
 39 
     | 
    
         
            +
                @n_items = 0  # number of items in cache
         
     | 
| 
      
 40 
     | 
    
         
            +
              end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
              def inc(item)
         
     | 
| 
      
 43 
     | 
    
         
            +
                raise if full?
         
     | 
| 
      
 44 
     | 
    
         
            +
                @n_items += 1
         
     | 
| 
      
 45 
     | 
    
         
            +
              end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
              def dec(item)
         
     | 
| 
      
 48 
     | 
    
         
            +
                raise if empty?
         
     | 
| 
      
 49 
     | 
    
         
            +
                @n_items -= 1
         
     | 
| 
      
 50 
     | 
    
         
            +
              end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
              def full?
         
     | 
| 
      
 53 
     | 
    
         
            +
                @n_items >= @capacity 
         
     | 
| 
      
 54 
     | 
    
         
            +
              end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
              def empty?
         
     | 
| 
      
 57 
     | 
    
         
            +
                @n_items == 0
         
     | 
| 
      
 58 
     | 
    
         
            +
              end
         
     | 
| 
      
 59 
     | 
    
         
            +
            end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
            # Implements the least frequently used (LFU) strategy.
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
            class Cache::Strategy::LFU < Cache::Strategy::CapacityBounded
         
     | 
| 
      
 64 
     | 
    
         
            +
              class Item < Struct.new(:value, :freq); end 
         
     | 
| 
      
 65 
     | 
    
         
            +
              def item_class() Item end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
              def access(item)
         
     | 
| 
      
 68 
     | 
    
         
            +
                item.freq += 1
         
     | 
| 
      
 69 
     | 
    
         
            +
              end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
              def delete(item)
         
     | 
| 
      
 72 
     | 
    
         
            +
                dec(item)
         
     | 
| 
      
 73 
     | 
    
         
            +
              end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
              # enum::
         
     | 
| 
      
 76 
     | 
    
         
            +
              #    a [key, item] enumerable
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
              def insert_or_extrude(item, enum)
         
     | 
| 
      
 79 
     | 
    
         
            +
                # find least recently used key/item and yield
         
     | 
| 
      
 80 
     | 
    
         
            +
                yield enum.min_by {|key, it| it.freq} while full?
         
     | 
| 
      
 81 
     | 
    
         
            +
                item.freq = 0 
         
     | 
| 
      
 82 
     | 
    
         
            +
                inc(item)
         
     | 
| 
      
 83 
     | 
    
         
            +
              end
         
     | 
| 
      
 84 
     | 
    
         
            +
            end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
            # Implements the least recently used (LRU) strategy.
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
            class Cache::Strategy::LRU < Cache::Strategy::CapacityBounded
         
     | 
| 
      
 89 
     | 
    
         
            +
              class Item < Struct.new(:value, :time); end 
         
     | 
| 
      
 90 
     | 
    
         
            +
              def item_class() Item end
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
              def access(item)
         
     | 
| 
      
 93 
     | 
    
         
            +
                item.time = Time.now
         
     | 
| 
      
 94 
     | 
    
         
            +
              end
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
              def delete(item)
         
     | 
| 
      
 97 
     | 
    
         
            +
                dec(item)
         
     | 
| 
      
 98 
     | 
    
         
            +
              end
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
              # enum::
         
     | 
| 
      
 101 
     | 
    
         
            +
              #    a [key, item] enumerable
         
     | 
| 
      
 102 
     | 
    
         
            +
              #
         
     | 
| 
      
 103 
     | 
    
         
            +
              def insert_or_extrude(item, enum)
         
     | 
| 
      
 104 
     | 
    
         
            +
                # find least recently used key/item and yield
         
     | 
| 
      
 105 
     | 
    
         
            +
                yield enum.min_by {|key, it| it.time} while full?
         
     | 
| 
      
 106 
     | 
    
         
            +
                item.time = Time.now
         
     | 
| 
      
 107 
     | 
    
         
            +
                inc(item)
         
     | 
| 
      
 108 
     | 
    
         
            +
              end
         
     | 
| 
      
 109 
     | 
    
         
            +
            end
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
            # Implements a cache using a parameterizable strategy and a storage. 
         
     | 
| 
      
 112 
     | 
    
         
            +
            # The protocol that the _store_ must understand is: 
         
     | 
| 
      
 113 
     | 
    
         
            +
            #
         
     | 
| 
      
 114 
     | 
    
         
            +
            #   fetch(key) -> val
         
     | 
| 
      
 115 
     | 
    
         
            +
            #   has_key?(key)
         
     | 
| 
      
 116 
     | 
    
         
            +
            #   delete(key) -> val
         
     | 
| 
      
 117 
     | 
    
         
            +
            #   each {|key, val| }
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
            class Cache::StorageCache < Cache
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
              def initialize(strategy, store=Hash.new, store_on_update=false)
         
     | 
| 
      
 122 
     | 
    
         
            +
                @strategy = strategy
         
     | 
| 
      
 123 
     | 
    
         
            +
                @store = store
         
     | 
| 
      
 124 
     | 
    
         
            +
                @store_on_update = store_on_update
         
     | 
| 
      
 125 
     | 
    
         
            +
              end
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
              def has_key?(key)
         
     | 
| 
      
 128 
     | 
    
         
            +
                @store.has_key?(key)
         
     | 
| 
      
 129 
     | 
    
         
            +
              end
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
              def delete(key)
         
     | 
| 
      
 132 
     | 
    
         
            +
                if @store.has_key?(key)
         
     | 
| 
      
 133 
     | 
    
         
            +
                  item = @store.delete(key)
         
     | 
| 
      
 134 
     | 
    
         
            +
                  @strategy.delete(item)
         
     | 
| 
      
 135 
     | 
    
         
            +
                  item.value
         
     | 
| 
      
 136 
     | 
    
         
            +
                else
         
     | 
| 
      
 137 
     | 
    
         
            +
                  nil
         
     | 
| 
      
 138 
     | 
    
         
            +
                end
         
     | 
| 
      
 139 
     | 
    
         
            +
              end
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
              def fetch(key, default_value=nil)
         
     | 
| 
      
 142 
     | 
    
         
            +
                if @store.has_key?(key)
         
     | 
| 
      
 143 
     | 
    
         
            +
                  item = @store.fetch(key)
         
     | 
| 
      
 144 
     | 
    
         
            +
                  @strategy.access(item)
         
     | 
| 
      
 145 
     | 
    
         
            +
                  @store.store(key, item) if @store_on_update
         
     | 
| 
      
 146 
     | 
    
         
            +
                  item.value
         
     | 
| 
      
 147 
     | 
    
         
            +
                else
         
     | 
| 
      
 148 
     | 
    
         
            +
                  default_value
         
     | 
| 
      
 149 
     | 
    
         
            +
                end
         
     | 
| 
      
 150 
     | 
    
         
            +
              end
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
              def store(key, value)
         
     | 
| 
      
 153 
     | 
    
         
            +
                if @store.has_key?(key)
         
     | 
| 
      
 154 
     | 
    
         
            +
                  # update only 
         
     | 
| 
      
 155 
     | 
    
         
            +
                  item = @store.fetch(key)
         
     | 
| 
      
 156 
     | 
    
         
            +
                  item.value = value 
         
     | 
| 
      
 157 
     | 
    
         
            +
                  @strategy.access(item)
         
     | 
| 
      
 158 
     | 
    
         
            +
                  @store.store(key, item) if @store_on_update
         
     | 
| 
      
 159 
     | 
    
         
            +
                else 
         
     | 
| 
      
 160 
     | 
    
         
            +
                  # insert new item
         
     | 
| 
      
 161 
     | 
    
         
            +
                  item = @strategy.item_class.new 
         
     | 
| 
      
 162 
     | 
    
         
            +
                  item.value = value  
         
     | 
| 
      
 163 
     | 
    
         
            +
                  @strategy.insert_or_extrude(item, @store) do |k, i|
         
     | 
| 
      
 164 
     | 
    
         
            +
                    @strategy.delete(i)
         
     | 
| 
      
 165 
     | 
    
         
            +
                    @store.delete(k)
         
     | 
| 
      
 166 
     | 
    
         
            +
                  end
         
     | 
| 
      
 167 
     | 
    
         
            +
                  @store.store(key, item) # correct!
         
     | 
| 
      
 168 
     | 
    
         
            +
                end
         
     | 
| 
      
 169 
     | 
    
         
            +
                value
         
     | 
| 
      
 170 
     | 
    
         
            +
              end
         
     | 
| 
      
 171 
     | 
    
         
            +
             
     | 
| 
      
 172 
     | 
    
         
            +
              alias [] fetch
         
     | 
| 
      
 173 
     | 
    
         
            +
              alias []= store
         
     | 
| 
      
 174 
     | 
    
         
            +
            end
         
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
      
 176 
     | 
    
         
            +
            # Implements an in-memory cache (uses a Hash as store) with a LRU replacement
         
     | 
| 
      
 177 
     | 
    
         
            +
            # stragegy.
         
     | 
| 
      
 178 
     | 
    
         
            +
             
     | 
| 
      
 179 
     | 
    
         
            +
            class Cache::MemoryLRUCache < Cache::StorageCache
         
     | 
| 
      
 180 
     | 
    
         
            +
              DEFAULT_CAPACITY = 20
         
     | 
| 
      
 181 
     | 
    
         
            +
             
     | 
| 
      
 182 
     | 
    
         
            +
              def initialize(capacity=DEFAULT_CAPACITY)
         
     | 
| 
      
 183 
     | 
    
         
            +
                super(Cache::Strategy::LRU.new(capacity))
         
     | 
| 
      
 184 
     | 
    
         
            +
              end
         
     | 
| 
      
 185 
     | 
    
         
            +
            end
         
     | 
| 
      
 186 
     | 
    
         
            +
             
     | 
| 
      
 187 
     | 
    
         
            +
            end # module Glue
         
     | 
| 
      
 188 
     | 
    
         
            +
             
     | 
| 
      
 189 
     | 
    
         
            +
            # * Michael Neumann <mneumann@ntecs.de>
         
     | 
    
        data/lib/glue/configuration.rb
    CHANGED
    
    | 
         @@ -14,87 +14,105 @@ require 'glue/flexob' 
     | 
|
| 
       14 
14 
     | 
    
         | 
| 
       15 
15 
     | 
    
         
             
            class Configuration
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
      
 17 
     | 
    
         
            +
              # A hash of setting owners. Use double @'s to allow for
         
     | 
| 
      
 18 
     | 
    
         
            +
              # the Settings alias.
         
     | 
| 
      
 19 
     | 
    
         
            +
              #--
         
     | 
| 
      
 20 
     | 
    
         
            +
              # TODO: find a better name.
         
     | 
| 
      
 21 
     | 
    
         
            +
              #++
         
     | 
| 
      
 22 
     | 
    
         
            +
                
         
     | 
| 
      
 23 
     | 
    
         
            +
              @@owners = Glue::SafeHash.new  
         
     | 
| 
       24 
24 
     | 
    
         | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
      
 25 
     | 
    
         
            +
              # A datastructure to store Settings metadata.
         
     | 
| 
      
 26 
     | 
    
         
            +
              
         
     | 
| 
      
 27 
     | 
    
         
            +
              class Setting
         
     | 
| 
      
 28 
     | 
    
         
            +
                attr_accessor :owner, :name, :type, :value, :options
         
     | 
| 
      
 29 
     | 
    
         
            +
                
         
     | 
| 
      
 30 
     | 
    
         
            +
                def initialize(owner, name, options)
         
     | 
| 
      
 31 
     | 
    
         
            +
                  raise ArgumentError.new('A default value is required') unless options.key?(:default)
         
     | 
| 
      
 32 
     | 
    
         
            +
                  @owner, @name = owner, name
         
     | 
| 
      
 33 
     | 
    
         
            +
                  @options = options
         
     | 
| 
      
 34 
     | 
    
         
            +
                  @value = options[:default]
         
     | 
| 
      
 35 
     | 
    
         
            +
                  @type = options[:type] = options[:type] || @value.class
         
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
       37 
37 
     | 
    
         | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
      
 38 
     | 
    
         
            +
                def value=(value)
         
     | 
| 
      
 39 
     | 
    
         
            +
                  @value = value
         
     | 
| 
      
 40 
     | 
    
         
            +
                  constant(@owner).module_eval %{
         
     | 
| 
      
 41 
     | 
    
         
            +
                    @@#{@name} = #{value.inspect}
         
     | 
| 
      
 42 
     | 
    
         
            +
                  }
         
     | 
| 
      
 43 
     | 
    
         
            +
                end
         
     | 
| 
       44 
44 
     | 
    
         | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
      
 45 
     | 
    
         
            +
                def to_s
         
     | 
| 
      
 46 
     | 
    
         
            +
                  @value.to_s
         
     | 
| 
      
 47 
     | 
    
         
            +
                end
         
     | 
| 
      
 48 
     | 
    
         
            +
              end
         
     | 
| 
      
 49 
     | 
    
         
            +
              
         
     | 
| 
      
 50 
     | 
    
         
            +
              class << self
         
     | 
| 
      
 51 
     | 
    
         
            +
              
         
     | 
| 
      
 52 
     | 
    
         
            +
                # Inject the configuration parameters to configuration
         
     | 
| 
      
 53 
     | 
    
         
            +
                # classes.
         
     | 
| 
      
 54 
     | 
    
         
            +
                
         
     | 
| 
      
 55 
     | 
    
         
            +
                def setup(options)
         
     | 
| 
      
 56 
     | 
    
         
            +
                  options.each do |owner, ss|
         
     | 
| 
      
 57 
     | 
    
         
            +
                    next unless ss
         
     | 
| 
      
 58 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 59 
     | 
    
         
            +
                      owner = constant(owner)
         
     | 
| 
      
 60 
     | 
    
         
            +
                    rescue NameError
         
     | 
| 
      
 61 
     | 
    
         
            +
                      next
         
     | 
| 
      
 62 
     | 
    
         
            +
                    end
         
     | 
| 
      
 63 
     | 
    
         
            +
                    ss.each do |name, s|
         
     | 
| 
      
 64 
     | 
    
         
            +
                      @@owners[owner][name.to_sym].value = s
         
     | 
| 
      
 65 
     | 
    
         
            +
                      owner.module_eval %{
         
     | 
| 
      
 66 
     | 
    
         
            +
                        @@#{name} = #{s.inspect}
         
     | 
| 
      
 67 
     | 
    
         
            +
                      }
         
     | 
| 
      
 68 
     | 
    
         
            +
                    end 
         
     | 
| 
      
 69 
     | 
    
         
            +
                  end
         
     | 
| 
      
 70 
     | 
    
         
            +
                end
         
     | 
| 
       63 
71 
     | 
    
         | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
       70 
     | 
    
         
            -
             
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
     | 
    
         
            -
             
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
       75 
     | 
    
         
            -
             
     | 
| 
       76 
     | 
    
         
            -
             
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
       78 
     | 
    
         
            -
             
     | 
| 
       79 
     | 
    
         
            -
             
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
       81 
     | 
    
         
            -
             
     | 
| 
       82 
     | 
    
         
            -
             
     | 
| 
       83 
     | 
    
         
            -
             
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
       85 
     | 
    
         
            -
             
     | 
| 
       86 
     | 
    
         
            -
             
     | 
| 
       87 
     | 
    
         
            -
             
     | 
| 
       88 
     | 
    
         
            -
             
     | 
| 
       89 
     | 
    
         
            -
             
     | 
| 
      
 72 
     | 
    
         
            +
                # Parse configuration parameters in yaml format.
         
     | 
| 
      
 73 
     | 
    
         
            +
                
         
     | 
| 
      
 74 
     | 
    
         
            +
                def parse(options)
         
     | 
| 
      
 75 
     | 
    
         
            +
                  temp = YAML::load(options)
         
     | 
| 
      
 76 
     | 
    
         
            +
                  options = {}
         
     | 
| 
      
 77 
     | 
    
         
            +
                  temp.each do |k, v| 
         
     | 
| 
      
 78 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 79 
     | 
    
         
            +
                      options[constant(k.gsub(/\./, '::').to_sym)] = v 
         
     | 
| 
      
 80 
     | 
    
         
            +
                    rescue Object
         
     | 
| 
      
 81 
     | 
    
         
            +
                      options[k] = v 
         
     | 
| 
      
 82 
     | 
    
         
            +
                    end
         
     | 
| 
      
 83 
     | 
    
         
            +
                  end
         
     | 
| 
      
 84 
     | 
    
         
            +
                  setup(options)
         
     | 
| 
      
 85 
     | 
    
         
            +
                end
         
     | 
| 
      
 86 
     | 
    
         
            +
                
         
     | 
| 
      
 87 
     | 
    
         
            +
                # Load and parse an external yaml configuration file.
         
     | 
| 
      
 88 
     | 
    
         
            +
                
         
     | 
| 
      
 89 
     | 
    
         
            +
                def load(filename)
         
     | 
| 
      
 90 
     | 
    
         
            +
                  parse(File.read(filename))
         
     | 
| 
      
 91 
     | 
    
         
            +
                end
         
     | 
| 
      
 92 
     | 
    
         
            +
                
         
     | 
| 
      
 93 
     | 
    
         
            +
                def add_setting(owner, name, options)
         
     | 
| 
      
 94 
     | 
    
         
            +
                  s = @@owners[owner] || {}
         
     | 
| 
      
 95 
     | 
    
         
            +
                  s[name] = Setting.new(owner, name, options)
         
     | 
| 
      
 96 
     | 
    
         
            +
                  @@owners[owner] = s
         
     | 
| 
      
 97 
     | 
    
         
            +
                end
         
     | 
| 
      
 98 
     | 
    
         
            +
                
         
     | 
| 
      
 99 
     | 
    
         
            +
                def settings(owner = nil)
         
     | 
| 
      
 100 
     | 
    
         
            +
                  if owner
         
     | 
| 
      
 101 
     | 
    
         
            +
                    @@owners[owner]
         
     | 
| 
      
 102 
     | 
    
         
            +
                  else
         
     | 
| 
      
 103 
     | 
    
         
            +
                    @@owners.values.inject([]) { |memo, obj| memo.concat(obj.values) }
         
     | 
| 
      
 104 
     | 
    
         
            +
                  end
         
     | 
| 
      
 105 
     | 
    
         
            +
                end
         
     | 
| 
      
 106 
     | 
    
         
            +
                alias_method :all, :settings
         
     | 
| 
      
 107 
     | 
    
         
            +
                alias_method :[], :settings
         
     | 
| 
       90 
108 
     | 
    
         | 
| 
       91 
     | 
    
         
            -
             
     | 
| 
       92 
     | 
    
         
            -
             
     | 
| 
       93 
     | 
    
         
            -
             
     | 
| 
       94 
     | 
    
         
            -
             
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
       96 
     | 
    
         
            -
             
     | 
| 
       97 
     | 
    
         
            -
             
     | 
| 
      
 109 
     | 
    
         
            +
                def method_missing(sym)
         
     | 
| 
      
 110 
     | 
    
         
            +
                  if sym.to_s =~ /[A-Z]/ # facet's capitalized? is buggy at the moment.
         
     | 
| 
      
 111 
     | 
    
         
            +
                    Flexob.new(self[constant(sym)])
         
     | 
| 
      
 112 
     | 
    
         
            +
                  end
         
     | 
| 
      
 113 
     | 
    
         
            +
                end
         
     | 
| 
      
 114 
     | 
    
         
            +
              end
         
     | 
| 
      
 115 
     | 
    
         
            +
              
         
     | 
| 
       98 
116 
     | 
    
         
             
            end
         
     | 
| 
       99 
117 
     | 
    
         | 
| 
       100 
118 
     | 
    
         
             
            # Alias for the Configuration class (shorter).
         
     | 
| 
         @@ -104,23 +122,23 @@ end 
     | 
|
| 
       104 
122 
     | 
    
         | 
| 
       105 
123 
     | 
    
         
             
            class Module
         
     | 
| 
       106 
124 
     | 
    
         | 
| 
       107 
     | 
    
         
            -
             
     | 
| 
       108 
     | 
    
         
            -
             
     | 
| 
       109 
     | 
    
         
            -
             
     | 
| 
       110 
     | 
    
         
            -
             
     | 
| 
       111 
     | 
    
         
            -
             
     | 
| 
       112 
     | 
    
         
            -
             
     | 
| 
       113 
     | 
    
         
            -
             
     | 
| 
       114 
     | 
    
         
            -
             
     | 
| 
       115 
     | 
    
         
            -
             
     | 
| 
       116 
     | 
    
         
            -
             
     | 
| 
      
 125 
     | 
    
         
            +
              # Defines a configuration setting.
         
     | 
| 
      
 126 
     | 
    
         
            +
              #--
         
     | 
| 
      
 127 
     | 
    
         
            +
              # TODO: implement with annotations.
         
     | 
| 
      
 128 
     | 
    
         
            +
              #++
         
     | 
| 
      
 129 
     | 
    
         
            +
              
         
     | 
| 
      
 130 
     | 
    
         
            +
              def setting(sym, options = {})
         
     | 
| 
      
 131 
     | 
    
         
            +
                Configuration.add_setting(self, sym, options)
         
     | 
| 
      
 132 
     | 
    
         
            +
                module_eval %{
         
     | 
| 
      
 133 
     | 
    
         
            +
                  mattr_accessor sym, options[:default]
         
     | 
| 
      
 134 
     | 
    
         
            +
                  
         
     | 
| 
       117 
135 
     | 
    
         
             
                  def self.#{sym.id2name}=(obj)
         
     | 
| 
       118 
136 
     | 
    
         
             
                    @@#{sym.id2name} = obj
         
     | 
| 
       119 
137 
     | 
    
         
             
                    Configuration[#{self}][:#{sym}].value = obj
         
     | 
| 
       120 
138 
     | 
    
         
             
                  end
         
     | 
| 
       121 
     | 
    
         
            -
             
     | 
| 
       122 
     | 
    
         
            -
             
     | 
| 
       123 
     | 
    
         
            -
             
     | 
| 
      
 139 
     | 
    
         
            +
                }
         
     | 
| 
      
 140 
     | 
    
         
            +
              end
         
     | 
| 
      
 141 
     | 
    
         
            +
              
         
     | 
| 
       124 
142 
     | 
    
         
             
            end
         
     | 
| 
       125 
143 
     | 
    
         | 
| 
       126 
     | 
    
         
            -
            # * George Moschovitis <gm@navel.gr> 
     | 
| 
      
 144 
     | 
    
         
            +
            # * George Moschovitis <gm@navel.gr>   
         
     |