view src/kryshen/catalina/userconfig/UserConfig.java @ 26:9501a363dcbb

Override start and stop event handlers.
author Mikhail Kryshen <mikhail@kryshen.net>
date Tue, 03 Nov 2009 17:20:42 +0300
parents 620ec7263ee1
children
line source
1 /*
2 * Copyright 2009 Mikhail Kryshen
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
17 package kryshen.catalina.userconfig;
19 import java.io.File;
20 import org.apache.catalina.startup.HostConfig;
21 import org.apache.juli.logging.LogFactory;
23 /**
24 * Event listener for Host that deploys and updates applications
25 * provided by users. In multi-app mode (appsPerUser property &gt 1)
26 * each user's application is mapped to "/~username/application" path,
27 * ROOT is mapped to "/~username". In single-app mode (appsPerUser = 1)
28 * each user could have single webapp mapped to "/~username".
29 *
30 * @author Mikhail Kryshen
31 */
32 public abstract class UserConfig extends HostConfig {
34 /**
35 * The directory name to be searched for within each user home directory.
36 */
37 private String directoryName = "public_webapps";
39 /**
40 * Maximum number of application each user is allowed to deploy.
41 */
42 private int appsPerUser = -1;
45 protected UserConfig() {
46 log = LogFactory.getLog(UserConfig.class);
47 }
49 /**
50 * Returns the directory name to be searched for webapps for each user
51 * (relative to the user's home direcotry).
52 */
53 public String getDirectoryName() {
54 return directoryName;
55 }
57 /**
58 * Set the directory name to be searched for webapps for each user
59 * (relative to the user's home direcotry).
60 *
61 * @param directoryName The new directory name.
62 */
63 public void setDirectoryName(String directoryName) {
64 this.directoryName = directoryName;
65 }
67 /**
68 * Returns the maximum number of application each user is allowed to
69 * deploy.
70 */
71 public int getAppsPerUser() {
72 return appsPerUser;
73 }
75 /**
76 * Set the maximum number of application each user is allowed to deploy.
77 */
78 public void setAppsPerUser(int appsPerUser) {
79 if (appsPerUser < 1 && appsPerUser != -1) {
80 throw new IllegalArgumentException("Invalid appsPerUser value.");
81 }
83 this.appsPerUser = appsPerUser;
84 }
86 @Override
87 protected void deployApps() {
88 deployUserApps();
89 }
91 /**
92 * Deploy applications for all available users.
93 */
94 protected abstract void deployUserApps();
96 /**
97 * Deploy applications (if any) for specific user.
98 *
99 * @param user Username.
100 * @param home User home directory.
101 */
102 protected void deployUserApps(String user, File home) {
103 File base = new File(home, directoryName);
105 if (!base.isDirectory() || !base.canRead()) {
106 return;
107 }
109 String[] files = base.list();
111 if (files == null) {
112 log.warn("Error reading base directory: " + base.getPath() + ".");
113 return;
114 }
116 // TODO: deployWars
118 if (appsPerUser == 1) {
119 // Single application mode.
120 String contextPath = getContextPath(user, "ROOT");
122 if (isServiced(contextPath)) {
123 return;
124 }
126 deployDirectory(contextPath, base, base.getAbsolutePath());
127 } else {
128 // Multiple applications mode.
129 deployUserDirectories(user, base, files);
130 }
131 }
133 /**
134 * Deploy user application directories.
135 *
136 * @param user Username.
137 * @param base Application base directory.
138 * @param files Array of directories to deploy.
139 */
140 protected void deployUserDirectories(String user, File base,
141 String[] files) {
143 int appCount = 0;
145 if (appsPerUser > 0) {
146 // Count number of already deployed user applications.
147 for (int i = 0; i < files.length; i++) {
148 String contextPath = getContextPath(user, files[i]);
150 if (isDeployed(contextPath)) {
151 appCount++;
152 }
153 }
154 }
156 // Deploy new applications.
157 for (int i = 0; i < files.length; i++) {
158 if (appsPerUser > 0 && appCount >= appsPerUser) {
159 break;
160 }
162 if (files[i].equalsIgnoreCase("META-INF") ||
163 files[i].equalsIgnoreCase("WEB-INF")) {
164 continue;
165 }
167 File dir = new File(base, files[i]);
169 if (!dir.isDirectory() || !dir.canRead()) {
170 continue;
171 }
173 String contextPath = getContextPath(user, files[i]);
175 if (isDeployed(contextPath) || isServiced(contextPath)) {
176 continue;
177 }
179 deployDirectory(contextPath, dir, dir.getAbsolutePath());
180 appCount++;
181 }
182 }
184 /**
185 * Constructs context path for the specifed user name and application.
186 *
187 * @param user User name.
188 * @param app Application name.
189 * @return Context path.
190 */
191 protected String getContextPath(String user, String app) {
192 if (app.equals("ROOT")) {
193 return "/~" + user;
194 }
196 return "/~" + user + '/' + app.replace('#', '/');
197 }
199 /**
200 * Process a start event.
201 */
202 @Override
203 public void start() {
204 if (log.isDebugEnabled()) {
205 log.debug("Starging UserConfig.");
206 }
208 if (host.getDeployOnStartup()) {
209 deployApps();
210 }
211 }
213 /**
214 * Process a stop event.
215 */
216 @Override
217 public void stop() {
218 if (log.isDebugEnabled()) {
219 log.debug("Stopping UserConfig");
220 }
222 undeployApps();
223 }
224 }