jruby-ehcache 0.5.0 → 1.0.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.
@@ -1,128 +1,51 @@
1
- require 'erb'
2
- require 'yaml'
3
-
4
- module Ehcache
5
-
6
- class MissingConfigurationException < StandardError
7
- def initialize(search_dirs)
8
- super("Could not find Ehcache configuration file in any of: #{search_dirs.inspect}")
1
+ require 'ehcache/yaml_config'
2
+
3
+ # Enhance net.sf.ehcache.config.Configuration with a more Rubyesque API, and
4
+ # add support for using YAML for configuration.
5
+ class Java::NetSfEhcacheConfig::Configuration
6
+ Factory = Java::NetSfEhcacheConfig::ConfigurationFactory
7
+
8
+ # Searches for an Ehcache configuration file and, if found, returns a
9
+ # Configuration object created from it. The search algorithm looks for
10
+ # files named "ehcache.yml" or "ehcache.xml", first looking in the provided
11
+ # directories in order, and if not found there then looking in the Ruby
12
+ # $LOAD_PATH.
13
+ # Returns nil if no configuration file is found.
14
+ def self.find(*dirs)
15
+ file_names = %w[ehcache.yml ehcache.xml]
16
+ dirs += $LOAD_PATH
17
+ dirs.each do |dir|
18
+ file_names.each do |name|
19
+ candidate = File.join(dir, name)
20
+ return create(candidate) if File.exist?(candidate)
21
+ end
9
22
  end
23
+ nil
10
24
  end
11
25
 
12
- # default configuration and a cache named "cache"
13
- # manager = Ehcache::CacheManager.new
14
- # cache = manager.cache
15
- #
16
- # default configuration and a cache named "steve"
17
- # manager = Ehcache::CacheManager.new({"cache" => {"name" => "steve"}})
18
- # cache = manager.cache("steve")
19
- class Config
20
- CONFIG_FILE_NAME = 'ehcache.yml'
21
-
22
- RAILS_CONFIG_DIR =
23
- if defined?(::Rails)
24
- File.join(::Rails.root.to_s, 'config')
25
- elsif defined?(RAILS_ROOT)
26
- File.join(RAILS_ROOT, 'config')
27
- end
28
-
29
- SEARCH_DIRS = [RAILS_CONFIG_DIR,
30
- File.join(ENV['HOME'], 'lib', 'config'),
31
- File.join(EHCACHE_HOME, 'config')].compact
32
-
33
- class << self
34
- def generate(options={})
35
- unless config_file = find_config_file
36
- raise MissingConfigurationException.new(SEARCH_DIRS)
26
+ def self.create(*args)
27
+ result = nil
28
+ case args.size
29
+ when 0
30
+ result = Factory.parseConfiguration()
31
+ when 1
32
+ arg = args.first
33
+
34
+ if arg.is_a?(String)
35
+ raise ArgumentError, "Cannot read config file '#{arg}'" unless File.readable?(arg)
36
+ if arg =~ /\.yml$/
37
+ result = Ehcache::Config::YamlConfig.parse_yaml_config(arg)
38
+ else
39
+ result = Factory.parseConfiguration(java.io.File.new(arg))
37
40
  end
