1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18
19 package org.apache.catalina.startup;
20
21
22 import java.io.File;
23 import java.util.Enumeration;
24
25 import org.apache.catalina.Context;
26 import org.apache.catalina.Host;
27 import org.apache.catalina.Lifecycle;
28 import org.apache.catalina.LifecycleEvent;
29 import org.apache.catalina.LifecycleListener;
30 import org.apache.catalina.util.StringManager;
31
32
33 /**
34 * Startup event listener for a <b>Host</b> that configures Contexts (web
35 * applications) for all defined "users" who have a web application in a
36 * directory with the specified name in their home directories. The context
37 * path of each deployed application will be set to <code>~xxxxx</code>, where
38 * xxxxx is the username of the owning user for that web application
39 *
40 * @author Craig R. McClanahan
41 * @version $Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $
42 */
43
44 public final class UserConfig
45 implements LifecycleListener {
46
47
48 private static org.apache.juli.logging.Log log=
49 org.apache.juli.logging.LogFactory.getLog( UserConfig.class );
50
51
52 // ----------------------------------------------------- Instance Variables
53
54
55 /**
56 * The Java class name of the Context configuration class we should use.
57 */
58 private String configClass = "org.apache.catalina.startup.ContextConfig";
59
60
61 /**
62 * The Java class name of the Context implementation we should use.
63 */
64 private String contextClass = "org.apache.catalina.core.StandardContext";
65
66
67 /**
68 * The directory name to be searched for within each user home directory.
69 */
70 private String directoryName = "public_html";
71
72
73 /**
74 * The base directory containing user home directories.
75 */
76 private String homeBase = null;
77
78
79 /**
80 * The Host we are associated with.
81 */
82 private Host host = null;
83
84
85 /**
86 * The string resources for this package.
87 */
88 private static final StringManager sm =
89 StringManager.getManager(Constants.Package);
90
91
92 /**
93 * The Java class name of the user database class we should use.
94 */
95 private String userClass =
96 "org.apache.catalina.startup.PasswdUserDatabase";
97
98
99 // ------------------------------------------------------------- Properties
100
101
102 /**
103 * Return the Context configuration class name.
104 */
105 public String getConfigClass() {
106
107 return (this.configClass);
108
109 }
110
111
112 /**
113 * Set the Context configuration class name.
114 *
115 * @param configClass The new Context configuration class name.
116 */
117 public void setConfigClass(String configClass) {
118
119 this.configClass = configClass;
120
121 }
122
123
124 /**
125 * Return the Context implementation class name.
126 */
127 public String getContextClass() {
128
129 return (this.contextClass);
130
131 }
132
133
134 /**
135 * Set the Context implementation class name.
136 *
137 * @param contextClass The new Context implementation class name.
138 */
139 public void setContextClass(String contextClass) {
140
141 this.contextClass = contextClass;
142
143 }
144
145
146 /**
147 * Return the directory name for user web applications.
148 */
149 public String getDirectoryName() {
150
151 return (this.directoryName);
152
153 }
154
155
156 /**
157 * Set the directory name for user web applications.
158 *
159 * @param directoryName The new directory name
160 */
161 public void setDirectoryName(String directoryName) {
162
163 this.directoryName = directoryName;
164
165 }
166
167
168 /**
169 * Return the base directory containing user home directories.
170 */
171 public String getHomeBase() {
172
173 return (this.homeBase);
174
175 }
176
177
178 /**
179 * Set the base directory containing user home directories.
180 *
181 * @param homeBase The new base directory
182 */
183 public void setHomeBase(String homeBase) {
184
185 this.homeBase = homeBase;
186
187 }
188
189
190 /**
191 * Return the user database class name for this component.
192 */
193 public String getUserClass() {
194
195 return (this.userClass);
196
197 }
198
199
200 /**
201 * Set the user database class name for this component.
202 */
203 public void setUserClass(String userClass) {
204
205 this.userClass = userClass;
206
207 }
208
209
210 // --------------------------------------------------------- Public Methods
211
212
213 /**
214 * Process the START event for an associated Host.
215 *
216 * @param event The lifecycle event that has occurred
217 */
218 public void lifecycleEvent(LifecycleEvent event) {
219
220 // Identify the host we are associated with
221 try {
222 host = (Host) event.getLifecycle();
223 } catch (ClassCastException e) {
224 log.error(sm.getString("hostConfig.cce", event.getLifecycle()), e);
225 return;
226 }
227
228 // Process the event that has occurred
229 if (event.getType().equals(Lifecycle.START_EVENT))
230 start();
231 else if (event.getType().equals(Lifecycle.STOP_EVENT))
232 stop();
233
234 }
235
236
237 // -------------------------------------------------------- Private Methods
238
239
240 /**
241 * Deploy a web application for any user who has a web application present
242 * in a directory with a specified name within their home directory.
243 */
244 private void deploy() {
245
246 if (host.getLogger().isDebugEnabled())
247 host.getLogger().debug(sm.getString("userConfig.deploying"));
248
249 // Load the user database object for this host
250 UserDatabase database = null;
251 try {
252 Class clazz = Class.forName(userClass);
253 database = (UserDatabase) clazz.newInstance();
254 database.setUserConfig(this);
255 } catch (Exception e) {
256 host.getLogger().error(sm.getString("userConfig.database"), e);
257 return;
258 }
259
260 // Deploy the web application (if any) for each defined user
261 Enumeration users = database.getUsers();
262 while (users.hasMoreElements()) {
263 String user = (String) users.nextElement();
264 String home = database.getHome(user);
265 deploy(user, home);
266 }
267
268 }
269
270
271 /**
272 * Deploy a web application for the specified user if they have such an
273 * application in the defined directory within their home directory.
274 *
275 * @param user Username owning the application to be deployed
276 * @param home Home directory of this user
277 */
278 private void deploy(String user, String home) {
279
280 // Does this user have a web application to be deployed?
281 String contextPath = "/~" + user;
282 if (host.findChild(contextPath) != null)
283 return;
284 File app = new File(home, directoryName);
285 if (!app.exists() || !app.isDirectory())
286 return;
287 /*
288 File dd = new File(app, "/WEB-INF/web.xml");
289 if (!dd.exists() || !dd.isFile() || !dd.canRead())
290 return;
291 */
292 host.getLogger().info(sm.getString("userConfig.deploy", user));
293
294 // Deploy the web application for this user
295 try {
296 Class clazz = Class.forName(contextClass);
297 Context context =
298 (Context) clazz.newInstance();
299 context.setPath(contextPath);
300 context.setDocBase(app.toString());
301 if (context instanceof Lifecycle) {
302 clazz = Class.forName(configClass);
303 LifecycleListener listener =
304 (LifecycleListener) clazz.newInstance();
305 ((Lifecycle) context).addLifecycleListener(listener);
306 }
307 host.addChild(context);
308 } catch (Exception e) {
309 host.getLogger().error(sm.getString("userConfig.error", user), e);
310 }
311
312 }
313
314
315 /**
316 * Process a "start" event for this Host.
317 */
318 private void start() {
319
320 if (host.getLogger().isDebugEnabled())
321 host.getLogger().debug(sm.getString("userConfig.start"));
322
323 deploy();
324
325 }
326
327
328 /**
329 * Process a "stop" event for this Host.
330 */
331 private void stop() {
332
333 if (host.getLogger().isDebugEnabled())
334 host.getLogger().debug(sm.getString("userConfig.stop"));
335
336 }
337
338
339 }