changeset 3:3ab011b6e6e8

Cleaner refactored version.
author Mikhail Kryshen <mikhail@kryshen.net>
date Fri, 30 Oct 2009 05:12:58 +0300
parents d11df03af52a
children 6ef7cbf5c8d6
files nbproject/build-impl.xml nbproject/genfiles.properties nbproject/project.properties src/kryshen/catalina/startup/HomesUserDatabase.java src/kryshen/catalina/startup/UserConfig.java src/kryshen/catalina/startup/UserConfig2.java src/kryshen/catalina/startup/UserDatabase.java
diffstat 7 files changed, 271 insertions(+), 224 deletions(-) [+]
line wrap: on
line diff
--- a/nbproject/build-impl.xml	Fri Oct 30 03:54:56 2009 +0300
+++ b/nbproject/build-impl.xml	Fri Oct 30 05:12:58 2009 +0300
@@ -20,6 +20,13 @@
 
         -->
 <project xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" basedir=".." default="default" name="tomcat-userconfig-impl">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
     <target depends="test,jar,javadoc" description="Build and test whole project." name="default"/>
     <!-- 
                 ======================
@@ -152,10 +159,18 @@
             <attribute default="${includes}" name="includes"/>
             <attribute default="${excludes}" name="excludes"/>
             <attribute default="${javac.debug}" name="debug"/>
-            <attribute default="/does/not/exist" name="sourcepath"/>
+            <attribute default="${empty.dir}" name="sourcepath"/>
+            <attribute default="${empty.dir}" name="gensrcdir"/>
             <element name="customize" optional="true"/>
             <sequential>
+                <property location="${build.dir}/empty" name="empty.dir"/>
+                <mkdir dir="${empty.dir}"/>
                 <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}">
+                    <src>
+                        <dirset dir="@{gensrcdir}" erroronmissingdir="false">
+                            <include name="*"/>
+                        </dirset>
+                    </src>
                     <classpath>
                         <path path="@{classpath}"/>
                     </classpath>
@@ -271,6 +286,8 @@
                 <java classname="@{classname}" dir="${work.dir}" fork="true">
                     <jvmarg line="${debug-args-line}"/>
                     <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
+                    <jvmarg value="-Dfile.encoding=${source.encoding}"/>
+                    <redirector errorencoding="${source.encoding}" inputencoding="${source.encoding}" outputencoding="${source.encoding}"/>
                     <jvmarg line="${run.jvmargs}"/>
                     <classpath>
                         <path path="@{classpath}"/>
@@ -287,12 +304,15 @@
     <target name="-init-macrodef-java">
         <macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">
             <attribute default="${main.class}" name="classname"/>
+            <attribute default="${run.classpath}" name="classpath"/>
             <element name="customize" optional="true"/>
             <sequential>
                 <java classname="@{classname}" dir="${work.dir}" fork="true">
+                    <jvmarg value="-Dfile.encoding=${source.encoding}"/>
+                    <redirector errorencoding="${source.encoding}" inputencoding="${source.encoding}" outputencoding="${source.encoding}"/>
                     <jvmarg line="${run.jvmargs}"/>
                     <classpath>
-                        <path path="${run.classpath}"/>
+                        <path path="@{classpath}"/>
                     </classpath>
                     <syspropertyset>
                         <propertyref prefix="run-sys-prop."/>
@@ -332,10 +352,15 @@
         <!-- You can override this target in the ../build.xml file. -->
     </target>
     <target if="do.depend.true" name="-compile-depend">
-        <j2seproject3:depend/>
+        <pathconvert property="build.generated.subdirs">
+            <dirset dir="${build.generated.sources.dir}" erroronmissingdir="false">
+                <include name="*"/>
+            </dirset>
+        </pathconvert>
+        <j2seproject3:depend srcdir="${src.dir}:${build.generated.subdirs}"/>
     </target>
     <target depends="init,deps-jar,-pre-pre-compile,-pre-compile,-compile-depend" if="have.sources" name="-do-compile">
-        <j2seproject3:javac/>
+        <j2seproject3:javac gensrcdir="${build.generated.sources.dir}"/>
         <copy todir="${build.classes.dir}">
             <fileset dir="${src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
         </copy>
@@ -352,7 +377,7 @@
     <target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
         <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
         <j2seproject3:force-recompile/>
-        <j2seproject3:javac excludes="" includes="${javac.includes}" sourcepath="${src.dir}"/>
+        <j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}" sourcepath="${src.dir}"/>
     </target>
     <target name="-post-compile-single">
         <!-- Empty placeholder for easier customization. -->