38
- config = ERB.new(File.open(config_file) {|f| f.read})
39
- config = YAML.load(config.result(binding))
40
- initialize_factory_proxies
41
- process(config, options)
42
- end
43
-
44
- private
45
-
46
- def find_config_file
47
- SEARCH_DIRS.map {|dir| File.join(dir, CONFIG_FILE_NAME)}.find { |f|
48
- File.readable?(f)
49
- }
50
- end
51
-
52
- def process(config, options)
53
- # merge in new defaults if any
54
- config["default"].deep_merge!(options["default"]) if options["default"]
55
-
56
- # primary cache should be based off of default cache
57
- config["cache"] = config["default"].merge({"name" => Ehcache::Cache::PRIMARY})
58
-
59
- # update the rest of the configuration
60
- config.deep_merge!(options) if options
61
- config.each { |key, value| setter(key, value) }
62
-
63
- # add default cache and primary cache if present
64
- create_default_cache(config["default"])
65
- create_primary_cache(config["cache"]) if config["cache"]
66
-
67
- # populate the configuration
68
- @configuration.add_disk_store(@disk)
69
- @configuration.add_cache_manager_peer_provider_factory(@peer_provider)
70
- @configuration.add_cache_manager_peer_listener_factory(@peer_listener)
71
- @configuration
72
- end
73
-
74
- # creates and installs default cache
75
- def create_default_cache(default)
76
- default_cache_config = create_cache_configuration("default", default)
77
- @configuration.add_default_cache(default_cache_config)
78
- end
79
-
80
- # creates and installs primary cache
81
- def create_primary_cache(primary)
82
- primary_cache_config = create_cache_configuration("cache", primary)
83
- @configuration.add_cache(primary_cache_config)
84
- end
85
-
86
- # creates and sets up cache configurations
87
- def create_cache_configuration(cache_name, data)
88
- config = instance_variable_get("@#{cache_name}".intern)
89
- data.each { |k,v|
90
- # included hashes will be event listener factories, exception handler
91
- # factories, loader factories, etc. TODO: clean this up, and add
92
- # support for adding other factories in a cleaner fashion.
93
- if v.is_a?(Hash)
94
- case k
95
- when "event_listener":
96
- event_factory = Ehcache::Java::CacheConfiguration::CacheEventListenerFactoryConfiguration.new(config)
97
- v.each { |k,v| event_factory.send("set_#{k.to_s}",v) }
98
- config.add_cache_event_listener_factory(event_factory)
99
- when "bootstrap_loader":
100
- bootstrap_loader = Ehcache::Java::CacheConfiguration::BootstrapCacheLoaderFactoryConfiguration.new(config)
101
- v.each { |k,v| bootstrap_loader.send("set_#{k.to_s}",v) }
102
- config.add_bootstrap_cache_loader_factory(bootstrap_loader)
103
- end
104
- else
105
- config.send("set_#{k.to_s}",v)
106
- end
107
- }
108
- config
109
- end
110
-
111
- # initialize all the java factory proxies for configuration
112
- def initialize_factory_proxies
113
- @configuration = Ehcache::Java::Configuration.new
114
- @disk = Ehcache::Java::DiskStoreConfiguration.new
115
- @cache = Ehcache::Java::CacheConfiguration.new
116
- @default = Ehcache::Java::CacheConfiguration.new
117
- @peer_provider = Ehcache::Java::FactoryConfiguration.new
118
- @peer_listener = Ehcache::Java::FactoryConfiguration.new
41
+ else
42
+ result = Factory.parseConfiguration(arg)
119
43
  end
44
+ end
120
45
 
121
- # helper for setters
122
- def setter(factory, config)
123
- factory = instance_variable_get("@#{factory}".intern)
124
- config.each { |k,v| factory.send("set_#{k.to_s}",v) unless v.is_a?(Hash) }
125
- end
46
+ unless result.is_a?(self)
47
+ raise ArgumentError, "Could not create Configuration from: #{args.inspect}"
126
48
  end
49
+ result
127
50
  end
128
51
  end
@@ -1,27 +1,17 @@
1
- module Ehcache
2
- class Element
3
- attr_accessor :key, :value
4
-
5
- def initialize(key, value, options = {})
6
- @key = key
7
- @value = value
8
- @ttl = options[:ttl] || nil
9
-
10
- element = Ehcache::Java::Element.new(key, value)
11
- element.set_time_to_live(@ttl) if @ttl
12
- @proxy = element
13
- end
14
-
15
- def ttl
16
- @ttl = @proxy.get_time_to_live
1
+ # Enhance net.sf.ehcache.Element with a more Rubyesque API.
2
+ class Java::NetSfEhcache::Element
3
+ def self.create(key, value, options = {})
4
+ result = self.new(key, value)
5
+ options.each do |key, value|
6
+ setter = "#{key}=".to_sym
7
+ result.send(setter, value) if result.respond_to?(setter)
17
8
  end
9
+ result
10
+ end
18
11
 
19
- def tti
20
- @tti = @proxy.get_time_to_idle
21
- end
12
+ alias tti getTimeToIdle
13
+ alias ttl getTimeToLive
22
14
 
23
- def proxy
24
- @proxy
25
- end
26
- end
15
+ alias tti= setTimeToIdle
16
+ alias ttl= setTimeToLive
27
17
  end
