changeset 18:1915c9c69129

Rename package.
author Mikhail Kryshen <mikhail@kryshen.net>
date Tue, 03 Nov 2009 03:42:30 +0300
parents 012d66bbc61f
children d3495301ca01
files dist/README src/kryshen/catalina/startup/HomesUserConfig.java src/kryshen/catalina/startup/PasswdUserConfig.java src/kryshen/catalina/startup/UserConfig.java src/kryshen/catalina/userconfig/HomesUserConfig.java src/kryshen/catalina/userconfig/PasswdUserConfig.java src/kryshen/catalina/userconfig/UserConfig.java
diffstat 7 files changed, 398 insertions(+), 398 deletions(-) [+]
line diff
     1.1 --- a/dist/README	Tue Nov 03 03:32:45 2009 +0300
     1.2 +++ b/dist/README	Tue Nov 03 03:42:30 2009 +0300
     1.3 @@ -15,11 +15,11 @@
     1.4  element in the Tomcat configuration file (server.xml).
     1.5  
     1.6  Listener that uses passwd database to list users:
     1.7 -    <Listener className="kryshen.catalina.startup.PasswdUserConfig"/>
     1.8 +    <Listener className="kryshen.catalina.userconfig.PasswdUserConfig"/>
     1.9  
    1.10  Listener that considers all home directories in the specified base
    1.11  directory:
    1.12 -    <Listener className="kryshen.catalina.startup.HomesUserConfig"/>
    1.13 +    <Listener className="kryshen.catalina.userconfig.HomesUserConfig"/>
    1.14  
    1.15  = Listener properties =
    1.16  
     2.1 --- a/src/kryshen/catalina/startup/HomesUserConfig.java	Tue Nov 03 03:32:45 2009 +0300
     2.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.3 @@ -1,78 +0,0 @@
     2.4 -/*
     2.5 - * Copyright 2009 Mikhail Kryshen
     2.6 - *
     2.7 - * Licensed under the Apache License, Version 2.0 (the "License");
     2.8 - * you may not use this file except in compliance with the License.
     2.9 - * You may obtain a copy of the License at
    2.10 - *
    2.11 - *     http://www.apache.org/licenses/LICENSE-2.0
    2.12 - *
    2.13 - * Unless required by applicable law or agreed to in writing, software
    2.14 - * distributed under the License is distributed on an "AS IS" BASIS,
    2.15 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    2.16 - * See the License for the specific language governing permissions and
    2.17 - * limitations under the License.
    2.18 - */
    2.19 -
    2.20 -package kryshen.catalina.startup;
    2.21 -
    2.22 -import java.io.File;
    2.23 -import org.apache.juli.logging.LogFactory;
    2.24 -
    2.25 -/**
    2.26 - * Event listener for Host that deploys and updates applications 
    2.27 - * provided by users. Files in the specified base directory are 
    2.28 - * considered tp be user home directories.
    2.29 - *
    2.30 - * @author Mikhail Kryshen
    2.31 - */
    2.32 -public class HomesUserConfig extends UserConfig {
    2.33 -
    2.34 -    /**
    2.35 -     * The base directory containing user home directories.
    2.36 -     */
    2.37 -    private String homeBase = "/home";
    2.38 -
    2.39 -
    2.40 -    public HomesUserConfig() {
    2.41 -        log = LogFactory.getLog(HomesUserConfig.class);
    2.42 -    }
    2.43 -
    2.44 -    /**
    2.45 -     * Return the base directory containing user home directories.
    2.46 -     */
    2.47 -    public String getHomeBase() {
    2.48 -        return homeBase;
    2.49 -    }
    2.50 -
    2.51 -    /**
    2.52 -     * Set the base directory containing user home directories.
    2.53 -     *
    2.54 -     * @param homeBase The new base directory
    2.55 -     */
    2.56 -    public void setHomeBase(String homeBase) {
    2.57 -        this.homeBase = homeBase;
    2.58 -    }
    2.59 -
    2.60 -    @Override
    2.61 -    protected void deployUserApps() {
    2.62 -        File homeBaseFile = new File(homeBase);
    2.63 -
    2.64 -        if (!homeBaseFile.isDirectory()) {
    2.65 -            log.error("Invalid home base.");
    2.66 -            return;
    2.67 -        }
    2.68 -
    2.69 -        String[] homes = homeBaseFile.list();
    2.70 -
    2.71 -        for (String name : homes) {
    2.72 -            File home = new File(homeBaseFile, name);
    2.73 -            
    2.74 -            if (!home.isDirectory() /* || !home.canExecute() */) {
    2.75 -                continue;
    2.76 -            }
    2.77 -
    2.78 -            deployUserApps(name, home);
    2.79 -        }
    2.80 -    }
    2.81 -}
     3.1 --- a/src/kryshen/catalina/startup/PasswdUserConfig.java	Tue Nov 03 03:32:45 2009 +0300
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,126 +0,0 @@
     3.4 -/*
     3.5 - * Copyright 2009 Mikhail Kryshen
     3.6 - *
     3.7 - * Licensed under the Apache License, Version 2.0 (the "License");
     3.8 - * you may not use this file except in compliance with the License.
     3.9 - * You may obtain a copy of the License at
    3.10 - *
    3.11 - *     http://www.apache.org/licenses/LICENSE-2.0
    3.12 - *
    3.13 - * Unless required by applicable law or agreed to in writing, software
    3.14 - * distributed under the License is distributed on an "AS IS" BASIS,
    3.15 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    3.16 - * See the License for the specific language governing permissions and
    3.17 - * limitations under the License.
    3.18 - */
    3.19 -
    3.20 -package kryshen.catalina.startup;
    3.21 -
    3.22 -import java.io.BufferedReader;
    3.23 -import java.io.File;
    3.24 -import java.io.FileReader;
    3.25 -import java.io.IOException;
    3.26 -import java.io.InputStreamReader;
    3.27 -import java.util.regex.Pattern;
    3.28 -import org.apache.juli.logging.LogFactory;
    3.29 -
    3.30 -/**
    3.31 - * Event listener for Host that deploys and updates applications 
    3.32 - * provided by users listed in passwd database.
    3.33 - *
    3.34 - * @author Mikhail Kryshen
    3.35 - */
    3.36 -public class PasswdUserConfig extends UserConfig {
    3.37 -
    3.38 -    private static final String PASSWD_DATABASE = "passwd";
    3.39 -
    3.40 -    /* Passwd format details. */
    3.41 -    private static final Pattern PASSWD_SPLIT_PATTERN = Pattern.compile(":");
    3.42 -    private static final int PASSWD_FIELD_USERNAME = 0;
    3.43 -    private static final int PASSWD_FIELD_HOME = 5;
    3.44 -
    3.45 -    /**
    3.46 -     * Command for retrieving passwd database.
    3.47 -     */
    3.48 -    private String getent = null;
    3.49 -
    3.50 -    /**
    3.51 -     * Path to local passwd file.
    3.52 -     */
    3.53 -    private String passwd = "/etc/passwd";
    3.54 -
    3.55 -    
    3.56 -    public PasswdUserConfig() {
    3.57 -        log = LogFactory.getLog(PasswdUserConfig.class);
    3.58 -    }
    3.59 -
    3.60 -    /**
    3.61 -     * Get command for retrieving passwd database.
    3.62 -     */
    3.63 -    public String getGetent() {
    3.64 -        return getent;
    3.65 -    }
    3.66 -
    3.67 -    /**
    3.68 -     * Set command for retrieving passwd database.
    3.69 -     */
    3.70 -    public void setGetent(String getent) {
    3.71 -        this.getent = getent;
    3.72 -    }
    3.73 -
    3.74 -    /**
    3.75 -     * Get path to local passwd file.
    3.76 -     */
    3.77 -    public String getPasswd() {
    3.78 -        return passwd;
    3.79 -    }
    3.80 -
    3.81 -    /**
    3.82 -     * Set path to local passwd file.
    3.83 -     */
    3.84 -    public void setPasswd(String passwd) {
    3.85 -        this.passwd = passwd;
    3.86 -    }
    3.87 -
    3.88 -    @Override
    3.89 -    protected void deployUserApps() {
    3.90 -        BufferedReader in;
    3.91 -
    3.92 -        try {
    3.93 -            if (getent == null) {
    3.94 -                in = new BufferedReader(new FileReader(passwd));
    3.95 -            } else {
    3.96 -                Process process = Runtime.getRuntime().exec(
    3.97 -                       new String[] {getent, PASSWD_DATABASE});
    3.98 -
    3.99 -                in = new BufferedReader(
   3.100 -                        new InputStreamReader(process.getInputStream()));
   3.101 -            }
   3.102 -
   3.103 -            String line;
   3.104 -
   3.105 -            try {
   3.106 -                while ((line = in.readLine()) != null) {
   3.107 -                    String[] fields = PASSWD_SPLIT_PATTERN.split(line);
   3.108 -
   3.109 -                    String name = fields[PASSWD_FIELD_USERNAME];
   3.110 -                    File home = new File(fields[PASSWD_FIELD_HOME]);
   3.111 -
   3.112 -                    if (!home.isDirectory()) {
   3.113 -                        //log.warn("Invalid home directory for user "
   3.114 -                        //        + name + ": " + home.getPath() + ".");
   3.115 -                        continue;
   3.116 -                    }
   3.117 -
   3.118 -                    deployUserApps(name, home);
   3.119 -                }
   3.120 -            } finally {
   3.121 -                in.close();
   3.122 -            }
   3.123 -        } catch (IOException e) {
   3.124 -            log.error("Error reading passwd database.", e);
   3.125 -        } catch (ArrayIndexOutOfBoundsException e) {
   3.126 -            log.error("Invalid passwd format.", e);
   3.127 -        }
   3.128 -    }
   3.129 -}
     4.1 --- a/src/kryshen/catalina/startup/UserConfig.java	Tue Nov 03 03:32:45 2009 +0300
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,192 +0,0 @@
     4.4 -/*
     4.5 - * Copyright 2009 Mikhail Kryshen
     4.6 - *
     4.7 - * Licensed under the Apache License, Version 2.0 (the "License");
     4.8 - * you may not use this file except in compliance with the License.
     4.9 - * You may obtain a copy of the License at
    4.10 - *
    4.11 - *     http://www.apache.org/licenses/LICENSE-2.0
    4.12 - *
    4.13 - * Unless required by applicable law or agreed to in writing, software
    4.14 - * distributed under the License is distributed on an "AS IS" BASIS,
    4.15 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    4.16 - * See the License for the specific language governing permissions and
    4.17 - * limitations under the License.
    4.18 - */
    4.19 -
    4.20 -package kryshen.catalina.startup;
    4.21 -
    4.22 -import java.io.File;
    4.23 -import org.apache.catalina.startup.HostConfig;
    4.24 -import org.apache.juli.logging.LogFactory;
    4.25 -
    4.26 -/**
    4.27 - * Event listener for Host that deploys and updates applications
    4.28 - * provided by users. In multi-app mode (appsPerUser property &gt 1)
    4.29 - * each user's application is mapped to "/~username/application" path,
    4.30 - * ROOT is mapped to "/~username". In single-app mode (appsPerUser = 1)
    4.31 - * each user could have single webapp mapped to "/~username".
    4.32 - *
    4.33 - * @author Mikhail Kryshen
    4.34 - */
    4.35 -public abstract class UserConfig extends HostConfig {
    4.36 -
    4.37 -    /**
    4.38 -     * The directory name to be searched for within each user home directory.
    4.39 -     */
    4.40 -    private String directoryName = "public_webapps";
    4.41 -
    4.42 -    /**
    4.43 -     * Maximum number of application each user is allowed to deploy.
    4.44 -     */
    4.45 -    private int appsPerUser = -1;
    4.46 -
    4.47 -
    4.48 -    protected UserConfig() {
    4.49 -        log = LogFactory.getLog(UserConfig.class);
    4.50 -    }
    4.51 -
    4.52 -    /**
    4.53 -     *  Returns the directory name to be searched for webapps for each user
    4.54 -     *  (relative to the user's home direcotry).
    4.55 -     */
    4.56 -    public String getDirectoryName() {
    4.57 -        return directoryName;
    4.58 -    }
    4.59 -
    4.60 -    /**
    4.61 -     *  Set the directory name to be searched for webapps for each user
    4.62 -     *  (relative to the user's home direcotry).
    4.63 -     * 
    4.64 -     * @param directoryName The new directory name.
    4.65 -     */
    4.66 -    public void setDirectoryName(String directoryName) {
    4.67 -        this.directoryName = directoryName;
    4.68 -    }
    4.69 -
    4.70 -    
    4.71 -    /**
    4.72 -     * Returns the maximum number of application each user is allowed to
    4.73 -     * deploy.
    4.74 -     */
    4.75 -    public int getAppsPerUser() {
    4.76 -        return appsPerUser;
    4.77 -    }
    4.78 -
    4.79 -    /**
    4.80 -     * Set the maximum number of application each user is allowed to deploy.
    4.81 -     */
    4.82 -    public void setAppsPerUser(int appsPerUser) {
    4.83 -        if (appsPerUser < 1 && appsPerUser != -1) {
    4.84 -            throw new IllegalArgumentException("Invalid appsPerUser value.");
    4.85 -        }
    4.86 -
    4.87 -        this.appsPerUser = appsPerUser;
    4.88 -    }
    4.89 -
    4.90 -
    4.91 -    @Override
    4.92 -    protected void deployApps() {       
    4.93 -        deployUserApps();
    4.94 -    }
    4.95 -
    4.96 -    @Override
    4.97 -    protected void deployApps(String name) {
    4.98 -        throw new UnsupportedOperationException
    4.99 -                ("deployApps(String) is not supported.");
   4.100 -    }
   4.101 -
   4.102 -    /**
   4.103 -     * Deploy applications for all available users.
   4.104 -     */
   4.105 -    protected abstract void deployUserApps();
   4.106 -
   4.107 -    /**
   4.108 -     * Deploy applications (if any) for specific user.
   4.109 -     *
   4.110 -     * @param user Username.
   4.111 -     * @param home User home directory.
   4.112 -     */
   4.113 -    protected void deployUserApps(String user, File home) {
   4.114 -        File base = new File(home, directoryName);
   4.115 -
   4.116 -        if (!base.isDirectory() || !base.canRead()) {
   4.117 -            return;
   4.118 -        }
   4.119 -
   4.120 -        String[] files = base.list();
   4.121 -
   4.122 -        if (files == null) {
   4.123 -            log.warn("Error reading base directory: " + base.getPath() + ".");
   4.124 -            return;
   4.125 -        }
   4.126 -
   4.127 -        // TODO: deployWars
   4.128 -
   4.129 -        if (appsPerUser == 1) {
   4.130 -            // Single application mode.
   4.131 -            deployUserApp(user, base, "ROOT");
   4.132 -        } else {
   4.133 -            // Multiple applications mode.
   4.134 -            deployUserDirectories(user, base, files);
   4.135 -        }
   4.136 -    }
   4.137 -
   4.138 -    /**
   4.139 -     * Deploy user application directories.
   4.140 -     *
   4.141 -     * @param user Username.
   4.142 -     * @param base Application base directory.
   4.143 -     * @param files Array of directories to deploy.
   4.144 -     */
   4.145 -    protected void deployUserDirectories(String user, File base, 
   4.146 -            String[] files) {
   4.147 -
   4.148 -        int appsNum = files.length;
   4.149 -
   4.150 -        if (appsNum > appsPerUser) {
   4.151 -            appsNum = appsPerUser;
   4.152 -        }
   4.153 -
   4.154 -        for (int i = 0; i < appsNum; i++) {
   4.155 -            if (files[i].equalsIgnoreCase("META-INF")) {
   4.156 -                continue;
   4.157 -            }
   4.158 -
   4.159 -            if (files[i].equalsIgnoreCase("WEB-INF")) {
   4.160 -                continue;
   4.161 -            }
   4.162 -
   4.163 -            File dir = new File(base, files[i]);
   4.164 -
   4.165 -            if (!dir.isDirectory() || !dir.canRead()) {
   4.166 -                continue;
   4.167 -            }
   4.168 -
   4.169 -            deployUserApp(user, dir, files[i]);
   4.170 -        }
   4.171 -    }
   4.172 -
   4.173 -    /**
   4.174 -     * Deploy user application.
   4.175 -     *
   4.176 -     * @param user Username.
   4.177 -     * @param dir Application directory.
   4.178 -     * @param app Application name.
   4.179 -     */
   4.180 -    protected void deployUserApp(String user, File dir, String app) {
   4.181 -        String contextPath;
   4.182 -
   4.183 -        if (app.equals("ROOT")) {
   4.184 -            contextPath = "/~" + user;
   4.185 -        } else {
   4.186 -            contextPath = "/~" + user + '/' + app.replace('#', '/');
   4.187 -        }
   4.188 -
   4.189 -        if (isServiced(contextPath)) {
   4.190 -            return;
   4.191 -        }
   4.192 -
   4.193 -        deployDirectory(contextPath, dir, dir.getAbsolutePath());
   4.194 -    }
   4.195 -}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/src/kryshen/catalina/userconfig/HomesUserConfig.java	Tue Nov 03 03:42:30 2009 +0300
     5.3 @@ -0,0 +1,78 @@
     5.4 +/*
     5.5 + * Copyright 2009 Mikhail Kryshen
     5.6 + *
     5.7 + * Licensed under the Apache License, Version 2.0 (the "License");
     5.8 + * you may not use this file except in compliance with the License.
     5.9 + * You may obtain a copy of the License at
    5.10 + *
    5.11 + *     http://www.apache.org/licenses/LICENSE-2.0
    5.12 + *
    5.13 + * Unless required by applicable law or agreed to in writing, software
    5.14 + * distributed under the License is distributed on an "AS IS" BASIS,
    5.15 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    5.16 + * See the License for the specific language governing permissions and
    5.17 + * limitations under the License.
    5.18 + */
    5.19 +
    5.20 +package kryshen.catalina.userconfig;
    5.21 +
    5.22 +import java.io.File;
    5.23 +import org.apache.juli.logging.LogFactory;
    5.24 +
    5.25 +/**
    5.26 + * Event listener for Host that deploys and updates applications 
    5.27 + * provided by users. Files in the specified base directory are 
    5.28 + * considered tp be user home directories.
    5.29 + *
    5.30 + * @author Mikhail Kryshen
    5.31 + */
    5.32 +public class HomesUserConfig extends UserConfig {
    5.33 +
    5.34 +    /**
    5.35 +     * The base directory containing user home directories.
    5.36 +     */
    5.37 +    private String homeBase = "/home";
    5.38 +
    5.39 +
    5.40 +    public HomesUserConfig() {
    5.41 +        log = LogFactory.getLog(HomesUserConfig.class);
    5.42 +    }
    5.43 +
    5.44 +    /**
    5.45 +     * Return the base directory containing user home directories.
    5.46 +     */
    5.47 +    public String getHomeBase() {
    5.48 +        return homeBase;
    5.49 +    }
    5.50 +
    5.51 +    /**
    5.52 +     * Set the base directory containing user home directories.
    5.53 +     *
    5.54 +     * @param homeBase The new base directory
    5.55 +     */
    5.56 +    public void setHomeBase(String homeBase) {
    5.57 +        this.homeBase = homeBase;
    5.58 +    }
    5.59 +
    5.60 +    @Override
    5.61 +    protected void deployUserApps() {
    5.62 +        File homeBaseFile = new File(homeBase);
    5.63 +
    5.64 +        if (!homeBaseFile.isDirectory()) {
    5.65 +            log.error("Invalid home base.");
    5.66 +            return;
    5.67 +        }
    5.68 +
    5.69 +        String[] homes = homeBaseFile.list();
    5.70 +
    5.71 +        for (String name : homes) {
    5.72 +            File home = new File(homeBaseFile, name);
    5.73 +            
    5.74 +            if (!home.isDirectory() /* || !home.canExecute() */) {
    5.75 +                continue;
    5.76 +            }
    5.77 +
    5.78 +            deployUserApps(name, home);
    5.79 +        }
    5.80 +    }
    5.81 +}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/kryshen/catalina/userconfig/PasswdUserConfig.java	Tue Nov 03 03:42:30 2009 +0300
     6.3 @@ -0,0 +1,126 @@
     6.4 +/*
     6.5 + * Copyright 2009 Mikhail Kryshen
     6.6 + *
     6.7 + * Licensed under the Apache License, Version 2.0 (the "License");
     6.8 + * you may not use this file except in compliance with the License.
     6.9 + * You may obtain a copy of the License at
    6.10 + *
    6.11 + *     http://www.apache.org/licenses/LICENSE-2.0
    6.12 + *
    6.13 + * Unless required by applicable law or agreed to in writing, software
    6.14 + * distributed under the License is distributed on an "AS IS" BASIS,
    6.15 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    6.16 + * See the License for the specific language governing permissions and
    6.17 + * limitations under the License.
    6.18 + */
    6.19 +
    6.20 +package kryshen.catalina.userconfig;
    6.21 +
    6.22 +import java.io.BufferedReader;
    6.23 +import java.io.File;
    6.24 +import java.io.FileReader;
    6.25 +import java.io.IOException;
    6.26 +import java.io.InputStreamReader;
    6.27 +import java.util.regex.Pattern;
    6.28 +import org.apache.juli.logging.LogFactory;
    6.29 +
    6.30 +/**
    6.31 + * Event listener for Host that deploys and updates applications 
    6.32 + * provided by users listed in passwd database.
    6.33 + *
    6.34 + * @author Mikhail Kryshen
    6.35 + */
    6.36 +public class PasswdUserConfig extends UserConfig {
    6.37 +
    6.38 +    private static final String PASSWD_DATABASE = "passwd";
    6.39 +
    6.40 +    /* Passwd format details. */
    6.41 +    private static final Pattern PASSWD_SPLIT_PATTERN = Pattern.compile(":");
    6.42 +    private static final int PASSWD_FIELD_USERNAME = 0;
    6.43 +    private static final int PASSWD_FIELD_HOME = 5;
    6.44 +
    6.45 +    /**
    6.46 +     * Command for retrieving passwd database.
    6.47 +     */
    6.48 +    private String getent = null;
    6.49 +
    6.50 +    /**
    6.51 +     * Path to local passwd file.
    6.52 +     */
    6.53 +    private String passwd = "/etc/passwd";
    6.54 +
    6.55 +    
    6.56 +    public PasswdUserConfig() {
    6.57 +        log = LogFactory.getLog(PasswdUserConfig.class);
    6.58 +    }
    6.59 +
    6.60 +    /**
    6.61 +     * Get command for retrieving passwd database.
    6.62 +     */
    6.63 +    public String getGetent() {
    6.64 +        return getent;
    6.65 +    }
    6.66 +
    6.67 +    /**
    6.68 +     * Set command for retrieving passwd database.
    6.69 +     */
    6.70 +    public void setGetent(String getent) {
    6.71 +        this.getent = getent;
    6.72 +    }
    6.73 +
    6.74 +    /**
    6.75 +     * Get path to local passwd file.
    6.76 +     */
    6.77 +    public String getPasswd() {
    6.78 +        return passwd;
    6.79 +    }
    6.80 +
    6.81 +    /**
    6.82 +     * Set path to local passwd file.
    6.83 +     */
    6.84 +    public void setPasswd(String passwd) {
    6.85 +        this.passwd = passwd;
    6.86 +    }
    6.87 +
    6.88 +    @Override
    6.89 +    protected void deployUserApps() {
    6.90 +        BufferedReader in;
    6.91 +
    6.92 +        try {
    6.93 +            if (getent == null) {
    6.94 +                in = new BufferedReader(new FileReader(passwd));
    6.95 +            } else {
    6.96 +                Process process = Runtime.getRuntime().exec(
    6.97 +                       new String[] {getent, PASSWD_DATABASE});
    6.98 +
    6.99 +                in = new BufferedReader(
   6.100 +                        new InputStreamReader(process.getInputStream()));
   6.101 +            }
   6.102 +
   6.103 +            String line;
   6.104 +
   6.105 +            try {
   6.106 +                while ((line = in.readLine()) != null) {
   6.107 +                    String[] fields = PASSWD_SPLIT_PATTERN.split(line);
   6.108 +
   6.109 +                    String name = fields[PASSWD_FIELD_USERNAME];
   6.110 +                    File home = new File(fields[PASSWD_FIELD_HOME]);
   6.111 +
   6.112 +                    if (!home.isDirectory()) {
   6.113 +                        //log.warn("Invalid home directory for user "
   6.114 +                        //        + name + ": " + home.getPath() + ".");
   6.115 +                        continue;
   6.116 +                    }
   6.117 +
   6.118 +                    deployUserApps(name, home);
   6.119 +                }
   6.120 +            } finally {
   6.121 +                in.close();
   6.122 +            }
   6.123 +        } catch (IOException e) {
   6.124 +            log.error("Error reading passwd database.", e);
   6.125 +        } catch (ArrayIndexOutOfBoundsException e) {
   6.126 +            log.error("Invalid passwd format.", e);
   6.127 +        }
   6.128 +    }
   6.129 +}
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/src/kryshen/catalina/userconfig/UserConfig.java	Tue Nov 03 03:42:30 2009 +0300
     7.3 @@ -0,0 +1,192 @@
     7.4 +/*
     7.5 + * Copyright 2009 Mikhail Kryshen
     7.6 + *
     7.7 + * Licensed under the Apache License, Version 2.0 (the "License");
     7.8 + * you may not use this file except in compliance with the License.
     7.9 + * You may obtain a copy of the License at
    7.10 + *
    7.11 + *     http://www.apache.org/licenses/LICENSE-2.0
    7.12 + *
    7.13 + * Unless required by applicable law or agreed to in writing, software
    7.14 + * distributed under the License is distributed on an "AS IS" BASIS,
    7.15 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    7.16 + * See the License for the specific language governing permissions and
    7.17 + * limitations under the License.
    7.18 + */
    7.19 +
    7.20 +package kryshen.catalina.userconfig;
    7.21 +
    7.22 +import java.io.File;
    7.23 +import org.apache.catalina.startup.HostConfig;
    7.24 +import org.apache.juli.logging.LogFactory;
    7.25 +
    7.26 +/**
    7.27 + * Event listener for Host that deploys and updates applications
    7.28 + * provided by users. In multi-app mode (appsPerUser property &gt 1)
    7.29 + * each user's application is mapped to "/~username/application" path,
    7.30 + * ROOT is mapped to "/~username". In single-app mode (appsPerUser = 1)
    7.31 + * each user could have single webapp mapped to "/~username".
    7.32 + *
    7.33 + * @author Mikhail Kryshen
    7.34 + */
    7.35 +public abstract class UserConfig extends HostConfig {
    7.36 +
    7.37 +    /**
    7.38 +     * The directory name to be searched for within each user home directory.
    7.39 +     */
    7.40 +    private String directoryName = "public_webapps";
    7.41 +
    7.42 +    /**
    7.43 +     * Maximum number of application each user is allowed to deploy.
    7.44 +     */
    7.45 +    private int appsPerUser = -1;
    7.46 +
    7.47 +
    7.48 +    protected UserConfig() {
    7.49 +        log = LogFactory.getLog(UserConfig.class);
    7.50 +    }
    7.51 +
    7.52 +    /**
    7.53 +     *  Returns the directory name to be searched for webapps for each user
    7.54 +     *  (relative to the user's home direcotry).
    7.55 +     */
    7.56 +    public String getDirectoryName() {
    7.57 +        return directoryName;
    7.58 +    }
    7.59 +
    7.60 +    /**
    7.61 +     *  Set the directory name to be searched for webapps for each user
    7.62 +     *  (relative to the user's home direcotry).
    7.63 +     * 
    7.64 +     * @param directoryName The new directory name.
    7.65 +     */
    7.66 +    public void setDirectoryName(String directoryName) {
    7.67 +        this.directoryName = directoryName;
    7.68 +    }
    7.69 +
    7.70 +    
    7.71 +    /**
    7.72 +     * Returns the maximum number of application each user is allowed to
    7.73 +     * deploy.
    7.74 +     */
    7.75 +    public int getAppsPerUser() {
    7.76 +        return appsPerUser;
    7.77 +    }
    7.78 +
    7.79 +    /**
    7.80 +     * Set the maximum number of application each user is allowed to deploy.
    7.81 +     */
    7.82 +    public void setAppsPerUser(int appsPerUser) {
    7.83 +        if (appsPerUser < 1 && appsPerUser != -1) {
    7.84 +            throw new IllegalArgumentException("Invalid appsPerUser value.");
    7.85 +        }
    7.86 +
    7.87 +        this.appsPerUser = appsPerUser;
    7.88 +    }
    7.89 +
    7.90 +
    7.91 +    @Override
    7.92 +    protected void deployApps() {       
    7.93 +        deployUserApps();
    7.94 +    }
    7.95 +
    7.96 +    @Override
    7.97 +    protected void deployApps(String name) {
    7.98 +        throw new UnsupportedOperationException
    7.99 +                ("deployApps(String) is not supported.");
   7.100 +    }
   7.101 +
   7.102 +    /**
   7.103 +     * Deploy applications for all available users.
   7.104 +     */
   7.105 +    protected abstract void deployUserApps();
   7.106 +
   7.107 +    /**
   7.108 +     * Deploy applications (if any) for specific user.
   7.109 +     *
   7.110 +     * @param user Username.
   7.111 +     * @param home User home directory.
   7.112 +     */
   7.113 +    protected void deployUserApps(String user, File home) {
   7.114 +        File base = new File(home, directoryName);
   7.115 +
   7.116 +        if (!base.isDirectory() || !base.canRead()) {
   7.117 +            return;
   7.118 +        }
   7.119 +
   7.120 +        String[] files = base.list();
   7.121 +
   7.122 +        if (files == null) {
   7.123 +            log.warn("Error reading base directory: " + base.getPath() + ".");
   7.124 +            return;
   7.125 +        }
   7.126 +
   7.127 +        // TODO: deployWars
   7.128 +
   7.129 +        if (appsPerUser == 1) {
   7.130 +            // Single application mode.
   7.131 +            deployUserApp(user, base, "ROOT");
   7.132 +        } else {
   7.133 +            // Multiple applications mode.
   7.134 +            deployUserDirectories(user, base, files);
   7.135 +        }
   7.136 +    }
   7.137 +
   7.138 +    /**
   7.139 +     * Deploy user application directories.
   7.140 +     *
   7.141 +     * @param user Username.
   7.142 +     * @param base Application base directory.
   7.143 +     * @param files Array of directories to deploy.
   7.144 +     */
   7.145 +    protected void deployUserDirectories(String user, File base, 
   7.146 +            String[] files) {
   7.147 +
   7.148 +        int appsNum = files.length;
   7.149 +
   7.150 +        if (appsNum > appsPerUser) {
   7.151 +            appsNum = appsPerUser;
   7.152 +        }
   7.153 +
   7.154 +        for (int i = 0; i < appsNum; i++) {
   7.155 +            if (files[i].equalsIgnoreCase("META-INF")) {
   7.156 +                continue;
   7.157 +            }
   7.158 +
   7.159 +            if (files[i].equalsIgnoreCase("WEB-INF")) {
   7.160 +                continue;
   7.161 +            }
   7.162 +
   7.163 +            File dir = new File(base, files[i]);
   7.164 +
   7.165 +            if (!dir.isDirectory() || !dir.canRead()) {
   7.166 +                continue;
   7.167 +            }
   7.168 +
   7.169 +            deployUserApp(user, dir, files[i]);
   7.170 +        }
   7.171 +    }
   7.172 +
   7.173 +    /**
   7.174 +     * Deploy user application.
   7.175 +     *
   7.176 +     * @param user Username.
   7.177 +     * @param dir Application directory.
   7.178 +     * @param app Application name.
   7.179 +     */
   7.180 +    protected void deployUserApp(String user, File dir, String app) {
   7.181 +        String contextPath;
   7.182 +
   7.183 +        if (app.equals("ROOT")) {
   7.184 +            contextPath = "/~" + user;
   7.185 +        } else {
   7.186 +            contextPath = "/~" + user + '/' + app.replace('#', '/');
   7.187 +        }
   7.188 +
   7.189 +        if (isServiced(contextPath)) {
   7.190 +            return;
   7.191 +        }
   7.192 +
   7.193 +        deployDirectory(contextPath, dir, dir.getAbsolutePath());
   7.194 +    }
   7.195 +}