001: /*
002: * This file is part of the WfMOpen project.
003: * Copyright (C) 2001-2003 Danet GmbH (www.danet.de), GS-AN.
004: * All rights reserved.
005: *
006: * This program is free software; you can redistribute it and/or modify
007: * it under the terms of the GNU General Public License as published by
008: * the Free Software Foundation; either version 2 of the License, or
009: * (at your option) any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: *
020: * $Id: UserPrefsServiceFactory.java,v 1.2 2006/09/29 12:32:11 drmlipp Exp $
021: *
022: * $Log: UserPrefsServiceFactory.java,v $
023: * Revision 1.2 2006/09/29 12:32:11 drmlipp
024: * Consistently using WfMOpen as projct name now.
025: *
026: * Revision 1.1.1.1 2003/06/30 20:05:12 drmlipp
027: * Initial import
028: *
029: * Revision 1.15 2003/06/27 08:51:46 lipp
030: * Fixed copyright/license information.
031: *
032: * Revision 1.14 2003/06/03 12:49:47 lipp
033: * Added defaults for user preferences.
034: *
035: * Revision 1.13 2003/05/26 14:42:23 lipp
036: * Using different fallback strategy for userprefs without user prefs
037: * service.
038: *
039: * Revision 1.12 2003/05/21 20:54:44 lipp
040: * Added fallback implementation.
041: *
042: * Revision 1.11 2003/03/31 16:50:28 huaiyang
043: * Logging using common-logging.
044: *
045: * Revision 1.10 2003/03/03 12:35:18 lipp
046: * Removed inappropriate use of printStacktrace.
047: *
048: * Revision 1.9 2002/10/15 21:23:28 lipp
049: * Removed not needed method.
050: *
051: * Revision 1.8 2002/09/15 12:06:44 lipp
052: * Renamed ServiceLookup to ServiceMgmt.
053: *
054: * Revision 1.7 2002/08/17 11:11:55 lipp
055: * Fixed class loading.
056: *
057: * Revision 1.6 2002/08/14 16:21:59 feldgen
058: * Added userId (Principal principal).
059: *
060: * Revision 1.5 2002/04/03 12:53:04 lipp
061: * JavaDoc fixes.
062: *
063: * Revision 1.4 2001/12/16 10:33:45 lipp
064: * User preferences service implemented.
065: *
066: * Revision 1.3 2001/11/30 11:43:26 lipp
067: * javadoc fixes.
068: *
069: * Revision 1.2 2001/11/21 13:28:57 lipp
070: * UserPrefsService design refined.
071: *
072: * Revision 1.1 2001/11/20 20:03:22 lipp
073: * New user prefs service, interface design.
074: *
075: */
076: package de.danet.an.util.userprefs;
077:
078: import java.io.IOException;
079: import java.io.InputStream;
080:
081: import java.util.List;
082: import java.util.Properties;
083:
084: import javax.naming.NamingException;
085:
086: import de.danet.an.util.EJBUtil;
087: import de.danet.an.util.ServiceMgmt;
088:
089: /**
090: * Defines a factory API for accessing a user preferences service.<P>
091: *
092: * Setting logger priority to <code>DEBUG</code> logs information about
093: * factory lookup.
094: */
095: public abstract class UserPrefsServiceFactory {
096:
097: private static final org.apache.commons.logging.Log logger = org.apache.commons.logging.LogFactory
098: .getLog(UserPrefsServiceFactory.class);
099:
100: private static Class factoryClass = null;
101: private static Properties defaults = null;
102: private static boolean defaultsLoaded = false;
103:
104: /**
105: * Constructor. Must be overridden with a parameterless public
106: * constructor by derived class.
107: */
108: protected UserPrefsServiceFactory() {
109: }
110:
111: /**
112: * Obtain a new instance of a
113: * <code>UserPrefsServiceFactory</code>. This static method
114: * creates a new factory instance . The method uses the following
115: * ordered lookup procedure to determine the
116: * <code>UserPrefsServiceFactory</code> implementation class
117: * to load:
118: * <ul>
119: * <li>If an {@link javax.naming.InitialContext initial naming context}
120: * is available, look for a classname in
121: * <code>java:comp/env/de.danet.an.util.UserPrefsServiceFactory</code>.
122: * </li>
123: * <li>Use the services API (as detailed in the JAR specification)
124: * to determine the classname. The Services API
125: * will look for a classname in the file
126: * <code>META-INF/services/de.danet.an.UserPrefsServiceFactory</code>.
127: * in jars available to the runtime.</li>
128: * </ul>
129: *
130: * @return an instance of the <code>UserPrefsServiceFactory</code>
131: * @throws FactoryConfigurationError if a factory instance can't be
132: * created
133: */
134: public static UserPrefsServiceFactory newInstance()
135: throws FactoryConfigurationError {
136: if (factoryClass == null) {
137: factoryClass = findFactoryClass();
138: }
139: try {
140: return ((UserPrefsServiceFactory) factoryClass
141: .newInstance());
142: } catch (InstantiationException e) {
143: logger.error(e.getMessage(), e);
144: throw new FactoryConfigurationError(e.getMessage());
145: } catch (IllegalAccessException e) {
146: logger.error(e.getMessage(), e);
147: throw new FactoryConfigurationError(e.getMessage());
148: }
149: }
150:
151: private static Class findFactoryClass()
152: throws FactoryConfigurationError {
153: // Lookup in JNDI
154: try {
155: String clsname = (String) EJBUtil
156: .lookupJNDIEntry("java:comp/env/de.danet.an.util.UserPrefsServiceFactory");
157: ClassLoader cl = Thread.currentThread()
158: .getContextClassLoader();
159: Class res = cl.loadClass(clsname);
160: logger.debug("Found UserPrefsServiceFactory: " + clsname);
161: return res;
162: } catch (NamingException ne) {
163: // Name not defined
164: } catch (ClassNotFoundException e) {
165: logger.error(e.getMessage(), e);
166: throw new FactoryConfigurationError(e.getMessage());
167: } catch (ClassCastException e) {
168: logger.error(e.getMessage(), e);
169: throw new FactoryConfigurationError(e.getMessage());
170: }
171: // Lookup as service in JARs
172: List cls = ServiceMgmt
173: .providerClassesFromJARs(UserPrefsServiceFactory.class);
174: if (cls.size() > 0) {
175: Class res = (Class) cls.get(0);
176: logger.debug("Found UserPrefsServiceFactory: "
177: + res.getName());
178: return res;
179: }
180: throw new FactoryConfigurationError();
181: }
182:
183: /**
184: * Creates a new instance of a {@link UserPrefsService
185: * <code>UserPrefsService</code>} for a specific user. The method
186: * tries to locate a resource
187: * <code>default-user-preferences.properties</code> and, if found,
188: * use the defined properties as defaults for user preferences.
189: *
190: * @param userId the id used to identify the user
191: * @return a new preferences service for the specified user
192: * @throws ServiceUnavailableException may be thrown if the service
193: * cannot be created for the specified user
194: */
195: public UserPrefsService newUserPrefsService(String userId)
196: throws ServiceUnavailableException {
197: if (!defaultsLoaded) {
198: InputStream is = Thread.currentThread()
199: .getContextClassLoader().getResourceAsStream(
200: "/default-user-preferences.properties");
201: if (is != null) {
202: try {
203: defaults = new Properties();
204: defaults.load(is);
205: } catch (IOException e) {
206: logger.error(
207: "Problem loading user preferences defaults: "
208: + e.getMessage(), e);
209: }
210: }
211: defaultsLoaded = true;
212: }
213: return newUserPrefsService(userId, defaults);
214: }
215:
216: /**
217: * Creates a new instance of a {@link UserPrefsService
218: * <code>UserPrefsService</code>} for a specific user. The given
219: * properties are used as defaults for unspecified preferences.
220: *
221: * @param userId the id used to identify the user
222: * @param props used as defaults for unspecified preferences, may
223: * be <code>null</code>
224: * @return a new preferences service for the specified user
225: * @throws ServiceUnavailableException may be thrown if the service
226: * cannot be created for the specified user
227: */
228: public abstract UserPrefsService newUserPrefsService(String userId,
229: Properties props) throws ServiceUnavailableException;
230:
231: }
|