001: /*
002: * @(#)AbstractSingleStore.java
003: *
004: * Copyright (C) 2002-2003 Matt Albrecht
005: * groboclown@users.sourceforge.net
006: * http://groboutils.sourceforge.net
007: *
008: * Permission is hereby granted, free of charge, to any person obtaining a
009: * copy of this software and associated documentation files (the "Software"),
010: * to deal in the Software without restriction, including without limitation
011: * the rights to use, copy, modify, merge, publish, distribute, sublicense,
012: * and/or sell copies of the Software, and to permit persons to whom the
013: * Software is furnished to do so, subject to the following conditions:
014: *
015: * The above copyright notice and this permission notice shall be included in
016: * all copies or substantial portions of the Software.
017: *
018: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
019: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
020: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
021: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
022: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
023: * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
024: * DEALINGS IN THE SOFTWARE.
025: */
026:
027: package net.sourceforge.groboutils.util.classes.v1;
028:
029: /**
030: * Aids pluggable factories and related classes by being a central repository
031: * for storing a singleton, and creating means to load and change the singleton.
032: *
033: * @author Matt Albrecht <a href="mailto:groboclown@users.sourceforge.net">groboclown@users.sourceforge.net</a>
034: * @version $Date: 2003/02/10 22:52:36 $
035: * @since March 30, 2002
036: */
037: public abstract class AbstractSingleStore {
038: private Class instanceOf;
039: private Object singleton;
040:
041: /**
042: * Constructor specifying all the parameters for using a singleton in this
043: * framework.
044: *
045: * @param instanceOf singletons must be of this class.
046: */
047: public AbstractSingleStore(Class instanceOf) {
048: this .instanceOf = instanceOf;
049: }
050:
051: /**
052: * Returns the current inner singleton. If it has never been set, then
053: * the default will be used instead.
054: *
055: * @return the inner singleton instance.
056: * @exception IllegalStateException if no singleton was created.
057: */
058: public Object getSingleton() {
059: synchronized (this ) {
060: if (this .singleton == null) {
061: setDefaultSingleton();
062: if (this .singleton == null) {
063: throw new IllegalStateException(
064: "No singleton created.");
065: }
066: }
067: }
068: return this .singleton;
069: }
070:
071: /**
072: * Sets the singleton. It must be of the correct class, and non-null.
073: *
074: * @param singleton the singleton to set.
075: * @exception IllegalArgumentException if <tt>singleton</tt> is
076: * <tt>null</tt>, or is not of the correct type.
077: */
078: public synchronized void setSingleton(Object singleton) {
079: if (singleton == null) {
080: throw new IllegalArgumentException("no null arguments");
081: }
082: if (this .instanceOf != null
083: && !this .instanceOf.isInstance(singleton)) {
084: throw new IllegalArgumentException("Passed-in singleton "
085: + singleton + " is not assignable to class "
086: + this .instanceOf.getName() + ", but is of class "
087: + singleton.getClass().getName());
088: }
089: this .singleton = singleton;
090: }
091:
092: /**
093: * Sets the inner singleton to the default, which is an implementation
094: * specific method.
095: */
096: protected abstract void setDefaultSingleton();
097:
098: /**
099: * Helper method to load an object from the class specified in the given
100: * system property; if the class is invalid, then the given default
101: * class will be used instead. No cast testing is performed.
102: *
103: * @param key the System property to reference for the classname to
104: * instantiate. It is passed to <tt>ClassLoadHelper</tt>.
105: * @param defaultClass class to instantiate if the class defined in the
106: * system property is invalid.
107: * @return the generated object.
108: * @exception IllegalArgumentException if <tt>key</tt> is <tt>null</tt>.
109: * @see ClassLoadHelper#createObjectFromProperty( String, Class, boolean )
110: */
111: protected static Object createFromProperty(String key,
112: Class defaultClass) {
113: if (key == null) {
114: throw new IllegalArgumentException("no null args");
115: }
116: ClassLoadHelper clh = new ClassLoadHelper();
117: return clh.createObjectFromProperty(key, defaultClass, false);
118: }
119: }
|