@@ -1,3 +1,6 @@
1
+ require 'active_support/core_ext/string/inflections'
2
+ require 'active_support/core_ext/array/extract_options'
3
+
1
4
  class Hash
2
5
  # Merges self with another hash, recursively.
3
6
  # This code was lovingly stolen from some random gem:
data/lib/ehcache/java.rb CHANGED
@@ -1,8 +1,38 @@
1
+ require 'java'
2
+
3
+ EHCACHE_LIBS_DIR = "#{Ehcache::EHCACHE_HOME}/ext"
4
+
1
5
  module Ehcache
2
- module Java
3
- include ::Java
4
- Dir["#{Ehcache::EHCACHE_HOME}/ext/**/*.jar"].sort.each {|l| require l}
5
- include_package "net.sf.ehcache"
6
- include_package "net.sf.ehcache.config"
6
+ slf4j_loader = lambda { Java::OrgSlf4j::LoggerFactory.getLogger("JRubyEhcache") }
7
+ begin
8
+ LOG = slf4j_loader.call
9
+ LOG.info("Using SLF4J Logger from CLASSPATH")
10
+ rescue NameError
11
+ Dir["#{EHCACHE_LIBS_DIR}/**/*slf4j*.jar"].each do |l| require l end
12
+ LOG = slf4j_loader.call
13
+ LOG.info("Using bundled SLF4J Logger")
7
14
  end
15
+
16
+ ehcache_version_loader = lambda {
17
+ Java::NetSfEhcacheUtil::ProductInfo.new.getVersion()
18
+ }
19
+ begin
20
+ # If Ehcache is already on the classpath, use it.
21
+ VERSION = ehcache_version_loader.call
22
+ LOG.info("Using Ehcache #{VERSION} from CLASSPATH")
23
+ rescue NameError
24
+ # If not, use the Ehcache bundled with the jruby-ehcache gem.
25
+ Dir["#{EHCACHE_LIBS_DIR}/**/*.jar"].each do |l|
26
+ require l unless l =~ /slf4j/
27
+ end
28
+ VERSION = ehcache_version_loader.call
29
+ LOG.info("Using bundled Ehcache #{VERSION}")
30
+ end
31
+
32
+ include_package 'net.sf.ehcache'
33
+
34
+ module Config
35
+ include_package 'net.sf.ehcache.config'
36
+ end
37
+
8
38
  end