@@ -418,11 +443,29 @@
         <property location="${dist.jar}" name="dist.jar.resolved"/>
         <echo>java -jar "${dist.jar.resolved}"</echo>
     </target>
+    <target depends="init,compile,-pre-pre-jar,-pre-jar" if="libs.CopyLibs.classpath" name="-do-jar-with-libraries-without-manifest" unless="manifest.available+main.class">
+        <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
+        <pathconvert property="run.classpath.without.build.classes.dir">
+            <path path="${run.classpath}"/>
+            <map from="${build.classes.dir.resolved}" to=""/>
+        </pathconvert>
+        <pathconvert pathsep=" " property="jar.classpath">
+            <path path="${run.classpath.without.build.classes.dir}"/>
+            <chainedmapper>
+                <flattenmapper/>
+                <globmapper from="*" to="lib/*"/>
+            </chainedmapper>
+        </pathconvert>
+        <taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
+        <copylibs compress="${jar.compress}" jarfile="${dist.jar}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
+            <fileset dir="${build.classes.dir}"/>
+        </copylibs>
+    </target>
     <target name="-post-jar">
         <!-- Empty placeholder for easier customization. -->
         <!-- You can override this target in the ../build.xml file. -->
     </target>
-    <target depends="init,compile,-pre-jar,-do-jar-with-manifest,-do-jar-without-manifest,-do-jar-with-mainclass,-do-jar-with-libraries,-post-jar" description="Build JAR." name="jar"/>
+    <target depends="init,compile,-pre-jar,-do-jar-with-manifest,-do-jar-without-manifest,-do-jar-with-mainclass,-do-jar-with-libraries,-do-jar-with-libraries-without-manifest,-post-jar" description="Build JAR." name="jar"/>
     <!--
                 =================
                 EXECUTION SECTION
@@ -442,6 +485,10 @@
         <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
         <j2seproject1:java classname="${run.class}"/>
     </target>
+    <target depends="init,-do-not-recompile,compile-test-single" name="run-test-with-main">
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+        <j2seproject1:java classname="${run.class}" classpath="${run.test.classpath}"/>
+    </target>
     <!--
                 =================
                 DEBUGGING SECTION
@@ -450,6 +497,9 @@
     <target depends="init" if="netbeans.home" name="-debug-start-debugger">
         <j2seproject1:nbjpdastart name="${debug.class}"/>
     </target>
+    <target depends="init" if="netbeans.home" name="-debug-start-debugger-main-test">
+        <j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${debug.class}"/>
+    </target>
     <target depends="init,compile" name="-debug-start-debuggee">
         <j2seproject3:debug>
             <customize>
@@ -467,6 +517,11 @@
         <j2seproject3:debug classname="${debug.class}"/>
     </target>
     <target depends="init,-do-not-recompile,compile-single,-debug-start-debugger,-debug-start-debuggee-single" if="netbeans.home" name="debug-single"/>
+    <target depends="init,compile-test-single" if="netbeans.home" name="-debug-start-debuggee-main-test">
+        <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
+        <j2seproject3:debug classname="${debug.class}" classpath="${debug.test.classpath}"/>
+    </target>
+    <target depends="init,-do-not-recompile,compile-test-single,-debug-start-debugger-main-test,-debug-start-debuggee-main-test" if="netbeans.home" name="debug-test-with-main"/>
     <target depends="init" name="-pre-debug-fix">
         <fail unless="fix.includes">Must set fix.includes</fail>
         <property name="javac.includes" value="${fix.includes}.java"/>
@@ -489,6 +544,9 @@
             <fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
                 <filename name="**/*.java"/>
             </fileset>
+            <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
+                <include name="**/*.java"/>
+            </fileset>
         </javadoc>
     </target>
     <target depends="init,-javadoc-build" if="netbeans.home" name="-javadoc-browse" unless="no.javadoc.preview">
@@ -550,7 +608,7 @@
         <j2seproject3:junit testincludes="**/*Test.java"/>
     </target>
     <target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">
-        <fail if="tests.failed">Some tests failed; see details above.</fail>
+        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
     </target>
     <target depends="init" if="have.tests" name="test-report"/>
     <target depends="init" if="netbeans.home+have.tests" name="-test-browse"/>
@@ -563,7 +621,7 @@
         <j2seproject3:junit excludes="" includes="${test.includes}"/>
     </target>
     <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single">
-        <fail if="tests.failed">Some tests failed; see details above.</fail>
+        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
     </target>
     <target depends="init,-do-not-recompile,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>
     <!--
