001: /*
002: * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/startup/UserConfig.java,v 1.3 2001/09/05 00:31:50 craigmcc Exp $
003: * $Revision: 1.3 $
004: * $Date: 2001/09/05 00:31:50 $
005: *
006: * ====================================================================
007: *
008: * The Apache Software License, Version 1.1
009: *
010: * Copyright (c) 1999 The Apache Software Foundation. All rights
011: * reserved.
012: *
013: * Redistribution and use in source and binary forms, with or without
014: * modification, are permitted provided that the following conditions
015: * are met:
016: *
017: * 1. Redistributions of source code must retain the above copyright
018: * notice, this list of conditions and the following disclaimer.
019: *
020: * 2. Redistributions in binary form must reproduce the above copyright
021: * notice, this list of conditions and the following disclaimer in
022: * the documentation and/or other materials provided with the
023: * distribution.
024: *
025: * 3. The end-user documentation included with the redistribution, if
026: * any, must include the following acknowlegement:
027: * "This product includes software developed by the
028: * Apache Software Foundation (http://www.apache.org/)."
029: * Alternately, this acknowlegement may appear in the software itself,
030: * if and wherever such third-party acknowlegements normally appear.
031: *
032: * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
033: * Foundation" must not be used to endorse or promote products derived
034: * from this software without prior written permission. For written
035: * permission, please contact apache@apache.org.
036: *
037: * 5. Products derived from this software may not be called "Apache"
038: * nor may "Apache" appear in their names without prior written
039: * permission of the Apache Group.
040: *
041: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
042: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
043: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
044: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
045: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
046: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
047: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
048: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
049: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
050: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
051: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
052: * SUCH DAMAGE.
053: * ====================================================================
054: *
055: * This software consists of voluntary contributions made by many
056: * individuals on behalf of the Apache Software Foundation. For more
057: * information on the Apache Software Foundation, please see
058: * <http://www.apache.org/>.
059: *
060: * [Additional notices, if required by prior licensing conditions]
061: *
062: */
063:
064: package org.apache.catalina.startup;
065:
066: import java.io.File;
067: import java.io.IOException;
068: import java.util.Enumeration;
069: import org.apache.catalina.Context;
070: import org.apache.catalina.Host;
071: import org.apache.catalina.Lifecycle;
072: import org.apache.catalina.LifecycleEvent;
073: import org.apache.catalina.LifecycleListener;
074: import org.apache.catalina.Logger;
075: import org.apache.catalina.util.StringManager;
076:
077: /**
078: * Startup event listener for a <b>Host</b> that configures Contexts (web
079: * applications) for all defined "users" who have a web application in a
080: * directory with the specified name in their home directories. The context
081: * path of each deployed application will be set to <code>~xxxxx</code>, where
082: * xxxxx is the username of the owning user for that web application
083: *
084: * @author Craig R. McClanahan
085: * @version $Revision: 1.3 $ $Date: 2001/09/05 00:31:50 $
086: */
087:
088: public final class UserConfig implements LifecycleListener {
089:
090: // ----------------------------------------------------- Instance Variables
091:
092: /**
093: * The Java class name of the Context configuration class we should use.
094: */
095: private String configClass = "org.apache.catalina.startup.ContextConfig";
096:
097: /**
098: * The Java class name of the Context implementation we should use.
099: */
100: private String contextClass = "org.apache.catalina.core.StandardContext";
101:
102: /**
103: * The debugging detail level for this component.
104: */
105: private int debug = 999;
106:
107: /**
108: * The directory name to be searched for within each user home directory.
109: */
110: private String directoryName = "public_html";
111:
112: /**
113: * The base directory containing user home directories.
114: */
115: private String homeBase = null;
116:
117: /**
118: * The Host we are associated with.
119: */
120: private Host host = null;
121:
122: /**
123: * The string resources for this package.
124: */
125: private static final StringManager sm = StringManager
126: .getManager(Constants.Package);
127:
128: /**
129: * The Java class name of the user database class we should use.
130: */
131: private String userClass = "org.apache.catalina.startup.PasswdUserDatabase";
132:
133: // ------------------------------------------------------------- Properties
134:
135: /**
136: * Return the Context configuration class name.
137: */
138: public String getConfigClass() {
139:
140: return (this .configClass);
141:
142: }
143:
144: /**
145: * Set the Context configuration class name.
146: *
147: * @param configClass The new Context configuration class name.
148: */
149: public void setConfigClass(String configClass) {
150:
151: this .configClass = configClass;
152:
153: }
154:
155: /**
156: * Return the Context implementation class name.
157: */
158: public String getContextClass() {
159:
160: return (this .contextClass);
161:
162: }
163:
164: /**
165: * Set the Context implementation class name.
166: *
167: * @param contextClass The new Context implementation class name.
168: */
169: public void setContextClass(String contextClass) {
170:
171: this .contextClass = contextClass;
172:
173: }
174:
175: /**
176: * Return the debugging detail level for this component.
177: */
178: public int getDebug() {
179:
180: return (this .debug);
181:
182: }
183:
184: /**
185: * Set the debugging detail level for this component.
186: *
187: * @param debug The new debugging detail level
188: */
189: public void setDebug(int debug) {
190:
191: this .debug = debug;
192:
193: }
194:
195: /**
196: * Return the directory name for user web applications.
197: */
198: public String getDirectoryName() {
199:
200: return (this .directoryName);
201:
202: }
203:
204: /**
205: * Set the directory name for user web applications.
206: *
207: * @param directoryName The new directory name
208: */
209: public void setDirectoryName(String directoryName) {
210:
211: this .directoryName = directoryName;
212:
213: }
214:
215: /**
216: * Return the base directory containing user home directories.
217: */
218: public String getHomeBase() {
219:
220: return (this .homeBase);
221:
222: }
223:
224: /**
225: * Set the base directory containing user home directories.
226: *
227: * @param homeBase The new base directory
228: */
229: public void setHomeBase(String homeBase) {
230:
231: this .homeBase = homeBase;
232:
233: }
234:
235: /**
236: * Return the user database class name for this component.
237: */
238: public String getUserClass() {
239:
240: return (this .userClass);
241:
242: }
243:
244: /**
245: * Set the user database class name for this component.
246: */
247: public void setUserClass(String userClass) {
248:
249: this .userClass = userClass;
250:
251: }
252:
253: // --------------------------------------------------------- Public Methods
254:
255: /**
256: * Process the START event for an associated Host.
257: *
258: * @param event The lifecycle event that has occurred
259: */
260: public void lifecycleEvent(LifecycleEvent event) {
261:
262: // Identify the host we are associated with
263: try {
264: host = (Host) event.getLifecycle();
265: } catch (ClassCastException e) {
266: log(sm.getString("hostConfig.cce", event.getLifecycle()), e);
267: return;
268: }
269:
270: // Process the event that has occurred
271: if (event.getType().equals(Lifecycle.START_EVENT))
272: start();
273: else if (event.getType().equals(Lifecycle.STOP_EVENT))
274: stop();
275:
276: }
277:
278: // -------------------------------------------------------- Private Methods
279:
280: /**
281: * Deploy a web application for any user who has a web application present
282: * in a directory with a specified name within their home directory.
283: */
284: private void deploy() {
285:
286: if (debug >= 1)
287: log(sm.getString("userConfig.deploying"));
288:
289: // Load the user database object for this host
290: UserDatabase database = null;
291: try {
292: Class clazz = Class.forName(userClass);
293: database = (UserDatabase) clazz.newInstance();
294: database.setUserConfig(this );
295: } catch (Exception e) {
296: log(sm.getString("userConfig.database"), e);
297: return;
298: }
299:
300: // Deploy the web application (if any) for each defined user
301: Enumeration users = database.getUsers();
302: while (users.hasMoreElements()) {
303: String user = (String) users.nextElement();
304: String home = database.getHome(user);
305: deploy(user, home);
306: }
307:
308: }
309:
310: /**
311: * Deploy a web application for the specified user if they have such an
312: * application in the defined directory within their home directory.
313: *
314: * @param user Username owning the application to be deployed
315: * @param home Home directory of this user
316: */
317: private void deploy(String user, String home) {
318:
319: // Does this user have a web application to be deployed?
320: String contextPath = "/~" + user;
321: if (host.findChild(contextPath) != null)
322: return;
323: File app = new File(home, directoryName);
324: if (!app.exists() || !app.isDirectory())
325: return;
326: /*
327: File dd = new File(app, "/WEB-INF/web.xml");
328: if (!dd.exists() || !dd.isFile() || !dd.canRead())
329: return;
330: */
331: log(sm.getString("userConfig.deploy", user));
332:
333: // Deploy the web application for this user
334: try {
335: Class clazz = Class.forName(contextClass);
336: Context context = (Context) clazz.newInstance();
337: context.setPath(contextPath);
338: context.setDocBase(app.toString());
339: if (context instanceof Lifecycle) {
340: clazz = Class.forName(configClass);
341: LifecycleListener listener = (LifecycleListener) clazz
342: .newInstance();
343: ((Lifecycle) context).addLifecycleListener(listener);
344: }
345: host.addChild(context);
346: } catch (Exception e) {
347: log(sm.getString("userConfig.error", user), e);
348: }
349:
350: }
351:
352: /**
353: * Log a message on the Logger associated with our Host (if any)
354: *
355: * @param message Message to be logged
356: */
357: private void log(String message) {
358:
359: Logger logger = null;
360: if (host != null)
361: logger = host.getLogger();
362: if (logger != null)
363: logger
364: .log("UserConfig[" + host.getName() + "]: "
365: + message);
366: else
367: System.out.println("UserConfig[" + host.getName() + "]: "
368: + message);
369:
370: }
371:
372: /**
373: * Log a message on the Logger associated with our Host (if any)
374: *
375: * @param message Message to be logged
376: * @param throwable Associated exception
377: */
378: private void log(String message, Throwable throwable) {
379:
380: Logger logger = null;
381: if (host != null)
382: logger = host.getLogger();
383: if (logger != null)
384: logger.log("UserConfig[" + host.getName() + "] " + message,
385: throwable);
386: else {
387: System.out.println("UserConfig[" + host.getName() + "]: "
388: + message);
389: System.out.println("" + throwable);
390: throwable.printStackTrace(System.out);
391: }
392:
393: }
394:
395: /**
396: * Process a "start" event for this Host.
397: */
398: private void start() {
399:
400: if (debug > 0)
401: log(sm.getString("userConfig.start"));
402:
403: deploy();
404:
405: }
406:
407: /**
408: * Process a "stop" event for this Host.
409: */
410: private void stop() {
411:
412: if (debug > 0)
413: log(sm.getString("userConfig.stop"));
414:
415: }
416:
417: }
|