1 package org.apache.commons.jcs3.engine.control;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.util.ArrayList;
23 import java.util.List;
24 import java.util.Properties;
25
26 import org.apache.commons.jcs3.auxiliary.AuxiliaryCache;
27 import org.apache.commons.jcs3.auxiliary.AuxiliaryCacheAttributes;
28 import org.apache.commons.jcs3.auxiliary.AuxiliaryCacheConfigurator;
29 import org.apache.commons.jcs3.auxiliary.AuxiliaryCacheFactory;
30 import org.apache.commons.jcs3.engine.behavior.ICache;
31 import org.apache.commons.jcs3.engine.behavior.ICompositeCacheAttributes;
32 import org.apache.commons.jcs3.engine.behavior.IElementAttributes;
33 import org.apache.commons.jcs3.engine.behavior.IElementSerializer;
34 import org.apache.commons.jcs3.engine.behavior.IRequireScheduler;
35 import org.apache.commons.jcs3.engine.logging.behavior.ICacheEventLogger;
36 import org.apache.commons.jcs3.engine.match.KeyMatcherPatternImpl;
37 import org.apache.commons.jcs3.engine.match.behavior.IKeyMatcher;
38 import org.apache.commons.jcs3.log.Log;
39 import org.apache.commons.jcs3.log.LogManager;
40 import org.apache.commons.jcs3.utils.config.OptionConverter;
41 import org.apache.commons.jcs3.utils.config.PropertySetter;
42
43
44
45
46
47
48
49
50 public class CompositeCacheConfigurator
51 {
52
53 private static final Log log = LogManager.getLog( CompositeCacheConfigurator.class );
54
55
56 protected static final String SYSTEM_PROPERTY_KEY_PREFIX = "jcs";
57
58
59 protected static final String REGION_PREFIX = "jcs.region.";
60
61
62 protected static final String SYSTEM_REGION_PREFIX = "jcs.system.";
63
64
65 protected static final String AUXILIARY_PREFIX = "jcs.auxiliary.";
66
67
68 protected static final String ATTRIBUTE_PREFIX = ".attributes";
69
70
71 protected static final String CACHE_ATTRIBUTE_PREFIX = ".cacheattributes";
72
73
74 protected static final String ELEMENT_ATTRIBUTE_PREFIX = ".elementattributes";
75
76
77
78
79
80
81 public static final String KEY_MATCHER_PREFIX = ".keymatcher";
82
83
84
85
86 public CompositeCacheConfigurator()
87 {
88
89 }
90
91
92
93
94
95
96
97 protected void parseSystemRegions( final Properties props, final CompositeCacheManager ccm )
98 {
99 for (final String key : props.stringPropertyNames() )
100 {
101 if ( key.startsWith( SYSTEM_REGION_PREFIX ) && key.indexOf( "attributes" ) == -1 )
102 {
103 final String regionName = key.substring( SYSTEM_REGION_PREFIX.length() );
104 final String auxiliaries = OptionConverter.findAndSubst( key, props );
105 final ICache<?, ?> cache;
106 synchronized ( regionName )
107 {
108 cache = parseRegion( props, ccm, regionName, auxiliaries, null, SYSTEM_REGION_PREFIX );
109 }
110 ccm.addCache( regionName, cache );
111 }
112 }
113 }
114
115
116
117
118
119
120
121 protected void parseRegions( final Properties props, final CompositeCacheManager ccm )
122 {
123 final List<String> regionNames = new ArrayList<>();
124
125 for (final String key : props.stringPropertyNames() )
126 {
127 if ( key.startsWith( REGION_PREFIX ) && key.indexOf( "attributes" ) == -1 )
128 {
129 final String regionName = key.substring( REGION_PREFIX.length() );
130 regionNames.add( regionName );
131 final String auxiliaries = OptionConverter.findAndSubst( key, props );
132 final ICache<?, ?> cache;
133 synchronized ( regionName )
134 {
135 cache = parseRegion( props, ccm, regionName, auxiliaries );
136 }
137 ccm.addCache( regionName, cache );
138 }
139 }
140
141 log.info( "Parsed regions {0}", regionNames );
142 }
143
144
145
146
147
148
149
150
151
152
153
154 protected <K, V> CompositeCache<K, V> parseRegion(
155 final Properties props, final CompositeCacheManager ccm, final String regName, final String auxiliaries )
156 {
157 return parseRegion( props, ccm, regName, auxiliaries, null, REGION_PREFIX );
158 }
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173 protected <K, V> CompositeCache<K, V> parseRegion(
174 final Properties props, final CompositeCacheManager ccm, final String regName, final String auxiliaries,
175 final ICompositeCacheAttributes cca )
176 {
177 return parseRegion( props, ccm, regName, auxiliaries, cca, REGION_PREFIX );
178 }
179
180
181
182
183
184
185
186
187
188
189
190
191
192 protected <K, V> CompositeCache<K, V> parseRegion(
193 final Properties props, final CompositeCacheManager ccm, final String regName, final String auxiliaries,
194 final ICompositeCacheAttributes cca, final String regionPrefix )
195 {
196
197
198 final IElementAttributes ea = parseElementAttributes( props, regName,
199 ccm.getDefaultElementAttributes(), regionPrefix );
200
201 final ICompositeCacheAttributes instantiationCca = cca == null
202 ? parseCompositeCacheAttributes(props, regName, ccm.getDefaultCacheAttributes(), regionPrefix)
203 : cca;
204 final CompositeCache<K, V> cache = newCache(instantiationCca, ea);
205
206
207 cache.setCompositeCacheManager(ccm);
208
209
210 cache.setScheduledExecutorService(ccm.getScheduledExecutorService());
211
212
213 cache.setElementEventQueue(ccm.getElementEventQueue());
214
215 if (auxiliaries != null)
216 {
217
218 final List<AuxiliaryCache<K, V>> auxList = new ArrayList<>();
219
220 log.debug( "Parsing region name \"{0}\", value \"{1}\"", regName, auxiliaries );
221
222 String auxNames[] = auxiliaries.split("\\s*,\\s*");
223
224
225 if (auxNames.length == 0)
226 {
227 return null;
228 }
229
230 for (String auxName : auxNames)
231 {
232 if (auxName.isEmpty())
233 {
234 log.warn( "Skipping empty auxiliary name" );
235 continue;
236 }
237
238 log.debug( "Parsing auxiliary named \"{0}\".", auxName );
239
240 AuxiliaryCache<K, V> auxCache = parseAuxiliary( props, ccm, auxName, regName );
241
242 if ( auxCache != null )
243 {
244 if (auxCache instanceof IRequireScheduler)
245 {
246 ((IRequireScheduler) auxCache).setScheduledExecutorService(
247 ccm.getScheduledExecutorService());
248 }
249
250 auxList.add( auxCache );
251 }
252 }
253
254
255 cache.setAuxCaches(auxList);
256 }
257
258
259 return cache;
260 }
261
262 protected <K, V> CompositeCache<K, V> newCache(
263 final ICompositeCacheAttributes cca, final IElementAttributes ea)
264 {
265 return new CompositeCache<>( cca, ea );
266 }
267
268
269
270
271
272
273
274
275
276
277 protected ICompositeCacheAttributes parseCompositeCacheAttributes( final Properties props,
278 final String regName, final ICompositeCacheAttributes defaultCCAttr )
279 {
280 return parseCompositeCacheAttributes( props, regName, defaultCCAttr, REGION_PREFIX );
281 }
282
283
284
285
286
287
288
289
290
291
292
293 protected ICompositeCacheAttributes parseCompositeCacheAttributes( final Properties props,
294 final String regName, final ICompositeCacheAttributes defaultCCAttr, final String regionPrefix )
295 {
296 ICompositeCacheAttributes ccAttr;
297
298 final String attrName = regionPrefix + regName + CACHE_ATTRIBUTE_PREFIX;
299
300
301
302 ccAttr = OptionConverter.instantiateByKey( props, attrName, null );
303
304 if ( ccAttr == null )
305 {
306 log.info( "No special CompositeCacheAttributes class defined for "
307 + "key [{0}], using default class.", attrName );
308
309 ccAttr = defaultCCAttr;
310 }
311
312 log.debug( "Parsing options for \"{0}\"", attrName );
313
314 PropertySetter.setProperties( ccAttr, props, attrName + "." );
315 ccAttr.setCacheName( regName );
316
317 log.debug( "End of parsing for \"{0}\"", attrName );
318
319
320 ccAttr.setCacheName( regName );
321 return ccAttr;
322 }
323
324
325
326
327
328
329
330
331
332
333
334 protected IElementAttributes parseElementAttributes( final Properties props, final String regName,
335 final IElementAttributes defaultEAttr, final String regionPrefix )
336 {
337 IElementAttributes eAttr;
338
339 final String attrName = regionPrefix + regName + CompositeCacheConfigurator.ELEMENT_ATTRIBUTE_PREFIX;
340
341
342
343 eAttr = OptionConverter.instantiateByKey( props, attrName, null );
344 if ( eAttr == null )
345 {
346 log.info( "No special ElementAttribute class defined for key [{0}], "
347 + "using default class.", attrName );
348
349 eAttr = defaultEAttr;
350 }
351
352 log.debug( "Parsing options for \"{0}\"", attrName );
353
354 PropertySetter.setProperties( eAttr, props, attrName + "." );
355
356
357 log.debug( "End of parsing for \"{0}\"", attrName );
358
359
360
361 return eAttr;
362 }
363
364
365
366
367
368
369
370
371
372
373 protected <K, V> AuxiliaryCache<K, V> parseAuxiliary( final Properties props, final CompositeCacheManager ccm,
374 final String auxName, final String regName )
375 {
376 log.debug( "parseAuxiliary {0}", auxName );
377
378
379 AuxiliaryCache<K, V> auxCache = ccm.getAuxiliaryCache(auxName, regName);
380
381 if (auxCache == null)
382 {
383
384 AuxiliaryCacheFactory auxFac = ccm.registryFacGet( auxName );
385 if ( auxFac == null )
386 {
387
388 final String prefix = AUXILIARY_PREFIX + auxName;
389 auxFac = OptionConverter.instantiateByKey( props, prefix, null );
390 if ( auxFac == null )
391 {
392 log.error( "Could not instantiate auxFactory named \"{0}\"", auxName );
393 return null;
394 }
395
396 auxFac.setName( auxName );
397
398 if ( auxFac instanceof IRequireScheduler)
399 {
400 ((IRequireScheduler)auxFac).setScheduledExecutorService(ccm.getScheduledExecutorService());
401 }
402
403 auxFac.initialize();
404 ccm.registryFacPut( auxFac );
405 }
406
407
408 AuxiliaryCacheAttributes auxAttr = ccm.registryAttrGet( auxName );
409 final String attrName = AUXILIARY_PREFIX + auxName + ATTRIBUTE_PREFIX;
410 if ( auxAttr == null )
411 {
412
413 final String prefix = AUXILIARY_PREFIX + auxName + ATTRIBUTE_PREFIX;
414 auxAttr = OptionConverter.instantiateByKey( props, prefix, null );
415 if ( auxAttr == null )
416 {
417 log.error( "Could not instantiate auxAttr named \"{0}\"", attrName );
418 return null;
419 }
420 auxAttr.setName( auxName );
421 ccm.registryAttrPut( auxAttr );
422 }
423
424 auxAttr = auxAttr.clone();
425
426 log.debug( "Parsing options for \"{0}\"", attrName );
427
428 PropertySetter.setProperties( auxAttr, props, attrName + "." );
429 auxAttr.setCacheName( regName );
430
431 log.debug( "End of parsing for \"{0}\"", attrName );
432
433
434 auxAttr.setCacheName( regName );
435
436 final String auxPrefix = AUXILIARY_PREFIX + auxName;
437
438
439 final ICacheEventLogger cacheEventLogger =
440 AuxiliaryCacheConfigurator.parseCacheEventLogger( props, auxPrefix );
441
442
443 final IElementSerializer elementSerializer =
444 AuxiliaryCacheConfigurator.parseElementSerializer( props, auxPrefix );
445
446
447
448
449
450
451
452
453
454 try
455 {
456 auxCache = auxFac.createCache( auxAttr, ccm, cacheEventLogger, elementSerializer );
457 }
458 catch (final Exception e)
459 {
460 log.error( "Could not instantiate auxiliary cache named \"{0}\"", regName, e );
461 return null;
462 }
463
464 ccm.addAuxiliaryCache(auxName, regName, auxCache);
465 }
466
467 return auxCache;
468 }
469
470
471
472
473
474
475 protected static void overrideWithSystemProperties( final Properties props )
476 {
477
478 final Properties sysProps = System.getProperties();
479 for (final String key : sysProps.stringPropertyNames())
480 {
481 if ( key.startsWith( SYSTEM_PROPERTY_KEY_PREFIX ) )
482 {
483 log.info( "Using system property [[{0}] [{1}]]", () -> key,
484 () -> sysProps.getProperty( key ) );
485 props.setProperty( key, sysProps.getProperty( key ) );
486 }
487 }
488 }
489
490
491
492
493
494
495
496
497 protected <K> IKeyMatcher<K> parseKeyMatcher( final Properties props, final String auxPrefix )
498 {
499
500
501 final String keyMatcherClassName = auxPrefix + KEY_MATCHER_PREFIX;
502 IKeyMatcher<K> keyMatcher = OptionConverter.instantiateByKey( props, keyMatcherClassName, null );
503 if ( keyMatcher != null )
504 {
505 final String attributePrefix = auxPrefix + KEY_MATCHER_PREFIX + ATTRIBUTE_PREFIX;
506 PropertySetter.setProperties( keyMatcher, props, attributePrefix + "." );
507 log.info( "Using custom key matcher [{0}] for auxiliary [{1}]", keyMatcher, auxPrefix );
508 }
509 else
510 {
511
512 keyMatcher = new KeyMatcherPatternImpl<>();
513 log.info( "Using standard key matcher [{0}] for auxiliary [{1}]", keyMatcher, auxPrefix );
514 }
515 return keyMatcher;
516 }
517 }