--- a/nbproject/genfiles.properties	Fri Oct 30 03:54:56 2009 +0300
+++ b/nbproject/genfiles.properties	Fri Oct 30 05:12:58 2009 +0300
@@ -1,8 +1,8 @@
 build.xml.data.CRC32=8168bf3c
 build.xml.script.CRC32=d8558c95
-build.xml.stylesheet.CRC32=958a1d3e
+build.xml.stylesheet.CRC32=958a1d3e@1.26.2.45
 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
 # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
 nbproject/build-impl.xml.data.CRC32=8168bf3c
-nbproject/build-impl.xml.script.CRC32=22b92b6d
-nbproject/build-impl.xml.stylesheet.CRC32=65b8de21
+nbproject/build-impl.xml.script.CRC32=92172d17
+nbproject/build-impl.xml.stylesheet.CRC32=5c621a33@1.26.2.45
--- a/nbproject/project.properties	Fri Oct 30 03:54:56 2009 +0300
+++ b/nbproject/project.properties	Fri Oct 30 05:12:58 2009 +0300
@@ -8,6 +8,7 @@
 # This directory is removed when the project is cleaned:
 build.dir=build
 build.generated.dir=${build.dir}/generated
+build.generated.sources.dir=${build.dir}/generated-sources
 # Only compile against the classpath explicitly listed here:
 build.sysclasspath=ignore
 build.test.classes.dir=${build.dir}/test/classes
@@ -71,6 +72,6 @@
     ${javac.test.classpath}:\
     ${build.test.classes.dir}
 source.encoding=UTF-8
-source.reference.catalina.jar=../../../misc/build/apache-tomcat-6.0.20-src/java
+source.reference.catalina.jar=${var.tomcat-src}/!/apache-tomcat-6.0.20-src/java/
 src.dir=src
 test.src.dir=test
--- a/src/kryshen/catalina/startup/HomesUserDatabase.java	Fri Oct 30 03:54:56 2009 +0300
+++ b/src/kryshen/catalina/startup/HomesUserDatabase.java	Fri Oct 30 05:12:58 2009 +0300
@@ -20,10 +20,9 @@
 
 
 import java.io.File;
-import java.util.Hashtable;
-import java.util.Enumeration;
-import org.apache.catalina.startup.*;
-
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * Concrete implementation of the <strong>UserDatabase</code> interface
@@ -31,33 +30,17 @@
  * to our constructor to be "home" directories for those users.
  *
  * @author Craig R. McClanahan
- * @version $Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (Tue, 24 Oct 2006) $
+ * @author Mikhail Kryshen
  */
 
