001: /* Copyright 2001, 2005 The JA-SIG Collaborative. All rights reserved.
002: * See license distributed with this file and
003: * available online at http://www.uportal.org/license.html
004: */
005:
006: package org.jasig.portal.layout;
007:
008: import org.jasig.portal.layout.alm.AggregatedUserLayoutStore;
009: import org.jasig.portal.properties.PropertiesManager;
010: import org.apache.commons.logging.Log;
011: import org.apache.commons.logging.LogFactory;
012:
013: /**
014: * Produces and manages a static singleton instance of IUserLayoutStore.
015: *
016: * The {@link IUserLayoutStore} implementation that we use is that named by the
017: * portal.properties property "org.jasig.portal.layout.UserLayoutStoreFactory.implementation".
018: * In the case where that property is not set or the IUserLayoutStore it names cannot
019: * be instantiated, we fall back on the {@link AggregatedUserLayoutStore} as the default.
020: *
021: * Prior to uPortal 2.5, this class existed in the package org.jasig.portal.
022: * It has been moved to its present package to express that it is part of the
023: * user layout infrastructure.
024: *
025: * This class is final because it is not designed to be subclassed.
026: *
027: * @author Ken Weiner, kweiner@unicon.net
028: * @author Michael Ivanov, mvi@immagic.com
029: * @version $Revision: 35816 $ $Date: 2005-05-18 11:27:43 -0700 (Wed, 18 May 2005) $
030: */
031: public final class UserLayoutStoreFactory {
032:
033: /**
034: * The name of the portal.properties property the value of which is the name
035: * of the IUserLayoutStore implementation we should use.
036: */
037: public static final String LAYOUT_STORE_IMPL_PROPERTY = "org.jasig.portal.layout.UserLayoutStoreFactory.implementation";
038:
039: /**
040: * Commons Logging log instance.
041: */
042: private static final Log LOG = LogFactory
043: .getLog(UserLayoutStoreFactory.class);
044:
045: /**
046: * Static singleton instance of userLayoutStoreImpl.
047: */
048: private static IUserLayoutStore userLayoutStoreImpl = null;
049:
050: /**
051: * The default IUserLayoutStore implementation we will fall back upon
052: * in the case where our property is not set or we cannot instantiate the
053: * IUserLayoutStore named by our property.
054: *
055: * This field is default scoped so that our testcase can access it. It is not intended
056: * to be part of the public API of this factory.
057: */
058: private static final Class DEFAULT_LAYOUT_STORE = AggregatedUserLayoutStore.class;
059:
060: /**
061: * Returns the singleton IUserLayoutStore instance, which will be that specified in portal.properties,
062: * an instance of the default IUserLayoutStore, or null, in that order.
063: *
064: * That is, we return a static singleton IUserLayoutStore instance when possible,
065: * prefering to return an instance of the IUserLayoutStore implementation named
066: * in our portal.properties property. If that property is not set or that implementation
067: * cannot be successfully instantiated, we will return an instance of the default
068: * IUserLayoutStore implementation. If we cannot instantiate that default IUserLayoutStore
069: * we will return null.
070: *
071: * This method is synchronized to ensure a consistent return value, resolving a
072: * double checked locking problem. By synchronizing, we ensure that when we
073: * write to the userLayoutStoreImpl static field, that write will be available
074: * to other threads when they obtain the lock and enter this method.
075: *
076: * @return the configured or default IUserLayoutStore implementation, or null
077: */
078: public static synchronized IUserLayoutStore getUserLayoutStoreImpl() {
079:
080: // if we already have a singleton instance, return it.
081: if (userLayoutStoreImpl != null) {
082: return userLayoutStoreImpl;
083: }
084:
085: // if we can instantiate one from portal.properties, let's do it
086:
087: // initialize the class name before the try so we can log the broken
088: // class name if available.
089: String className = "unknown";
090: try {
091: className = PropertiesManager
092: .getProperty(LAYOUT_STORE_IMPL_PROPERTY);
093: userLayoutStoreImpl = (IUserLayoutStore) Class.forName(
094: className).newInstance();
095: // note that we stored the static singleton instance
096: LOG
097: .info("Instantiated and stored singleton IUserLayoutStore of type "
098: + className);
099: return userLayoutStoreImpl;
100:
101: } catch (Exception e) {
102: // if anything went wrong, log the problem and fall back on our
103: // default layout store
104: LOG
105: .error(
106: "Unable to instantiate IUserLayoutStore implementation ["
107: + className
108: + "], attempting to fall back on default of "
109: + DEFAULT_LAYOUT_STORE.getName(), e);
110:
111: try {
112: userLayoutStoreImpl = (IUserLayoutStore) DEFAULT_LAYOUT_STORE
113: .newInstance();
114:
115: } catch (Exception e2) {
116: LOG.error("Error insantiating default layout store ["
117: + DEFAULT_LAYOUT_STORE + "]", e2);
118: }
119: // this will either return the default implementation if we succeeded in
120: // instantiating it, or null if we did not succeed.
121: return userLayoutStoreImpl;
122: }
123: }
124:
125: }
|