001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.catalina.startup;
019:
020: import java.io.File;
021: import java.util.Enumeration;
022:
023: import org.apache.catalina.Context;
024: import org.apache.catalina.Host;
025: import org.apache.catalina.Lifecycle;
026: import org.apache.catalina.LifecycleEvent;
027: import org.apache.catalina.LifecycleListener;
028: import org.apache.catalina.util.StringManager;
029:
030: /**
031: * Startup event listener for a <b>Host</b> that configures Contexts (web
032: * applications) for all defined "users" who have a web application in a
033: * directory with the specified name in their home directories. The context
034: * path of each deployed application will be set to <code>~xxxxx</code>, where
035: * xxxxx is the username of the owning user for that web application
036: *
037: * @author Craig R. McClanahan
038: * @version $Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $
039: */
040:
041: public final class UserConfig implements LifecycleListener {
042:
043: private static org.apache.juli.logging.Log log = org.apache.juli.logging.LogFactory
044: .getLog(UserConfig.class);
045:
046: // ----------------------------------------------------- Instance Variables
047:
048: /**
049: * The Java class name of the Context configuration class we should use.
050: */
051: private String configClass = "org.apache.catalina.startup.ContextConfig";
052:
053: /**
054: * The Java class name of the Context implementation we should use.
055: */
056: private String contextClass = "org.apache.catalina.core.StandardContext";
057:
058: /**
059: * The directory name to be searched for within each user home directory.
060: */
061: private String directoryName = "public_html";
062:
063: /**
064: * The base directory containing user home directories.
065: */
066: private String homeBase = null;
067:
068: /**
069: * The Host we are associated with.
070: */
071: private Host host = null;
072:
073: /**
074: * The string resources for this package.
075: */
076: private static final StringManager sm = StringManager
077: .getManager(Constants.Package);
078:
079: /**
080: * The Java class name of the user database class we should use.
081: */
082: private String userClass = "org.apache.catalina.startup.PasswdUserDatabase";
083:
084: // ------------------------------------------------------------- Properties
085:
086: /**
087: * Return the Context configuration class name.
088: */
089: public String getConfigClass() {
090:
091: return (this .configClass);
092:
093: }
094:
095: /**
096: * Set the Context configuration class name.
097: *
098: * @param configClass The new Context configuration class name.
099: */
100: public void setConfigClass(String configClass) {
101:
102: this .configClass = configClass;
103:
104: }
105:
106: /**
107: * Return the Context implementation class name.
108: */
109: public String getContextClass() {
110:
111: return (this .contextClass);
112:
113: }
114:
115: /**
116: * Set the Context implementation class name.
117: *
118: * @param contextClass The new Context implementation class name.
119: */
120: public void setContextClass(String contextClass) {
121:
122: this .contextClass = contextClass;
123:
124: }
125:
126: /**
127: * Return the directory name for user web applications.
128: */
129: public String getDirectoryName() {
130:
131: return (this .directoryName);
132:
133: }
134:
135: /**
136: * Set the directory name for user web applications.
137: *
138: * @param directoryName The new directory name
139: */
140: public void setDirectoryName(String directoryName) {
141:
142: this .directoryName = directoryName;
143:
144: }
145:
146: /**
147: * Return the base directory containing user home directories.
148: */
149: public String getHomeBase() {
150:
151: return (this .homeBase);
152:
153: }
154:
155: /**
156: * Set the base directory containing user home directories.
157: *
158: * @param homeBase The new base directory
159: */
160: public void setHomeBase(String homeBase) {
161:
162: this .homeBase = homeBase;
163:
164: }
165:
166: /**
167: * Return the user database class name for this component.
168: */
169: public String getUserClass() {
170:
171: return (this .userClass);
172:
173: }
174:
175: /**
176: * Set the user database class name for this component.
177: */
178: public void setUserClass(String userClass) {
179:
180: this .userClass = userClass;
181:
182: }
183:
184: // --------------------------------------------------------- Public Methods
185:
186: /**
187: * Process the START event for an associated Host.
188: *
189: * @param event The lifecycle event that has occurred
190: */
191: public void lifecycleEvent(LifecycleEvent event) {
192:
193: // Identify the host we are associated with
194: try {
195: host = (Host) event.getLifecycle();
196: } catch (ClassCastException e) {
197: log.error(sm.getString("hostConfig.cce", event
198: .getLifecycle()), e);
199: return;
200: }
201:
202: // Process the event that has occurred
203: if (event.getType().equals(Lifecycle.START_EVENT))
204: start();
205: else if (event.getType().equals(Lifecycle.STOP_EVENT))
206: stop();
207:
208: }
209:
210: // -------------------------------------------------------- Private Methods
211:
212: /**
213: * Deploy a web application for any user who has a web application present
214: * in a directory with a specified name within their home directory.
215: */
216: private void deploy() {
217:
218: if (host.getLogger().isDebugEnabled())
219: host.getLogger()
220: .debug(sm.getString("userConfig.deploying"));
221:
222: // Load the user database object for this host
223: UserDatabase database = null;
224: try {
225: Class clazz = Class.forName(userClass);
226: database = (UserDatabase) clazz.newInstance();
227: database.setUserConfig(this );
228: } catch (Exception e) {
229: host.getLogger().error(sm.getString("userConfig.database"),
230: e);
231: return;
232: }
233:
234: // Deploy the web application (if any) for each defined user
235: Enumeration users = database.getUsers();
236: while (users.hasMoreElements()) {
237: String user = (String) users.nextElement();
238: String home = database.getHome(user);
239: deploy(user, home);
240: }
241:
242: }
243:
244: /**
245: * Deploy a web application for the specified user if they have such an
246: * application in the defined directory within their home directory.
247: *
248: * @param user Username owning the application to be deployed
249: * @param home Home directory of this user
250: */
251: private void deploy(String user, String home) {
252:
253: // Does this user have a web application to be deployed?
254: String contextPath = "/~" + user;
255: if (host.findChild(contextPath) != null)
256: return;
257: File app = new File(home, directoryName);
258: if (!app.exists() || !app.isDirectory())
259: return;
260: /*
261: File dd = new File(app, "/WEB-INF/web.xml");
262: if (!dd.exists() || !dd.isFile() || !dd.canRead())
263: return;
264: */
265: host.getLogger().info(sm.getString("userConfig.deploy", user));
266:
267: // Deploy the web application for this user
268: try {
269: Class clazz = Class.forName(contextClass);
270: Context context = (Context) clazz.newInstance();
271: context.setPath(contextPath);
272: context.setDocBase(app.toString());
273: if (context instanceof Lifecycle) {
274: clazz = Class.forName(configClass);
275: LifecycleListener listener = (LifecycleListener) clazz
276: .newInstance();
277: ((Lifecycle) context).addLifecycleListener(listener);
278: }
279: host.addChild(context);
280: } catch (Exception e) {
281: host.getLogger().error(
282: sm.getString("userConfig.error", user), e);
283: }
284:
285: }
286:
287: /**
288: * Process a "start" event for this Host.
289: */
290: private void start() {
291:
292: if (host.getLogger().isDebugEnabled())
293: host.getLogger().debug(sm.getString("userConfig.start"));
294:
295: deploy();
296:
297: }
298:
299: /**
300: * Process a "stop" event for this Host.
301: */
302: private void stop() {
303:
304: if (host.getLogger().isDebugEnabled())
305: host.getLogger().debug(sm.getString("userConfig.stop"));
306:
307: }
308:
309: }
|