@@ -0,0 +1,251 @@
1
+ require 'java'
2
+ require 'ehcache'
3
+ require 'yaml'
4
+ require 'erb'
5
+
6
+ module Ehcache::Config
7
+ # Support for using YAML for Ehcache configuration.
8
+ #
9
+ # <strong>DEPRECATED:</strong> Please use ehcache.xml instead.
10
+ #
11
+ # YAML configuration is similar to XML configuration, but there are some
12
+ # changes to the names of configuration elements to make them simpler or
13
+ # more idiomatic to Ruby and YAML conventions. The changes are described
14
+ # below. For full documentation on the Ehcache configuration elements,
15
+ # see the Ehcache Cache Configuration documentation:
16
+ # http://ehcache.org/documentation/configuration.html
17
+ #
18
+ # The top level YAML configuration attributes and the corresponding XML
19
+ # elements or attributes are shown in the following table.
20
+ #
21
+ # name:: name attribute on ehcache element
22
+ # update_check:: updateCheck attribute on ehcache element
23
+ # monitoring:: monitoring attribute on ehcache element
24
+ # dynamic_config:: dynamicConfig attribute on ehcache element
25
+ # disk_store:: diskStore element
26
+ # transaction_manager:: transactionManagerLookup element
27
+ # event_listener:: cacheManagerEventListenerFactory element
28
+ # peer_providers (Array):: cacheManagerPeerProviderFactory elements
29
+ # peer_listeners (Array):: cacheManagerPeerListenerFactory elements
30
+ # terracotta_config:: terracottaConfig element
31
+ # default_cache:: defaultCache element
32
+ # caches (Array):: cache elements
33
+ #
34
+ # Each top level configuration attribute contains a set of key/value pairs
35
+ # that are equivalent to the Ehcache XML attributes, except that the
36
+ # attribute names are converted to use underscore_names instead of
37
+ # camelCaseNames. For instance, the Ehcache XML attribute
38
+ # diskSpoolBufferSizeMB becomes disk_spool_buffer_size_mb in YAML.
39
+ #
40
+ # Entries in the above table that are marked as (Array) should be YAML lists
41
+ # to allow for multiple values. So, for example, to configure multiple
42
+ # caches in your YAML configuration, use the following syntax:
43
+ #
44
+ # caches:
45
+ # - name: my_cache
46
+ # time_to_idle_seconds: 360
47
+ # time_to_live_seconds: 1000
48
+ # - name: my_other_cache
49
+ # max_elements_in_memory: 1000
50
+ # eternal: true
51
+ # overflow_to_disk: false
52
+ # disk_persistent: true
53
+ #
54
+ # Note the use of the '-' to separate list elements.
55
+ #
56
+ # One further difference between YAML configuration and XML configuration
57
+ # deals with cache configuration. The XML configuration allows for a set
58
+ # of XML sub elements to configure various aspects of caches (or the default
59
+ # cache). In YAML, these sub elements are translated to attributes within
60
+ # the cache configuration (or default_cache configuration) that
61
+ # refer to Hashes or Arrays. The following table shows the mapping.
62
+ #
63
+ # event_listeners (Array):: cacheEventListenerFactory sub elements
64
+ # extensions (Array):: cacheExtensionFactory sub elements
65
+ # loaders (Array):: cacheLoaderFactory sub elements
66
+ # decorators (Array):: cacheDecoratorFactory sub elements
67
+ # bootstrap_loader (Hash):: bootstrapCacheLoaderFactory sub element
68
+ # exception_handler (Hash):: cacheExceptionHandlerFactory sub element
69
+ # terracotta (Hash):: terracotta sub element
70
+ # cache_writer (Hash):: cacheWriter sub element
71
+ # copy_strategy (Hash):: copyStrategy sub element
72
+ #
73
+ # Those marked as (Array) may take a list of values, while those marked as
74
+ # (Hash) may take a single Hash value (set of key/value pairs). Here is an
75
+ # example of a cache configuration that uses one of each style:
76
+ #
77
+ # caches:
78
+ # - name: some_cache
79
+ # time_to_live_seconds: 100
80
+ # event_listeners:
81
+ # - class: net.sf.ehcache.distribution.RMICacheReplicatorFactory
82
+ # properties: "replicateAsynchronously=false"
83
+ # copy_strategy:
84
+ # class: net.sf.ehcache.store.compound.SerializationCopyStrategy
85
+ #
86
+ # Note again the use of the '-' character to separate list elements in the
87
+ # case of Array values, which is not present for Hash values.
88
+ module YamlConfig
89
+
90
+ InvalidYamlConfiguration = Class.new(StandardError)
91
+
92
+ # Not sure why, but "include Java::NetSfEhcacheConfig" does not work,
93
+ # so define local constants referring to the Ehcache classes
94
+ Configuration = Java::NetSfEhcacheConfig::Configuration
95
+ CacheConfiguration = Java::NetSfEhcacheConfig::CacheConfiguration
96
+ DiskStoreConfiguration = Java::NetSfEhcacheConfig::DiskStoreConfiguration
97
+ FactoryConfiguration = Java::NetSfEhcacheConfig::FactoryConfiguration
98
+
99
+ %w[name update_check monitoring dynamic_config
100
+ disk_store transaction_manager event_listener
101
+ peer_providers peer_listeners
102
+ terracotta_config default_cache caches
103
+ event_listeners extensions loaders decorators
104
+ ].each do |attribute|
105
+ const_set(attribute.upcase.to_sym, attribute)
106
+ end
107
+
108
+ # Parses the given yaml_config_file and returns a corresponding
109
+ # Ehcache::Config::Configuration object.
110
+ def self.parse_yaml_config(yaml_config_file)
111
+ Ehcache::LOG.warn("YAML configuration is deprecated. Please use ehcache.xml instead.")
112
+ YamlConfigBuilder.new(yaml_config_file).build
113
+ end
114
+
115
+ private
116
+
117
+ class YamlConfigBuilder
118
+
119
+ def initialize(yaml_file)
120
+ @yaml_file = yaml_file
121
+ @data = YAML.load(ERB.new(File.read(yaml_file)).result(binding))
122
+ raise InvalidYamlConfiguration unless valid?(@data)
123
+ end
124
+
125
+ def build
126
+ @config = Configuration.new
127
+ for attribute in [NAME, UPDATE_CHECK, MONITORING, DYNAMIC_CONFIG]
128
+ set_if_present(attribute)
129
+ end
130
+ set_disk_store
131
+ set_transaction_manager
132
+ set_event_listener
133
+ add_peer_providers
134
+ add_peer_listeners
135
+ set_default_cache
136
+ add_caches
137
+ @config
138
+ end
139
+
140
+ private
141
+
142
+ def valid?(data)
143
+ data.is_a?(Hash)
144
+ end
145
+
146
+ def set_if_present(key)
147
+ if @data.has_key?(key)
148
+ setter = "#{key}=".to_sym
149
+ @config.send(setter, @data[key])
150
+ end
151
+ end
152
+
153
+ def set_attributes(object, attributes)
154
+ attributes ||= []
155
+ attributes.each do |key, value|
156
+ if value.is_a?(Hash) || value.is_a?(Array)
157
+ create_cache_config_factories(object, key, value)
158
+ else
159
+ object.send("#{key}=", value)
160
+ end
161
+ end
162
+ object
163
+ end
164
+
165
+ def create_cache_config_factories(cache, key, value)
166
+ [value].flatten.each do |data|
167
+ create_cache_config_factory(cache, key, data)
168
+ end
169
+ end
170
+
171
+ def names_for_factory(key)
172
+ singular = key.singularize.sub(/s$/, '')
173
+ factory_name = if key == 'bootstrap_loader'
174
+ "BootstrapCacheLoaderFactory"
175
+ else
176
+ "Cache#{singular.camelize}Factory"
177
+ end
178
+ class_name = "#{factory_name}Configuration"
179
+ method_name = "add#{factory_name}"
180
+ return [class_name, method_name]
181
+ end
182
+
183
+ def create_cache_config_factory(cache, key, data)
184
+ class_name, method_name = names_for_factory(key)
185
+ factory_class = CacheConfiguration.const_get(class_name)
186
+ factory = factory_class.new
187
+
188
+ cache.send(method_name, factory)
189
+ set_attributes(factory, data)
190
+ end
191
+
192
+ def apply_config(key, config_class)
193
+ if @data[key]
194
+ [@data[key]].flatten.each do |data|
195
+ config = config_class.new
196
+ set_attributes(config, data)
197
+ yield config
198
+ end
199
+ end
200
+ end
201
+
202
+ def set_disk_store
203
+ apply_config(DISK_STORE, DiskStoreConfiguration) do |disk_store|
204
+ @config.add_disk_store(disk_store)
205
+ end
206
+ end
207
+
208
+ def set_transaction_manager
209
+ apply_config(TRANSACTION_MANAGER, FactoryConfiguration) do |tx_mgr|
210
+ @config.add_transaction_manager_lookup(tx_mgr)
211
+ end
212
+ end
213
+
214
+ def set_event_listener
215
+ apply_config(EVENT_LISTENER, FactoryConfiguration) do |event_listener|
216
+ @config.addCacheManagerEventListenerFactory(event_listener)
217
+ end
218
+ end
219
+
220
+ def add_peer_providers
221
+ apply_config(PEER_PROVIDERS, FactoryConfiguration) do |peer_provider|
222
+ @config.addCacheManagerPeerProviderFactory(peer_provider)
223
+ end
224
+ end
225
+
226
+ def add_peer_listeners
227
+ apply_config(PEER_LISTENERS, FactoryConfiguration) do |peer_listener|
228
+ @config.addCacheManagerPeerListenerFactory(peer_listener)
229
+ end
230
+ end
231
+
232
+ def set_default_cache
233
+ apply_config(DEFAULT_CACHE, CacheConfiguration) do |cache_config|
234
+ @config.default_cache_configuration = cache_config
235
+ end
236
+ end
237
+
238
+ def add_caches
239
+ apply_config(CACHES, CacheConfiguration) do |cache_config|
240
+ @config.add_cache(cache_config)
241
+ end
242
+ end
243
+
244
+ def create_factory_configuration(data)
245
+ result = FactoryConfiguration.new
246
+ set_attributes(result, data)
247
+ result
248
+ end
249
+ end
250
+ end
251
+ end