-public final class HomesUserDatabase
-    implements UserDatabase {
-
-
-    // --------------------------------------------------------- Constructors
-
-
-    /**
-     * Initialize a new instance of this user database component.
-     */
-    public HomesUserDatabase() {
-
-        super();
-
-    }
-
+public final class HomesUserDatabase implements UserDatabase {
 
     // --------------------------------------------------- Instance Variables
 
-
     /**
      * The set of home directories for all defined users, keyed by username.
      */
-    private Hashtable homes = new Hashtable();
+    private Map<String, File> homes = new HashMap<String, File>();
 
 
     /**
@@ -73,9 +56,7 @@
      * Return the UserConfig listener with which we are associated.
      */
     public UserConfig getUserConfig() {
-
         return (this.userConfig);
-
     }
 
 
@@ -85,7 +66,6 @@
      * @param userConfig The new UserConfig listener
      */
     public void setUserConfig(UserConfig userConfig) {
-
         this.userConfig = userConfig;
         init();
 
@@ -100,23 +80,10 @@
      *
      * @param user User for which a home directory should be retrieved
      */
-    public String getHome(String user) {
-
-        return ((String) homes.get(user));
-
+    public File getHome(String user) {
+        return (homes.get(user));
     }
 
-
-    /**
-     * Return an enumeration of the usernames defined on this server.
-     */
-    public Enumeration getUsers() {
-
-        return (homes.keys());
-
-    }
-
-
     // ------------------------------------------------------ Private Methods
 
 
@@ -124,22 +91,27 @@
      * Initialize our set of users and home directories.
      */
     private void init() {
-
         String homeBase = userConfig.getHomeBase();
         File homeBaseDir = new File(homeBase);
-        if (!homeBaseDir.exists() || !homeBaseDir.isDirectory())
+
+        if (!homeBaseDir.exists() || !homeBaseDir.isDirectory()) {
             return;
+        }
+        
         String homeBaseFiles[] = homeBaseDir.list();
 
         for (int i = 0; i < homeBaseFiles.length; i++) {
             File homeDir = new File(homeBaseDir, homeBaseFiles[i]);
-            if (!homeDir.isDirectory() || !homeDir.canExecute())
+
+            if (!homeDir.isDirectory() || !homeDir.canExecute()) {
                 continue;
-            homes.put(homeBaseFiles[i], homeDir.toString());
+            }
+
+            homes.put(homeBaseFiles[i], homeDir);
         }
-
-
     }
 
-
+    public Map<String, File> getUserHomes() {
+        return Collections.unmodifiableMap(homes);
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/kryshen/catalina/startup/UserConfig.java	Fri Oct 30 05:12:58 2009 +0300
@@ -0,0 +1,152 @@
+package kryshen.catalina.startup;
+
+import java.io.File;
+import java.util.Map;
+import org.apache.catalina.startup.HostConfig;
+
+/**
+ *
+ * @author Mikhail Kryshen
+ */
+public class UserConfig extends HostConfig {
+
+    /**
+     * The directory name to be searched for within each user home directory.
+     */
+    private String directoryName = "public_webapps";
+
+    /**
+     * The base directory containing user home directories.
+     */
+    private String homeBase = null;
+
+    /**
+     * The Java class name of the user database class we should use.
+     */
+    private String userClass =
+            "org.apache.catalina.startup.PasswdUserDatabase";
+
+    /**
+     * Return the directory name for user web applications.
+     */
+    public String getDirectoryName() {
+        return (this.directoryName);
+    }
+
+    /**
+     * Set the directory name for user web applications.
+     *
+     * @param directoryName The new directory name
+     */
+    public void setDirectoryName(String directoryName) {
+        this.directoryName = directoryName;
+    }
+
+    /**
+     * Return the base directory containing user home directories.
+     */
+    public String getHomeBase() {
+        return (this.homeBase);
+    }
+
+    /**
+     * Set the base directory containing user home directories.
+     *
+     * @param homeBase The new base directory
+     */
+    public void setHomeBase(String homeBase) {
+        this.homeBase = homeBase;
+    }
+
+    /** 
+     * Return the user database class name for this component. 
+     */
+    public String getUserClass() {
+        return (this.userClass);
+    }
+
+    /** 
+     * Set the user database class name for this component. 
+     */
+    public void setUserClass(String userClass) {
+        this.userClass = userClass;
+    }
+
+    @Override
+    protected void deployApps() {       
+        // Load the user database object for this host
+        UserDatabase database = null;
+        try {
+            Class clazz = Class.forName(userClass);
+            database = (UserDatabase) clazz.newInstance();
+            database.setUserConfig(this);
+        } catch (Exception e) {
+            host.getLogger().error(sm.getString("userConfig.database"), e);
+            return;
+        }
+
+        // Deploy the web application (if any) for each defined user
+        Map<String, File> userHomes = database.getUserHomes();
+        for (Map.Entry<String, File> entry :userHomes.entrySet()) {
+            deployUserApps(entry.getKey(), entry.getValue());
+        }
+    }
+
+    @Override
+    protected void deployApps(String name) {
+        throw new UnsupportedOperationException
+                ("deployApps(String) is not supported.");
+    }
+
+    protected void deployUserApps(String user, File home) {
+        File base = new File(home, directoryName);
+
+        if (!base.exists() || !base.isDirectory()) {
+            return;
+        }
+
+// TODO: deployWARs
+//        // Deploy WARs, and loop if additional descriptors are found
+//        deployWARs(appBase, appBase.list());
+
+        // Deploy expanded folders
+        deployDirectories(user, base, base.list());
+    }
+
+    /**
+     * Deploy user webapp directories.
+     */
+    protected void deployDirectories(String user, File base, String[] files) {
+
+        if (files == null) {
+            return;
+        }
+
+        for (int i = 0; i < files.length; 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()) {
+                String contextPath;
+                
+                if (files[i].equals("ROOT")) {
+                    contextPath = "/~" + user;
+                } else {
+                    contextPath = "/~" + user + '/' + files[i].replace('#', '/');
+                }
+
+                if (isServiced(contextPath)) {
+                    continue;
+                }
+
+                deployDirectory(contextPath, dir, dir.getAbsolutePath());
+            }
+        }
+    }
+}
--- a/src/kryshen/catalina/startup/UserConfig2.java	Fri Oct 30 03:54:56 2009 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,164 +0,0 @@
-package kryshen.catalina.startup;
-
-import java.io.File;
-import java.util.Enumeration;
-import org.apache.catalina.startup.UserDatabase;
-import org.apache.catalina.startup.HostConfig;
-import org.apache.catalina.startup.UserConfig;
-
-/**
- *
- * @author Mikhail Kryshen
- */
-public class UserConfig2 extends HostConfig {
-
-    /**
-     * The directory name to be searched for within each user home directory.
-     */
-    private String directoryName = "public_webapps";
-
-    /**
-     * The base directory containing user home directories.
-     */
-    private String homeBase = null;
-
-    /**
-     * The Java class name of the user database class we should use.
-     */
-    private String userClass =
-            "org.apache.catalina.startup.PasswdUserDatabase";
-
-    /**
-     * UserConfig instance is required by UserDatabase.
-     */
-    private UserConfig userConfig = new UserConfig();
-
-    /**
-     * Return the directory name for user web applications.
-     */
-    public String getDirectoryName() {
-        return (this.directoryName);
-    }
-
-    /**
-     * Set the directory name for user web applications.
-     *
-     * @param directoryName The new directory name
-     */
-    public void setDirectoryName(String directoryName) {
-        this.directoryName = directoryName;
-        userConfig.setDirectoryName(directoryName);
-    }
-
-    /**
-     * Return the base directory containing user home directories.
-     */
-    public String getHomeBase() {
-        return (this.homeBase);
-    }
-
-    /**
-     * Set the base directory containing user home directories.
-     *
-     * @param homeBase The new base directory
-     */
-    public void setHomeBase(String homeBase) {
-        this.homeBase = homeBase;
-        userConfig.setHomeBase(homeBase);
-    }
-
-    /** 
-     * Return the user database class name for this component. 
-     */
-    public String getUserClass() {
-        return (this.userClass);
-    }
-
-    /** 
-     * Set the user database class name for this component. 
-     */
-    public void setUserClass(String userClass) {
-        this.userClass = userClass;
-        userConfig.setUserClass(userClass);
-    }
-
-    @Override
-    protected void deployApps() {       
-        // Load the user database object for this host
-        UserDatabase database = null;
-        try {
-            Class clazz = Class.forName(userClass);
-            database = (UserDatabase) clazz.newInstance();
-            database.setUserConfig(userConfig);
-        } catch (Exception e) {
-            host.getLogger().error(sm.getString("userConfig.database"), e);
-            return;
-        }
-
-        // Deploy the web application (if any) for each defined user
-        Enumeration users = database.getUsers();
-        while (users.hasMoreElements()) {
-            String user = (String) users.nextElement();
-            String home = database.getHome(user);
-            deployUserApps(user, home);
-        }
-    }
-
-    @Override
-    protected void deployApps(String name) {
-        throw new UnsupportedOperationException
-                ("deployApps(String) is not supported.");
-    }
-
-    protected void deployUserApps(String user, String home) {
-        File base = new File(home, directoryName);
-
-        if (!base.exists() || !base.isDirectory()) {
-            return;
-        }
-
-// TODO: deployWARs
-//        // Deploy WARs, and loop if additional descriptors are found
-//        deployWARs(appBase, appBase.list());
-
-        // Deploy expanded folders
-        deployDirectories(user, base, base.list());
-    }
-
-    /**
-     * Deploy user webapp directories.
-     */
-    protected void deployDirectories(String user, File base, String[] files) {
-
-        if (files == null) {
-            return;
-        }
-
-        for (int i = 0; i < files.length; 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()) {
-                String contextPath;
-                
-                if (files[i].equals("ROOT")) {
-                    contextPath = "/~" + user;
-                } else {
-                    contextPath = "/~" + user + '/' + files[i].replace('#', '/');
-                }
-
-                if (isServiced(contextPath)) {
-                    continue;
-                }
-
-                deployDirectory(contextPath, dir, dir.getAbsolutePath());
-            }
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/kryshen/catalina/startup/UserDatabase.java	Fri Oct 30 05:12:58 2009 +0300
@@ -0,0 +1,28 @@
+package kryshen.catalina.startup;
+
+import java.io.File;
+import java.util.Map;
+
+/**
+ *
+ * @author Mikhail Kryshen
+ */
+public interface UserDatabase {
+
+    /**
+     * Return the UserConfig listener with which we are associated.
+     */
+    public UserConfig getUserConfig();
+
+    /**
+     * Set the UserConfig listener with which we are associated.
+     *
+     * @param userConfig The new UserConfig listener
+     */
+    public void setUserConfig(UserConfig userConfig);
+
+    /**
+     * Return mapping between usernames and homes.
+     */
+     Map<String, File> getUserHomes();
+}