view src/kryshen/catalina/startup/UserConfig.java @ 15:7ab85cf3fcda

Convert to freeform project.
author Mikhail Kryshen <mikhail@kryshen.net>
date Tue, 03 Nov 2009 03:00:43 +0300
parents 618d0df5d46c
children
line wrap: on
line source

/*
 * Copyright 2009 Mikhail Kryshen
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package kryshen.catalina.startup;

import java.io.File;
import org.apache.catalina.startup.HostConfig;
import org.apache.juli.logging.LogFactory;

/**
 * Event listener for Host that deploys and updates applications
 * provided by users. In multi-app mode (appsPerUser property &gt 1)
 * each user's application is mapped to "/~username/application" path,
 * ROOT is mapped to "/~username". In single-app mode (appsPerUser = 1)
 * each user could have single webapp mapped to "/~username".
 *
 * @author Mikhail Kryshen
 */
public abstract class UserConfig extends HostConfig {

    /**
     * The directory name to be searched for within each user home directory.
     */
    private String directoryName = "public_webapps";

    /**
     * Maximum number of application each user is allowed to deploy.
     */
    private int appsPerUser = -1;


    protected UserConfig() {
        log = LogFactory.getLog(UserConfig.class);
    }

    /**
     *  Returns the directory name to be searched for webapps for each user
     *  (relative to the user's home direcotry).
     */
    public String getDirectoryName() {
        return directoryName;
    }

    /**
     *  Set the directory name to be searched for webapps for each user
     *  (relative to the user's home direcotry).
     * 
     * @param directoryName The new directory name.
     */
    public void setDirectoryName(String directoryName) {
        this.directoryName = directoryName;
    }

    
    /**
     * Returns the maximum number of application each user is allowed to
     * deploy.
     */
    public int getAppsPerUser() {
        return appsPerUser;
    }

    /**
     * Set the maximum number of application each user is allowed to deploy.
     */
    public void setAppsPerUser(int appsPerUser) {
        if (appsPerUser < 1 && appsPerUser != -1) {
            throw new IllegalArgumentException("Invalid appsPerUser value.");
        }

        this.appsPerUser = appsPerUser;
    }


    @Override
    protected void deployApps() {       
        deployUserApps();
    }

    @Override
    protected void deployApps(String name) {
        throw new UnsupportedOperationException
                ("deployApps(String) is not supported.");
    }

    /**
     * Deploy applications for all available users.
     */
    protected abstract void deployUserApps();

    /**
     * Deploy applications (if any) for specific user.
     *
     * @param user Username.
     * @param home User home directory.
     */
    protected void deployUserApps(String user, File home) {
        File base = new File(home, directoryName);

        if (!base.isDirectory() || !base.canRead()) {
            return;
        }

        String[] files = base.list();

        if (files == null) {
            log.warn("Error reading base directory: " + base.getPath() + ".");
            return;
        }

        // TODO: deployWars

        if (appsPerUser == 1) {
            // Single application mode.
            deployUserApp(user, base, "ROOT");
        } else {
            // Multiple applications mode.
            deployUserDirectories(user, base, files);
        }
    }

    /**
     * Deploy user application directories.
     *
     * @param user Username.
     * @param base Application base directory.
     * @param files Array of directories to deploy.
     */
    protected void deployUserDirectories(String user, File base, 
            String[] files) {

        int appsNum = files.length;

        if (appsNum > appsPerUser) {
            appsNum = appsPerUser;
        }

        for (int i = 0; i < appsNum; i++) {
            if (files[i].equalsIgnoreCase("META-INF")) {
                continue;
            }

            if (files[i].equalsIgnoreCase("WEB-INF")) {
                continue;
            }

            File dir = new File(base, files[i]);

            if (!dir.isDirectory() || !dir.canRead()) {
                continue;
            }

            deployUserApp(user, dir, files[i]);
        }
    }

    /**
     * Deploy user application.
     *
     * @param user Username.
     * @param dir Application directory.
     * @param app Application name.
     */
    protected void deployUserApp(String user, File dir, String app) {
        String contextPath;

        if (app.equals("ROOT")) {
            contextPath = "/~" + user;
        } else {
            contextPath = "/~" + user + '/' + app.replace('#', '/');
        }

        if (isServiced(contextPath)) {
            return;
        }

        deployDirectory(contextPath, dir, dir.getAbsolutePath());
    }
}