1 /***
2 * Copyright 2003-2010 Terracotta, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package net.sf.ehcache.config;
18
19 import net.sf.ehcache.ObjectExistsException;
20 import net.sf.ehcache.config.generator.ConfigurationSource;
21 import net.sf.ehcache.transaction.manager.DefaultTransactionManagerLookup;
22
23 import java.util.ArrayList;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Set;
27 import java.util.concurrent.ConcurrentHashMap;
28
29 /***
30 * A bean, used by BeanUtils, to set configuration from an XML configuration file.
31 *
32 * @author <a href="mailto:gluck@thoughtworks.com">Greg Luck</a>
33 * @version $Id: Configuration.html 13146 2011-08-01 17:12:39Z oletizi $
34 */
35 public final class Configuration {
36
37 /***
38 * Default value for dynamicConfig
39 */
40 public static final boolean DEFAULT_DYNAMIC_CONFIG = true;
41 /***
42 * Default value for updateCheck
43 */
44 public static final boolean DEFAULT_UPDATE_CHECK = true;
45 /***
46 * Default value for defaultTransactionTimeoutInSeconds
47 */
48 public static final int DEFAULT_TRANSACTION_TIMEOUT = 15;
49 /***
50 * Default value for maxBytesLocalHeap when not explicitly set
51 */
52 public static final long DEFAULT_MAX_BYTES_ON_HEAP = 0;
53 /***
54 * Default value for maxBytesLocalOffHeap when not explicitly set
55 */
56 public static final long DEFAULT_MAX_BYTES_OFF_HEAP = 0;
57 /***
58 * Default value for maxBytesLocalDisk when not explicitly set
59 */
60 public static final long DEFAULT_MAX_BYTES_ON_DISK = 0;
61 /***
62 * Default value for monitoring
63 */
64 public static final Monitoring DEFAULT_MONITORING = Monitoring.AUTODETECT;
65
66 /***
67 * Default transactionManagerLookupConfiguration
68 */
69 public static final FactoryConfiguration DEFAULT_TRANSACTION_MANAGER_LOOKUP_CONFIG = getDefaultTransactionManagerLookupConfiguration();
70 private static final int HUNDRED = 100;
71
72 /***
73 * Represents whether monitoring should be enabled or not.
74 *
75 * @author amiller
76 */
77 public enum Monitoring {
78 /*** When possible, notice the use of Terracotta and auto register the SampledCacheMBean. */
79 AUTODETECT,
80
81 /*** Always auto register the SampledCacheMBean */
82 ON,
83
84 /*** Never auto register the SampledCacheMBean */
85 OFF;
86 }
87
88 private String cacheManagerName;
89 private boolean updateCheck = DEFAULT_UPDATE_CHECK;
90 private int defaultTransactionTimeoutInSeconds = DEFAULT_TRANSACTION_TIMEOUT;
91 private Monitoring monitoring = DEFAULT_MONITORING;
92 private DiskStoreConfiguration diskStoreConfiguration;
93 private CacheConfiguration defaultCacheConfiguration;
94 private final List<FactoryConfiguration> cacheManagerPeerProviderFactoryConfiguration = new ArrayList<FactoryConfiguration>();
95 private final List<FactoryConfiguration> cacheManagerPeerListenerFactoryConfiguration = new ArrayList<FactoryConfiguration>();
96 private FactoryConfiguration transactionManagerLookupConfiguration;
97 private FactoryConfiguration cacheManagerEventListenerFactoryConfiguration;
98 private TerracottaClientConfiguration terracottaConfigConfiguration;
99 private final Map<String, CacheConfiguration> cacheConfigurations = new ConcurrentHashMap<String, CacheConfiguration>();
100 private ConfigurationSource configurationSource;
101 private boolean dynamicConfig = DEFAULT_DYNAMIC_CONFIG;
102 private Long maxBytesLocalHeap;
103 private Long maxBytesLocalOffHeap;
104 private Long maxBytesLocalDisk;
105
106 /***
107 * Empty constructor, which is used by {@link ConfigurationFactory}, and can be also used programmatically.
108 * <p/>
109 * If you are using it programmtically you need to call the relevant add and setter methods in this class to populate everything.
110 */
111 public Configuration() {
112 }
113
114 /***
115 * Checks whether the user explicitly set the maxBytesOnDisk
116 * @return true if set by user, false otherwise
117 * @see #setMaxBytesLocalDisk(Long)
118 */
119 public boolean isMaxBytesLocalDiskSet() {
120 return maxBytesLocalDisk != null;
121 }
122
123 /***
124 * Checks whether the user explicitly set the maxBytesOffHeat
125 * @return true if set by user, false otherwise
126 * @see #setMaxBytesLocalOffHeap(Long)
127 */
128 public boolean isMaxBytesLocalOffHeapSet() {
129 return maxBytesLocalOffHeap != null;
130 }
131
132 /***
133 * Checks whether the user explicitly set the maxBytesOnHeap
134 * @return true if set by user, false otherwise
135 * @see #setMaxBytesLocalHeap(Long)
136 */
137 public boolean isMaxBytesLocalHeapSet() {
138 return maxBytesLocalHeap != null;
139 }
140
141
142 private static FactoryConfiguration getDefaultTransactionManagerLookupConfiguration() {
143 FactoryConfiguration configuration = new FactoryConfiguration();
144 configuration.setClass(DefaultTransactionManagerLookup.class.getName());
145 return configuration;
146 }
147
148 /***
149 * Builder to set the cache manager name.
150 *
151 * @see #setName(String)
152 * @param name
153 * the name to set
154 * @return this configuration instance
155 */
156 public final Configuration name(String name) {
157 setName(name);
158 return this;
159 }
160
161 /***
162 * Allows BeanHandler to set the CacheManager name.
163 */
164 public final void setName(String name) {
165 this.cacheManagerName = name;
166 }
167
168 /***
169 * CacheManager name
170 */
171 public final String getName() {
172 return this.cacheManagerName;
173 }
174
175 /***
176 * Builder to set the state of the automated update check.
177 *
178 * @param updateCheck
179 * {@code true} if the update check should be turned on; or {@code false} otherwise
180 * @return this configuration instance
181 */
182 public final Configuration updateCheck(boolean updateCheck) {
183 setUpdateCheck(updateCheck);
184 return this;
185 }
186
187 /***
188 * Allows BeanHandler to set the updateCheck flag.
189 */
190 public final void setUpdateCheck(boolean updateCheck) {
191 this.updateCheck = updateCheck;
192 }
193
194 /***
195 * Get flag for updateCheck
196 */
197 public final boolean getUpdateCheck() {
198 return this.updateCheck;
199 }
200
201 /***
202 * Builder to set the default transaction timeout.
203 *
204 * @param defaultTransactionTimeoutInSeconds the default transaction timeout in seconds
205 * @return this configuration instance
206 */
207 public final Configuration defaultTransactionTimeoutInSeconds(int defaultTransactionTimeoutInSeconds) {
208 setDefaultTransactionTimeoutInSeconds(defaultTransactionTimeoutInSeconds);
209 return this;
210 }
211
212 /***
213 * Allows BeanHandler to set the default transaction timeout.
214 */
215 public final void setDefaultTransactionTimeoutInSeconds(int defaultTransactionTimeoutInSeconds) {
216 this.defaultTransactionTimeoutInSeconds = defaultTransactionTimeoutInSeconds;
217 }
218
219 /***
220 * Get default transaction timeout
221 * @return default transaction timeout in seconds
222 */
223 public final int getDefaultTransactionTimeoutInSeconds() {
224 return defaultTransactionTimeoutInSeconds;
225 }
226
227 /***
228 * Builder to set the monitoring approach
229 *
230 * @param monitoring
231 * an non-null instance of {@link Monitoring}
232 * @return this configuration instance
233 */
234 public final Configuration monitoring(Monitoring monitoring) {
235 if (null == monitoring) {
236 throw new IllegalArgumentException("Monitoring value must be non-null");
237 }
238
239 this.monitoring = monitoring;
240 return this;
241 }
242
243 /***
244 * Allows BeanHandler to set the monitoring flag
245 */
246 public final void setMonitoring(String monitoring) {
247 if (monitoring == null) {
248 throw new IllegalArgumentException("Monitoring value must be non-null");
249 }
250 this.monitoring = Monitoring.valueOf(Monitoring.class, monitoring.toUpperCase());
251 }
252
253 /***
254 * Get monitoring type, should not be null
255 */
256 public final Monitoring getMonitoring() {
257 return this.monitoring;
258 }
259
260 /***
261 * Builder to set the dynamic config capability
262 *
263 * @param dynamicConfig
264 * {@code true} if dynamic config should be enabled; or {@code false} otherwise.
265 * @return this configuration instance
266 */
267 public final Configuration dynamicConfig(boolean dynamicConfig) {
268 setDynamicConfig(dynamicConfig);
269 return this;
270 }
271
272 /***
273 * Allows BeanHandler to set the dynamic configuration flag
274 */
275 public final void setDynamicConfig(boolean dynamicConfig) {
276 this.dynamicConfig = dynamicConfig;
277 }
278
279 /***
280 * Get flag for dynamicConfig
281 */
282 public final boolean getDynamicConfig() {
283 return this.dynamicConfig;
284 }
285
286 /***
287 * Maximum amount of bytes the CacheManager will use on the heap
288 * @return amount of bytes, 0 is unbound
289 */
290 public long getMaxBytesLocalHeap() {
291 return maxBytesLocalHeap == null ? DEFAULT_MAX_BYTES_ON_HEAP : maxBytesLocalHeap;
292 }
293
294 /***
295 * Sets maximum amount of bytes the CacheManager will use on the Disk Tier.
296 * @param maxBytesOnHeap String representation of the size.
297 * @see MemoryUnit#parseSizeInBytes(String)
298 */
299 public void setMaxBytesLocalHeap(final String maxBytesOnHeap) {
300 if (isPercentage(maxBytesOnHeap)) {
301 long maxMemory = Runtime.getRuntime().maxMemory();
302 long mem = maxMemory / HUNDRED * parsePercentage(maxBytesOnHeap);
303 setMaxBytesLocalHeap(mem);
304 } else {
305 setMaxBytesLocalHeap(MemoryUnit.parseSizeInBytes(maxBytesOnHeap));
306 }
307 }
308
309 private int parsePercentage(final String stringValue) {
310 String trimmed = stringValue.trim();
311 int percentage = Integer.parseInt(trimmed.substring(0, trimmed.length() - 1));
312 if (percentage > HUNDRED || percentage < 0) {
313 throw new IllegalArgumentException("Percentage need values need to be between 0 and 100 inclusive, but got : " + percentage);
314 }
315 return percentage;
316 }
317
318 private boolean isPercentage(final String stringValue) {
319 String trimmed = stringValue.trim();
320 return trimmed.charAt(trimmed.length() - 1) == '%';
321 }
322
323 /***
324 * Sets the maximum amount of bytes the cache manager being configured will use on the OnHeap tier
325 * @param maxBytesOnHeap amount of bytes
326 */
327 public void setMaxBytesLocalHeap(final Long maxBytesOnHeap) {
328 verifyGreaterThanZero(maxBytesOnHeap, "maxBytesOnHeap");
329 this.maxBytesLocalHeap = maxBytesOnHeap;
330 }
331
332 /***
333 * Sets the maxOnHeap size for the cache being configured
334 * @param amount the amount of unit
335 * @param memoryUnit the actual unit
336 * @return this
337 * @see #setMaxBytesLocalHeap(Long)
338 */
339 public Configuration maxBytesLocalHeap(final long amount, final MemoryUnit memoryUnit) {
340 setMaxBytesLocalHeap(memoryUnit.toBytes(amount));
341 return this;
342 }
343
344 /***
345 * Maximum amount of bytes the CacheManager will use on the OffHeap Tier.
346 * @return amount in bytes
347 */
348 public long getMaxBytesLocalOffHeap() {
349 return maxBytesLocalOffHeap == null ? DEFAULT_MAX_BYTES_OFF_HEAP : maxBytesLocalOffHeap;
350 }
351
352 /***
353 * Sets maximum amount of bytes the CacheManager will use on the OffHeap Tier.
354 * @param maxBytesOffHeap String representation of the size.
355 * @see MemoryUnit#parseSizeInBytes(String)
356 */
357 public void setMaxBytesLocalOffHeap(final String maxBytesOffHeap) {
358 setMaxBytesLocalOffHeap(MemoryUnit.parseSizeInBytes(maxBytesOffHeap));
359 }
360
361 /***
362 * Sets maximum amount of bytes the CacheManager will use on the OffHeap Tier.
363 * @param maxBytesOffHeap max bytes on disk in bytes. Needs be be greater than 0
364 */
365 public void setMaxBytesLocalOffHeap(final Long maxBytesOffHeap) {
366 verifyGreaterThanZero(maxBytesOffHeap, "maxBytesOffHeap");
367 this.maxBytesLocalOffHeap = maxBytesOffHeap;
368 }
369
370 /***
371 * Sets the maximum size for the OffHeap tier for all the caches this CacheManagers holds.
372 * @param amount the amount of unit
373 * @param memoryUnit the actual unit
374 * @return this
375 */
376 public Configuration maxBytesLocalOffHeap(final long amount, final MemoryUnit memoryUnit) {
377 setMaxBytesLocalOffHeap(memoryUnit.toBytes(amount));
378 return this;
379 }
380
381 /***
382 * Maximum amount of bytes the CacheManager will use on the Disk Tier.
383 * @return amount in bytes
384 */
385 public long getMaxBytesLocalDisk() {
386 return maxBytesLocalDisk == null ? DEFAULT_MAX_BYTES_ON_DISK : maxBytesLocalDisk;
387 }
388
389 /***
390 * Sets maximum amount of bytes the CacheManager will use on the Disk Tier.
391 * @param maxBytesOnDisk String representation of the size.
392 * @see MemoryUnit#parseSizeInBytes(String)
393 */
394 public void setMaxBytesLocalDisk(final String maxBytesOnDisk) {
395 setMaxBytesLocalDisk(MemoryUnit.parseSizeInBytes(maxBytesOnDisk));
396 }
397
398 /***
399 * Sets maximum amount of bytes the CacheManager will use on the Disk Tier.
400 * @param maxBytesOnDisk max bytes on disk in bytes. Needs be be greater than 0
401 */
402 public void setMaxBytesLocalDisk(final Long maxBytesOnDisk) {
403 verifyGreaterThanZero(maxBytesOnDisk, "maxBytesOnDisk");
404 this.maxBytesLocalDisk = maxBytesOnDisk;
405 }
406
407 /***
408 * Sets the maxOnDisk size
409 * @param amount the amount of unit
410 * @param memoryUnit the actual unit
411 * @return this
412 * @see #setMaxBytesLocalDisk(Long)
413 */
414 public Configuration maxBytesLocalDisk(final long amount, final MemoryUnit memoryUnit) {
415 setMaxBytesLocalDisk(memoryUnit.toBytes(amount));
416 return this;
417 }
418
419 private void verifyGreaterThanZero(final Long maxBytesOnHeap, final String field) {
420 if (maxBytesOnHeap != null && maxBytesOnHeap < 1) {
421 throw new IllegalArgumentException(field + " has to be larger than 0");
422 }
423 }
424
425 /***
426 * Builder to add a disk store to the cache manager, only one disk store can be added.
427 *
428 * @param diskStoreConfigurationParameter
429 * the disk store configuration to use
430 * @return this configuration instance
431 * @throws ObjectExistsException
432 * if the disk store has already been configured
433 */
434 public final Configuration diskStore(DiskStoreConfiguration diskStoreConfigurationParameter) throws ObjectExistsException {
435 addDiskStore(diskStoreConfigurationParameter);
436 return this;
437 }
438
439 /***
440 * Allows BeanHandler to add disk store location to the configuration.
441 */
442 public final void addDiskStore(DiskStoreConfiguration diskStoreConfigurationParameter) throws ObjectExistsException {
443 if (diskStoreConfiguration != null) {
444 throw new ObjectExistsException("The Disk Store has already been configured");
445 }
446 diskStoreConfiguration = diskStoreConfigurationParameter;
447 }
448
449 /***
450 * Builder to add a transaction manager lookup class to the cache manager, only one of these can be added.
451 *
452 * @param transactionManagerLookupParameter
453 * the transaction manager lookup class to use
454 * @return this configuration instance
455 * @throws ObjectExistsException
456 * if the transaction manager lookup has already been configured
457 */
458 public final Configuration transactionManagerLookup(FactoryConfiguration transactionManagerLookupParameter)
459 throws ObjectExistsException {
460 addTransactionManagerLookup(transactionManagerLookupParameter);
461 return this;
462 }
463
464 /***
465 * Allows BeanHandler to add transaction manager lookup to the configuration.
466 */
467 public final void addTransactionManagerLookup(FactoryConfiguration transactionManagerLookupParameter) throws ObjectExistsException {
468 if (transactionManagerLookupConfiguration != null) {
469 throw new ObjectExistsException("The TransactionManagerLookup class has already been configured");
470 }
471 transactionManagerLookupConfiguration = transactionManagerLookupParameter;
472 }
473
474 /***
475 * Builder to set the event lister through a factory, only one of these can be added and subsequent calls are ignored.
476 *
477 * @return this configuration instance
478 */
479 public final Configuration cacheManagerEventListenerFactory(FactoryConfiguration cacheManagerEventListenerFactoryConfiguration) {
480 addCacheManagerEventListenerFactory(cacheManagerEventListenerFactoryConfiguration);
481 return this;
482 }
483
484 /***
485 * Allows BeanHandler to add the CacheManagerEventListener to the configuration.
486 */
487 public final void addCacheManagerEventListenerFactory(FactoryConfiguration cacheManagerEventListenerFactoryConfiguration) {
488 if (this.cacheManagerEventListenerFactoryConfiguration == null) {
489 this.cacheManagerEventListenerFactoryConfiguration = cacheManagerEventListenerFactoryConfiguration;
490 }
491 }
492
493 /***
494 * Builder method to add a peer provider through a factory.
495 *
496 * @return this configuration instance
497 */
498 public final Configuration cacheManagerPeerProviderFactory(FactoryConfiguration factory) {
499 addCacheManagerPeerProviderFactory(factory);
500 return this;
501 }
502
503 /***
504 * Adds a CacheManagerPeerProvider through FactoryConfiguration.
505 */
506 public final void addCacheManagerPeerProviderFactory(FactoryConfiguration factory) {
507 cacheManagerPeerProviderFactoryConfiguration.add(factory);
508 }
509
510 /***
511 * Builder method to add a peer listener through a factory.
512 *
513 * @return this configuration instance
514 */
515 public final Configuration cacheManagerPeerListenerFactory(FactoryConfiguration factory) {
516 addCacheManagerPeerListenerFactory(factory);
517 return this;
518 }
519
520 /***
521 * Adds a CacheManagerPeerListener through FactoryConfiguration.
522 */
523 public final void addCacheManagerPeerListenerFactory(FactoryConfiguration factory) {
524 cacheManagerPeerListenerFactoryConfiguration.add(factory);
525 }
526
527 /***
528 * Builder method to Terracotta capabilities to the cache manager through a dedicated configuration, this can only be used once.
529 *
530 * @return this configuration instance
531 * @throws ObjectExistsException
532 * if the Terracotta config has already been configured
533 */
534 public final Configuration terracotta(TerracottaClientConfiguration terracottaConfiguration) throws ObjectExistsException {
535 addTerracottaConfig(terracottaConfiguration);
536 return this;
537 }
538
539 /***
540 * Allows BeanHandler to add a Terracotta configuration to the configuration
541 */
542 public final void addTerracottaConfig(TerracottaClientConfiguration terracottaConfiguration) throws ObjectExistsException {
543 if (this.terracottaConfigConfiguration != null) {
544 throw new ObjectExistsException("The TerracottaConfig has already been configured");
545 }
546 this.terracottaConfigConfiguration = terracottaConfiguration;
547 }
548
549 /***
550 * Builder method to set the default cache configuration, this can only be used once.
551 *
552 * @return this configuration instance
553 * @throws ObjectExistsException
554 * if the default cache config has already been configured
555 */
556 public final Configuration defaultCache(CacheConfiguration defaultCacheConfiguration) throws ObjectExistsException {
557 setDefaultCacheConfiguration(defaultCacheConfiguration);
558 return this;
559 }
560
561 /***
562 * Allows BeanHandler to add a default configuration to the configuration.
563 */
564 public final void addDefaultCache(CacheConfiguration defaultCacheConfiguration) throws ObjectExistsException {
565 if (this.defaultCacheConfiguration != null) {
566 throw new ObjectExistsException("The Default Cache has already been configured");
567 }
568 this.defaultCacheConfiguration = defaultCacheConfiguration;
569 }
570
571 /***
572 * Builder to add a new cache through its config
573 *
574 * @return this configuration instance
575 * @throws ObjectExistsException
576 * if a cache with the same name already exists, or if the name conflicts with the name of the default cache
577 */
578 public final Configuration cache(CacheConfiguration cacheConfiguration) throws ObjectExistsException {
579 addCache(cacheConfiguration);
580 return this;
581 }
582
583 /***
584 * Allows BeanHandler to add Cache Configurations to the configuration.
585 */
586 public final void addCache(CacheConfiguration cacheConfiguration) throws ObjectExistsException {
587 if (cacheConfigurations.get(cacheConfiguration.name) != null) {
588 throw new ObjectExistsException("Cannot create cache: " + cacheConfiguration.name + " with the same name as an existing one.");
589 }
590 if (cacheConfiguration.name.equalsIgnoreCase(net.sf.ehcache.Cache.DEFAULT_CACHE_NAME)) {
591 throw new ObjectExistsException("The Default Cache has already been configured");
592 }
593
594 cacheConfigurations.put(cacheConfiguration.name, cacheConfiguration);
595 }
596
597 /***
598 * Gets a Map of cacheConfigurations.
599 */
600 public final Set<String> getCacheConfigurationsKeySet() {
601 return cacheConfigurations.keySet();
602 }
603
604 /***
605 * @return the configuration's default cache configuration
606 */
607 public final CacheConfiguration getDefaultCacheConfiguration() {
608 return defaultCacheConfiguration;
609 }
610
611 /***
612 * @param defaultCacheConfiguration
613 */
614 public final void setDefaultCacheConfiguration(CacheConfiguration defaultCacheConfiguration) {
615 this.defaultCacheConfiguration = defaultCacheConfiguration;
616 }
617
618 /***
619 * Gets the disk store configuration.
620 */
621 public final DiskStoreConfiguration getDiskStoreConfiguration() {
622 return diskStoreConfiguration;
623 }
624
625 /***
626 * Gets the transaction manager lookup configuration.
627 */
628 public final FactoryConfiguration getTransactionManagerLookupConfiguration() {
629 if (transactionManagerLookupConfiguration == null) {
630 return getDefaultTransactionManagerLookupConfiguration();
631 }
632 return transactionManagerLookupConfiguration;
633 }
634
635 /***
636 * Gets the CacheManagerPeerProvider factory configuration.
637 */
638 public final List<FactoryConfiguration> getCacheManagerPeerProviderFactoryConfiguration() {
639 return cacheManagerPeerProviderFactoryConfiguration;
640 }
641
642 /***
643 * Gets the CacheManagerPeerListener factory configuration.
644 */
645 public final List<FactoryConfiguration> getCacheManagerPeerListenerFactoryConfigurations() {
646 return cacheManagerPeerListenerFactoryConfiguration;
647 }
648
649 /***
650 * Gets the CacheManagerEventListener factory configuration.
651 */
652 public final FactoryConfiguration getCacheManagerEventListenerFactoryConfiguration() {
653 return cacheManagerEventListenerFactoryConfiguration;
654 }
655
656 /***
657 * Gets the TerracottaClientConfiguration
658 */
659 public final TerracottaClientConfiguration getTerracottaConfiguration() {
660 return this.terracottaConfigConfiguration;
661 }
662
663 /***
664 * Gets a Map of cache configurations, keyed by name.
665 */
666 public final Map<String, CacheConfiguration> getCacheConfigurations() {
667 return cacheConfigurations;
668 }
669
670 /***
671 * Builder to set the configuration source.
672 *
673 * @return this configuration instance
674 */
675 public final Configuration source(ConfigurationSource configurationSource) {
676 setSource(configurationSource);
677 return this;
678 }
679
680 /***
681 * Sets the configuration source.
682 *
683 * @param configurationSource
684 * an informative description of the source, preferably
685 * including the resource name and location.
686 */
687 public final void setSource(ConfigurationSource configurationSource) {
688 this.configurationSource = configurationSource;
689 }
690
691 /***
692 * Gets a description of the source from which this configuration was created.
693 */
694 public final ConfigurationSource getConfigurationSource() {
695 return configurationSource;
696 }
697
698 }