Author: sai
Date: Tue Apr  6 12:09:53 2010
New Revision: 931110

URL: http://svn.apache.org/viewvc?rev=931110&view=rev
Log:
Implemented JIRA issue FTPSERVER-362

Modified:
    
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ConnectionConfig.java
    
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ConnectionConfigFactory.java
    
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/config/spring/ServerBeanDefinitionParser.java
    
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/DefaultConnectionConfig.java
    
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpServerContext.java
    
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/FtpServerContext.java
    
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/listener/nio/NioListener.java
    
mina/ftpserver/trunk/core/src/main/resources/org/apache/ftpserver/config/spring/ftpserver-1.0.xsd

Modified: 
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ConnectionConfig.java
URL: 
http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ConnectionConfig.java?rev=931110&r1=931109&r2=931110&view=diff
==============================================================================
--- 
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ConnectionConfig.java
 (original)
+++ 
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ConnectionConfig.java
 Tue Apr  6 12:09:53 2010
@@ -59,4 +59,13 @@ public interface ConnectionConfig {
      * @return true if anonymous logins are enabled
      */
     boolean isAnonymousLoginEnabled();
+    
+    /**
+     * Returns the maximum number of threads the server is allowed to create 
for
+     * processing client requests.
+     * 
+     * @return the maximum number of threads the server is allowed to create 
for
+     *         processing client requests.
+     */
+    int getMaxThreads();
 }

Modified: 
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ConnectionConfigFactory.java
URL: 
http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ConnectionConfigFactory.java?rev=931110&r1=931109&r2=931110&view=diff
==============================================================================
--- 
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ConnectionConfigFactory.java
 (original)
+++ 
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ConnectionConfigFactory.java
 Tue Apr  6 12:09:53 2010
@@ -39,6 +39,8 @@ public class ConnectionConfigFactory {
 
     private int loginFailureDelay = 500;
 
+    private int maxThreads = 0;
+
     /**
      * Create a connection configuration instances based on the configuration 
on this factory
      * @return The {...@link ConnectionConfig} instance
@@ -46,9 +48,9 @@ public class ConnectionConfigFactory {
     public ConnectionConfig createConnectionConfig() {
         return new DefaultConnectionConfig(anonymousLoginEnabled,
                 loginFailureDelay, maxLogins, maxAnonymousLogins,
-                maxLoginFailures);
+                maxLoginFailures, maxThreads);
     }
-    
+
     /**
      * The delay in number of milliseconds between login failures. Important 
to 
      * make brute force attacks harder.
@@ -101,6 +103,29 @@ public class ConnectionConfigFactory {
     }
 
     /**
+     * Returns the maximum number of threads the server is allowed to create 
for
+     * processing client requests.
+     * 
+     * @return the maximum number of threads the server is allowed to create 
for
+     *         processing client requests.
+     */
+    public int getMaxThreads() {
+        return maxThreads;
+    }
+
+    /**
+     * Sets the maximum number of threads the server is allowed to create for
+     * processing client requests.
+     * 
+     * @param maxThreads
+     *            the maximum number of threads the server is allowed to create
+     *            for processing client requests.
+     */
+    public void setMaxThreads(int maxThreads) {
+        this.maxThreads = maxThreads;
+    }
+
+    /**
      * Set if anonymous logins are allowed at the server
      * @param anonymousLoginEnabled true if anonymous logins should be enabled
      */

Modified: 
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/config/spring/ServerBeanDefinitionParser.java
URL: 
http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/config/spring/ServerBeanDefinitionParser.java?rev=931110&r1=931109&r2=931110&view=diff
==============================================================================
--- 
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/config/spring/ServerBeanDefinitionParser.java
 (original)
+++ 
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/config/spring/ServerBeanDefinitionParser.java
 Tue Apr  6 12:09:53 2010
@@ -118,6 +118,10 @@ public class ServerBeanDefinitionParser 
             connectionConfig.setMaxLogins(SpringUtil.parseInt(element,
                     "max-logins"));
         }
+        if (StringUtils.hasText(element.getAttribute("max-threads"))) {
+            connectionConfig.setMaxThreads(SpringUtil.parseInt(element,
+                    "max-threads"));
+        }
         if (StringUtils.hasText(element.getAttribute("max-anon-logins"))) {
             connectionConfig.setMaxAnonymousLogins(SpringUtil.parseInt(element,
                     "max-anon-logins"));

Modified: 
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/DefaultConnectionConfig.java
URL: 
http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/DefaultConnectionConfig.java?rev=931110&r1=931109&r2=931110&view=diff
==============================================================================
--- 
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/DefaultConnectionConfig.java
 (original)
+++ 
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/DefaultConnectionConfig.java
 Tue Apr  6 12:09:53 2010
@@ -39,18 +39,21 @@ public class DefaultConnectionConfig imp
     private int maxLoginFailures = 3;
 
     private int loginFailureDelay = 500;
+    
+    private int maxThreads = 0;
 
     /**
      * Internal constructor, do not use directly. Use {...@link 
ConnectionConfigFactory} instead
      */
     public DefaultConnectionConfig(boolean anonymousLoginEnabled,
             int loginFailureDelay, int maxLogins, int maxAnonymousLogins,
-            int maxLoginFailures) {
+            int maxLoginFailures, int maxThreads) {
         this.anonymousLoginEnabled = anonymousLoginEnabled;
         this.loginFailureDelay = loginFailureDelay;
         this.maxLogins = maxLogins;
         this.maxAnonymousLogins = maxAnonymousLogins;
         this.maxLoginFailures = maxLoginFailures;
+        this.maxThreads = maxThreads;
     }
 
     public int getLoginFailureDelay() {
@@ -72,5 +75,9 @@ public class DefaultConnectionConfig imp
     public boolean isAnonymousLoginEnabled() {
         return anonymousLoginEnabled;
     }
-
+    
+    public int getMaxThreads() {
+        return maxThreads;
+    }
+    
 }

Modified: 
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpServerContext.java
URL: 
http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpServerContext.java?rev=931110&r1=931109&r2=931110&view=diff
==============================================================================
--- 
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpServerContext.java
 (original)
+++ 
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpServerContext.java
 Tue Apr  6 12:09:53 2010
@@ -23,6 +23,8 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
 
 import org.apache.ftpserver.ConnectionConfig;
 import org.apache.ftpserver.ConnectionConfigFactory;
@@ -45,6 +47,7 @@ import org.apache.ftpserver.usermanager.
 import org.apache.ftpserver.usermanager.impl.ConcurrentLoginPermission;
 import org.apache.ftpserver.usermanager.impl.TransferRatePermission;
 import org.apache.ftpserver.usermanager.impl.WritePermission;
+import org.apache.mina.filter.executor.OrderedThreadPoolExecutor;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -78,6 +81,12 @@ public class DefaultFtpServerContext imp
 
     private static final List<Authority> ADMIN_AUTHORITIES = new 
ArrayList<Authority>();
     private static final List<Authority> ANON_AUTHORITIES = new 
ArrayList<Authority>();
+    
+    /**
+     * The thread pool executor to be used by the server using this context
+     */
+    private ThreadPoolExecutor threadPoolExecutor = null;
+    
     static {
         ADMIN_AUTHORITIES.add(new WritePermission());
         
@@ -189,6 +198,16 @@ public class DefaultFtpServerContext imp
     public void dispose() {
         listeners.clear();
         ftpletContainer.getFtplets().clear();
+        if (threadPoolExecutor != null) {
+            LOG.debug("Shutting down the thread pool executor");
+            threadPoolExecutor.shutdown();
+            try {
+                threadPoolExecutor.awaitTermination(5000, 
TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+            } finally {
+                // TODO: how to handle?
+            }
+        }
     }
 
     public Listener getListener(String name) {
@@ -242,4 +261,22 @@ public class DefaultFtpServerContext imp
     public void setConnectionConfig(ConnectionConfig connectionConfig) {
         this.connectionConfig = connectionConfig;
     }
+    
+    public synchronized ThreadPoolExecutor getThreadPoolExecutor() {
+        if(threadPoolExecutor == null) {
+            int maxThreads = connectionConfig.getMaxThreads();
+            if(maxThreads < 1) {
+                int maxLogins = connectionConfig.getMaxLogins();
+                if(maxLogins > 0) {
+                    maxThreads = maxLogins;
+                }
+                else {
+                    maxThreads = 16;
+                }
+            }
+            LOG.debug("Intializing shared thread pool executor with max 
threads of {}", maxThreads);
+            threadPoolExecutor = new OrderedThreadPoolExecutor(maxThreads);
+        }
+        return threadPoolExecutor;
+    }
 }

Modified: 
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/FtpServerContext.java
URL: 
http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/FtpServerContext.java?rev=931110&r1=931109&r2=931110&view=diff
==============================================================================
--- 
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/FtpServerContext.java
 (original)
+++ 
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/FtpServerContext.java
 Tue Apr  6 12:09:53 2010
@@ -20,6 +20,7 @@
 package org.apache.ftpserver.impl;
 
 import java.util.Map;
+import java.util.concurrent.ThreadPoolExecutor;
 
 import org.apache.ftpserver.ConnectionConfig;
 import org.apache.ftpserver.command.CommandFactory;
@@ -63,4 +64,10 @@ public interface FtpServerContext extend
      * Release all components.
      */
     void dispose();
+    
+    /**
+     * Returns the thread pool executor for this context.  
+     * @return the thread pool executor for this context.
+     */
+    ThreadPoolExecutor getThreadPoolExecutor();
 }

Modified: 
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/listener/nio/NioListener.java
URL: 
http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/listener/nio/NioListener.java?rev=931110&r1=931109&r2=931110&view=diff
==============================================================================
--- 
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/listener/nio/NioListener.java
 (original)
+++ 
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/listener/nio/NioListener.java
 Tue Apr  6 12:09:53 2010
@@ -23,7 +23,6 @@ import java.io.IOException;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.security.GeneralSecurityException;
-import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -48,7 +47,6 @@ import org.apache.mina.core.session.IoSe
 import org.apache.mina.filter.codec.ProtocolCodecFilter;
 import org.apache.mina.filter.executor.ExecutorFilter;
 import org.apache.mina.filter.executor.OrderedThreadPoolExecutor;
-import org.apache.mina.filter.firewall.BlacklistFilter;
 import org.apache.mina.filter.firewall.Subnet;
 import org.apache.mina.filter.logging.MdcInjectionFilter;
 import org.apache.mina.filter.ssl.SslFilter;
@@ -75,8 +73,6 @@ public class NioListener extends Abstrac
 
     boolean suspended = false;
 
-    private ExecutorService filterExecutor = new OrderedThreadPoolExecutor();
-
     private FtpHandler handler = new DefaultFtpHandler();
 
     private FtpServerContext context;
@@ -143,7 +139,7 @@ public class NioListener extends Abstrac
             }
     
             acceptor.getFilterChain().addLast("threadPool",
-                    new ExecutorFilter(filterExecutor));
+                    new ExecutorFilter(context.getThreadPoolExecutor()));
             acceptor.getFilterChain().addLast("codec",
                     new ProtocolCodecFilter(new 
FtpServerProtocolCodecFactory()));
             acceptor.getFilterChain().addLast("mdcFilter2", mdcFilter);
@@ -205,17 +201,6 @@ public class NioListener extends Abstrac
             acceptor.dispose();
             acceptor = null;
         }
-
-        if (filterExecutor != null) {
-            filterExecutor.shutdown();
-            try {
-                filterExecutor.awaitTermination(5000, TimeUnit.MILLISECONDS);
-            } catch (InterruptedException e) {
-            } finally {
-                // TODO: how to handle?
-            }
-        }
-        
         context = null;
     }
 

Modified: 
mina/ftpserver/trunk/core/src/main/resources/org/apache/ftpserver/config/spring/ftpserver-1.0.xsd
URL: 
http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/main/resources/org/apache/ftpserver/config/spring/ftpserver-1.0.xsd?rev=931110&r1=931109&r2=931110&view=diff
==============================================================================
--- 
mina/ftpserver/trunk/core/src/main/resources/org/apache/ftpserver/config/spring/ftpserver-1.0.xsd
 (original)
+++ 
mina/ftpserver/trunk/core/src/main/resources/org/apache/ftpserver/config/spring/ftpserver-1.0.xsd
 Tue Apr  6 12:09:53 2010
@@ -1,290 +1,291 @@
-<?xml version="1.0" encoding="UTF-8"?>
-       <!--
-               Licensed to the Apache Software Foundation (ASF) under one or 
more
-               contributor license agreements. See the NOTICE file distributed 
with
-               this work for additional information regarding copyright 
ownership.
-               The ASF licenses this file to you 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.
-       -->
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema";
-       elementFormDefault="qualified" 
targetNamespace="http://mina.apache.org/ftpserver/spring/v1";
-       xmlns="http://mina.apache.org/ftpserver/spring/v1"; 
xmlns:beans="http://www.springframework.org/schema/beans";>
-
-       <!-- Import the Spring beans XML schema -->
-       <xs:import namespace="http://www.springframework.org/schema/beans";
-               
schemaLocation="http://www.springframework.org/schema/beans/spring-beans-2.5.xsd";
 />
-
-       <!-- The main entry point, used for setting up an entire FTP server -->
-       <xs:element name="server">
-               <xs:complexType>
-                       <xs:sequence>
-                               <xs:element minOccurs="0" name="listeners">
-                                       <xs:complexType>
-                                               <xs:choice minOccurs="1" 
maxOccurs="unbounded">
-                                                       <xs:element 
ref="nio-listener" />
-                                                       <xs:element 
ref="listener" />
-                                               </xs:choice>
-                                       </xs:complexType>
-                               </xs:element>
-                               <xs:element minOccurs="0" ref="ftplets" />
-                               <xs:choice minOccurs="0" maxOccurs="1">
-                                       <xs:element minOccurs="0" 
ref="file-user-manager" />
-                                       <xs:element minOccurs="0" 
ref="db-user-manager" />
-                                       <xs:element minOccurs="0" 
ref="user-manager" />
-                               </xs:choice>
-                               <xs:choice minOccurs="0" maxOccurs="1">
-                                       <xs:element minOccurs="0" 
ref="native-filesystem" />
-                                       <xs:element minOccurs="0" 
ref="filesystem" />
-                               </xs:choice>
-                               <xs:element minOccurs="0" ref="commands" />
-                               <xs:element minOccurs="0" ref="messages" />
-                       </xs:sequence>
-                       <xs:attribute name="id" type="xs:ID" />
-                       <xs:attribute name="max-logins" type="xs:int" />
-                       <xs:attribute name="max-anon-logins" type="xs:int" />
-                       <xs:attribute name="anon-enabled" type="xs:boolean" />
-                       <xs:attribute name="max-login-failures" type="xs:int" />
-                       <xs:attribute name="login-failure-delay" type="xs:int" 
/>
-               </xs:complexType>
-       </xs:element>
-
-       <!-- Reusable element for defining SSL properties -->
-       <xs:element name="ssl">
-               <xs:complexType>
-                       <xs:sequence>
-                               <xs:element name="keystore">
-                                       <xs:complexType>
-                                               <xs:attribute name="file" 
use="required" />
-                                               <xs:attribute name="password" 
use="required" />
-                                               <xs:attribute name="type" />
-                                               <xs:attribute name="algorithm" 
/>
-                                               <xs:attribute name="key-alias" 
/>
-                                               <xs:attribute 
name="key-password" />
-                                       </xs:complexType>
-                               </xs:element>
-                               <xs:element minOccurs="0" name="truststore">
-                                       <xs:complexType>
-                                               <xs:attribute name="file" 
use="required" />
-                                               <xs:attribute name="password" />
-                                               <xs:attribute name="type" />
-                                               <xs:attribute name="algorithm" 
/>
-                                       </xs:complexType>
-                               </xs:element>
-                       </xs:sequence>
-                       <xs:attribute name="client-authentication">
-                               <xs:simpleType>
-                                       <xs:restriction base="xs:string">
-                                               <xs:enumeration value="NEED" />
-                                               <xs:enumeration value="WANT" />
-                                               <xs:enumeration value="NONE" />
-                                       </xs:restriction>
-                               </xs:simpleType>
-                       </xs:attribute>
-                       <xs:attribute name="enabled-ciphersuites" 
type="xs:string" />
-                       <xs:attribute name="protocol">
-                               <xs:simpleType>
-                                       <xs:restriction base="xs:string">
-                                               <xs:enumeration value="SSL" />
-                                               <xs:enumeration value="TLS" />
-                                       </xs:restriction>
-                               </xs:simpleType>
-                       </xs:attribute>
-               </xs:complexType>
-       </xs:element>
-
-       <!-- Element used to configure the IP Filtering -->
-       <xs:element name="ip-filter">
-               <xs:complexType>
-                       <xs:simpleContent>
-                               <xs:extension base="xs:string">
-                                       <xs:attribute name="type">
-                                               <xs:simpleType>
-                                                       <xs:restriction 
base="xs:string">
-                                                               <xs:enumeration 
value="allow" />
-                                                               <xs:enumeration 
value="deny" />
-                                                       </xs:restriction>
-                                               </xs:simpleType>
-                                       </xs:attribute>
-                               </xs:extension>
-                       </xs:simpleContent>
-               </xs:complexType>
-       </xs:element>
-
-       <!-- Element used to define the default, NIO based listener -->
-       <xs:element name="nio-listener">
-               <xs:complexType>
-                       <xs:sequence>
-                               <xs:element minOccurs="0" ref="ssl" />
-                               <xs:element minOccurs="0" 
name="data-connection">
-                                       <xs:complexType>
-                                               <xs:sequence>
-                                                       <xs:element 
minOccurs="0" ref="ssl" />
-                                                       <xs:element 
minOccurs="0" name="active">
-                                                               <xs:complexType>
-                                                                       
<xs:attribute name="enabled" type="xs:boolean" />
-                                                                       
<xs:attribute name="local-address" />
-                                                                       
<xs:attribute name="local-port" type="xs:int" />
-                                                                       
<xs:attribute name="ip-check" type="xs:boolean" />
-                                                               
</xs:complexType>
-                                                       </xs:element>
-                                                       <xs:element 
minOccurs="0" name="passive">
-                                                               <xs:complexType>
-                                                                       
<xs:attribute name="address" />
-                                                                       
<xs:attribute name="external-address" />
-                                                                       
<xs:attribute name="ip-check" type="xs:boolean" />
-                                                                       
<xs:attribute name="ports" />
-                                                               
</xs:complexType>
-                                                       </xs:element>
-                                               </xs:sequence>
-                                               <xs:attribute 
name="idle-timeout" type="xs:int" />
-                        <xs:attribute name="implicit-ssl" type="xs:boolean" />
-                                       </xs:complexType>
-                               </xs:element>
-                               <xs:element minOccurs="0" name="blacklist" 
type="xs:string" />
-                               <xs:element ref="ip-filter" minOccurs="0" 
maxOccurs="1" />
-                       </xs:sequence>
-                       <xs:attribute name="name" use="required" 
type="xs:string" />
-                       <xs:attribute name="local-address" />
-                       <xs:attribute name="port" type="xs:int" />
-                       <xs:attribute name="idle-timeout" type="xs:int" />
-                       <xs:attribute name="implicit-ssl" type="xs:boolean" />
-               </xs:complexType>
-       </xs:element>
-       
-       <!-- Extension element used for defining a custom listener -->
-       <xs:element name="listener" type="spring-bean-or-ref-with-name" />
-
-       <!-- Element used to configure Ftplets for used with the server -->
-       <xs:element name="ftplets">
-               <xs:complexType>
-                       <xs:choice>
-                               <xs:element name="ftplet" maxOccurs="unbounded">
-                                       <xs:complexType>
-                                               <xs:sequence>
-                                                       <xs:choice>
-                                                               <xs:element 
ref="beans:bean" />
-                                                               <xs:element 
ref="beans:ref" />
-                                                       </xs:choice>
-                                               </xs:sequence>
-                                               <xs:attribute name="name" 
use="required" type="xs:string" />
-                                       </xs:complexType>
-                               </xs:element>
-                               <xs:element ref="beans:map" />
-                       </xs:choice>
-               </xs:complexType>
-       </xs:element>
-
-       <!-- Element used to configure a file based user manager -->
-       <xs:element name="file-user-manager">
-               <xs:complexType>
-                       <xs:attribute name="file" type="xs:string" />
-                       <xs:attribute name="url" type="xs:string" />
-                       <xs:attribute name="encrypt-passwords">
-                               <xs:simpleType>
-                                       <xs:restriction base="xs:string">
-                                               <xs:enumeration 
value="clear"></xs:enumeration>
-                                               <!-- Deprecated, use "clear" -->
-                                               <xs:enumeration 
value="false"></xs:enumeration>
-                                               <xs:enumeration 
value="md5"></xs:enumeration>
-                                               <!-- Deprecated, use "md5" -->
-                                               <xs:enumeration 
value="true"></xs:enumeration>
-                                               <xs:enumeration 
value="salted"></xs:enumeration>
-                                       </xs:restriction>
-                               </xs:simpleType>
-                       </xs:attribute>
-               </xs:complexType>
-       </xs:element>
-       
-       <!-- Element used to configure a database based user manager -->
-       <xs:element name="db-user-manager">
-               <xs:complexType>
-               <xs:sequence>
-                               <xs:element name="data-source" 
type="spring-bean-or-ref" />
-                               <xs:element name="insert-user" type="xs:string" 
/>
-                               <xs:element name="update-user" type="xs:string" 
/>
-                               <xs:element name="delete-user" type="xs:string" 
/>
-                               <xs:element name="select-user" type="xs:string" 
/>
-                               <xs:element name="select-all-users" 
type="xs:string" />
-                               <xs:element name="is-admin" type="xs:string" />
-                               <xs:element name="authenticate" 
type="xs:string" />
-                       </xs:sequence>
-            <xs:attribute name="encrypt-passwords">
-                <xs:simpleType>
-                    <xs:restriction base="xs:string">
-                        <xs:enumeration value="clear"></xs:enumeration>
-                        <xs:enumeration value="md5"></xs:enumeration>
-                        <xs:enumeration value="salted"></xs:enumeration>
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-               </xs:complexType>
-       </xs:element>
-
-       <!-- Extension element used for defining a custom user manager -->
-       <xs:element name="user-manager" type="spring-bean-or-ref" />
-
-       <!-- Element used to configure the default file system -->
-       <xs:element name="native-filesystem">
-               <xs:complexType>
-                       <xs:attribute name="case-insensitive" type="xs:boolean" 
/>
-                       <xs:attribute name="create-home" type="xs:boolean" />
-               </xs:complexType>
-       </xs:element>
-
-       <!-- Extension element used for defining a custom file system -->
-       <xs:element name="filesystem" type="spring-bean-or-ref" />
-
-       <!-- Element used to provide custom command implementations -->
-       <xs:element name="commands">
-               <xs:complexType>
-                       <xs:sequence>
-                               <xs:element name="command" 
maxOccurs="unbounded">
-                                       <xs:complexType>
-                                               <xs:sequence>
-                                                       <xs:choice 
maxOccurs="unbounded">
-                                                               <xs:element 
ref="beans:bean" />
-                                                               <xs:element 
ref="beans:ref" />
-                                                       </xs:choice>
-                                               </xs:sequence>
-                                               <xs:attribute name="name" 
use="required" />
-                                       </xs:complexType>
-                               </xs:element>
-                       </xs:sequence>
-                       <xs:attribute name="use-default" type="xs:boolean" />
-               </xs:complexType>
-       </xs:element>
-       
-       <!-- Element used to configure and localize messages -->
-       <xs:element name="messages">
-               <xs:complexType>
-                       <xs:attribute name="languages" />
-                       <xs:attribute name="directory" />
-               </xs:complexType>
-       </xs:element>
-
-       <!-- Reusable type used for extension elements -->
-       <xs:complexType name="spring-bean-or-ref">
-               <xs:choice>
-                       <xs:element ref="beans:bean" />
-                       <xs:element ref="beans:ref" />
-               </xs:choice>
-       </xs:complexType>
-       
-       <!-- Reusable type used for named extension elements -->
-       <xs:complexType name="spring-bean-or-ref-with-name">
-               <xs:sequence>
-                       <xs:choice>
-                               <xs:element ref="beans:bean" />
-                               <xs:element ref="beans:ref" />
-                       </xs:choice>
-               </xs:sequence>
-               <xs:attribute name="name" use="required" type="xs:string" />
-       </xs:complexType>
+<?xml version="1.0" encoding="UTF-8"?>
+       <!--
+               Licensed to the Apache Software Foundation (ASF) under one or 
more
+               contributor license agreements. See the NOTICE file distributed 
with
+               this work for additional information regarding copyright 
ownership.
+               The ASF licenses this file to you 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.
+       -->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema";
+       elementFormDefault="qualified" 
targetNamespace="http://mina.apache.org/ftpserver/spring/v1";
+       xmlns="http://mina.apache.org/ftpserver/spring/v1"; 
xmlns:beans="http://www.springframework.org/schema/beans";>
+
+       <!-- Import the Spring beans XML schema -->
+       <xs:import namespace="http://www.springframework.org/schema/beans";
+               
schemaLocation="http://www.springframework.org/schema/beans/spring-beans-2.5.xsd";
 />
+
+       <!-- The main entry point, used for setting up an entire FTP server -->
+       <xs:element name="server">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element minOccurs="0" name="listeners">
+                                       <xs:complexType>
+                                               <xs:choice minOccurs="1" 
maxOccurs="unbounded">
+                                                       <xs:element 
ref="nio-listener" />
+                                                       <xs:element 
ref="listener" />
+                                               </xs:choice>
+                                       </xs:complexType>
+                               </xs:element>
+                               <xs:element minOccurs="0" ref="ftplets" />
+                               <xs:choice minOccurs="0" maxOccurs="1">
+                                       <xs:element minOccurs="0" 
ref="file-user-manager" />
+                                       <xs:element minOccurs="0" 
ref="db-user-manager" />
+                                       <xs:element minOccurs="0" 
ref="user-manager" />
+                               </xs:choice>
+                               <xs:choice minOccurs="0" maxOccurs="1">
+                                       <xs:element minOccurs="0" 
ref="native-filesystem" />
+                                       <xs:element minOccurs="0" 
ref="filesystem" />
+                               </xs:choice>
+                               <xs:element minOccurs="0" ref="commands" />
+                               <xs:element minOccurs="0" ref="messages" />
+                       </xs:sequence>
+                       <xs:attribute name="id" type="xs:ID" />
+                       <xs:attribute name="max-logins" type="xs:int" />
+                       <xs:attribute name="max-anon-logins" type="xs:int" />
+                       <xs:attribute name="anon-enabled" type="xs:boolean" />
+                       <xs:attribute name="max-login-failures" type="xs:int" />
+                       <xs:attribute name="login-failure-delay" type="xs:int" 
/>
+                       <xs:attribute name="max-threads" type="xs:int" />
+               </xs:complexType>
+       </xs:element>
+
+       <!-- Reusable element for defining SSL properties -->
+       <xs:element name="ssl">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="keystore">
+                                       <xs:complexType>
+                                               <xs:attribute name="file" 
use="required" />
+                                               <xs:attribute name="password" 
use="required" />
+                                               <xs:attribute name="type" />
+                                               <xs:attribute name="algorithm" 
/>
+                                               <xs:attribute name="key-alias" 
/>
+                                               <xs:attribute 
name="key-password" />
+                                       </xs:complexType>
+                               </xs:element>
+                               <xs:element minOccurs="0" name="truststore">
+                                       <xs:complexType>
+                                               <xs:attribute name="file" 
use="required" />
+                                               <xs:attribute name="password" />
+                                               <xs:attribute name="type" />
+                                               <xs:attribute name="algorithm" 
/>
+                                       </xs:complexType>
+                               </xs:element>
+                       </xs:sequence>
+                       <xs:attribute name="client-authentication">
+                               <xs:simpleType>
+                                       <xs:restriction base="xs:string">
+                                               <xs:enumeration value="NEED" />
+                                               <xs:enumeration value="WANT" />
+                                               <xs:enumeration value="NONE" />
+                                       </xs:restriction>
+                               </xs:simpleType>
+                       </xs:attribute>
+                       <xs:attribute name="enabled-ciphersuites" 
type="xs:string" />
+                       <xs:attribute name="protocol">
+                               <xs:simpleType>
+                                       <xs:restriction base="xs:string">
+                                               <xs:enumeration value="SSL" />
+                                               <xs:enumeration value="TLS" />
+                                       </xs:restriction>
+                               </xs:simpleType>
+                       </xs:attribute>
+               </xs:complexType>
+       </xs:element>
+
+       <!-- Element used to configure the IP Filtering -->
+       <xs:element name="ip-filter">
+               <xs:complexType>
+                       <xs:simpleContent>
+                               <xs:extension base="xs:string">
+                                       <xs:attribute name="type">
+                                               <xs:simpleType>
+                                                       <xs:restriction 
base="xs:string">
+                                                               <xs:enumeration 
value="allow" />
+                                                               <xs:enumeration 
value="deny" />
+                                                       </xs:restriction>
+                                               </xs:simpleType>
+                                       </xs:attribute>
+                               </xs:extension>
+                       </xs:simpleContent>
+               </xs:complexType>
+       </xs:element>
+
+       <!-- Element used to define the default, NIO based listener -->
+       <xs:element name="nio-listener">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element minOccurs="0" ref="ssl" />
+                               <xs:element minOccurs="0" 
name="data-connection">
+                                       <xs:complexType>
+                                               <xs:sequence>
+                                                       <xs:element 
minOccurs="0" ref="ssl" />
+                                                       <xs:element 
minOccurs="0" name="active">
+                                                               <xs:complexType>
+                                                                       
<xs:attribute name="enabled" type="xs:boolean" />
+                                                                       
<xs:attribute name="local-address" />
+                                                                       
<xs:attribute name="local-port" type="xs:int" />
+                                                                       
<xs:attribute name="ip-check" type="xs:boolean" />
+                                                               
</xs:complexType>
+                                                       </xs:element>
+                                                       <xs:element 
minOccurs="0" name="passive">
+                                                               <xs:complexType>
+                                                                       
<xs:attribute name="address" />
+                                                                       
<xs:attribute name="external-address" />
+                                                                       
<xs:attribute name="ip-check" type="xs:boolean" />
+                                                                       
<xs:attribute name="ports" />
+                                                               
</xs:complexType>
+                                                       </xs:element>
+                                               </xs:sequence>
+                                               <xs:attribute 
name="idle-timeout" type="xs:int" />
+                        <xs:attribute name="implicit-ssl" type="xs:boolean" />
+                                       </xs:complexType>
+                               </xs:element>
+                               <xs:element minOccurs="0" name="blacklist" 
type="xs:string" />
+                               <xs:element ref="ip-filter" minOccurs="0" 
maxOccurs="1" />
+                       </xs:sequence>
+                       <xs:attribute name="name" use="required" 
type="xs:string" />
+                       <xs:attribute name="local-address" />
+                       <xs:attribute name="port" type="xs:int" />
+                       <xs:attribute name="idle-timeout" type="xs:int" />
+                       <xs:attribute name="implicit-ssl" type="xs:boolean" />
+               </xs:complexType>
+       </xs:element>
+       
+       <!-- Extension element used for defining a custom listener -->
+       <xs:element name="listener" type="spring-bean-or-ref-with-name" />
+
+       <!-- Element used to configure Ftplets for used with the server -->
+       <xs:element name="ftplets">
+               <xs:complexType>
+                       <xs:choice>
+                               <xs:element name="ftplet" maxOccurs="unbounded">
+                                       <xs:complexType>
+                                               <xs:sequence>
+                                                       <xs:choice>
+                                                               <xs:element 
ref="beans:bean" />
+                                                               <xs:element 
ref="beans:ref" />
+                                                       </xs:choice>
+                                               </xs:sequence>
+                                               <xs:attribute name="name" 
use="required" type="xs:string" />
+                                       </xs:complexType>
+                               </xs:element>
+                               <xs:element ref="beans:map" />
+                       </xs:choice>
+               </xs:complexType>
+       </xs:element>
+
+       <!-- Element used to configure a file based user manager -->
+       <xs:element name="file-user-manager">
+               <xs:complexType>
+                       <xs:attribute name="file" type="xs:string" />
+                       <xs:attribute name="url" type="xs:string" />
+                       <xs:attribute name="encrypt-passwords">
+                               <xs:simpleType>
+                                       <xs:restriction base="xs:string">
+                                               <xs:enumeration 
value="clear"></xs:enumeration>
+                                               <!-- Deprecated, use "clear" -->
+                                               <xs:enumeration 
value="false"></xs:enumeration>
+                                               <xs:enumeration 
value="md5"></xs:enumeration>
+                                               <!-- Deprecated, use "md5" -->
+                                               <xs:enumeration 
value="true"></xs:enumeration>
+                                               <xs:enumeration 
value="salted"></xs:enumeration>
+                                       </xs:restriction>
+                               </xs:simpleType>
+                       </xs:attribute>
+               </xs:complexType>
+       </xs:element>
+       
+       <!-- Element used to configure a database based user manager -->
+       <xs:element name="db-user-manager">
+               <xs:complexType>
+               <xs:sequence>
+                               <xs:element name="data-source" 
type="spring-bean-or-ref" />
+                               <xs:element name="insert-user" type="xs:string" 
/>
+                               <xs:element name="update-user" type="xs:string" 
/>
+                               <xs:element name="delete-user" type="xs:string" 
/>
+                               <xs:element name="select-user" type="xs:string" 
/>
+                               <xs:element name="select-all-users" 
type="xs:string" />
+                               <xs:element name="is-admin" type="xs:string" />
+                               <xs:element name="authenticate" 
type="xs:string" />
+                       </xs:sequence>
+            <xs:attribute name="encrypt-passwords">
+                <xs:simpleType>
+                    <xs:restriction base="xs:string">
+                        <xs:enumeration value="clear"></xs:enumeration>
+                        <xs:enumeration value="md5"></xs:enumeration>
+                        <xs:enumeration value="salted"></xs:enumeration>
+                    </xs:restriction>
+                </xs:simpleType>
+            </xs:attribute>
+               </xs:complexType>
+       </xs:element>
+
+       <!-- Extension element used for defining a custom user manager -->
+       <xs:element name="user-manager" type="spring-bean-or-ref" />
+
+       <!-- Element used to configure the default file system -->
+       <xs:element name="native-filesystem">
+               <xs:complexType>
+                       <xs:attribute name="case-insensitive" type="xs:boolean" 
/>
+                       <xs:attribute name="create-home" type="xs:boolean" />
+               </xs:complexType>
+       </xs:element>
+
+       <!-- Extension element used for defining a custom file system -->
+       <xs:element name="filesystem" type="spring-bean-or-ref" />
+
+       <!-- Element used to provide custom command implementations -->
+       <xs:element name="commands">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="command" 
maxOccurs="unbounded">
+                                       <xs:complexType>
+                                               <xs:sequence>
+                                                       <xs:choice 
maxOccurs="unbounded">
+                                                               <xs:element 
ref="beans:bean" />
+                                                               <xs:element 
ref="beans:ref" />
+                                                       </xs:choice>
+                                               </xs:sequence>
+                                               <xs:attribute name="name" 
use="required" />
+                                       </xs:complexType>
+                               </xs:element>
+                       </xs:sequence>
+                       <xs:attribute name="use-default" type="xs:boolean" />
+               </xs:complexType>
+       </xs:element>
+       
+       <!-- Element used to configure and localize messages -->
+       <xs:element name="messages">
+               <xs:complexType>
+                       <xs:attribute name="languages" />
+                       <xs:attribute name="directory" />
+               </xs:complexType>
+       </xs:element>
+
+       <!-- Reusable type used for extension elements -->
+       <xs:complexType name="spring-bean-or-ref">
+               <xs:choice>
+                       <xs:element ref="beans:bean" />
+                       <xs:element ref="beans:ref" />
+               </xs:choice>
+       </xs:complexType>
+       
+       <!-- Reusable type used for named extension elements -->
+       <xs:complexType name="spring-bean-or-ref-with-name">
+               <xs:sequence>
+                       <xs:choice>
+                               <xs:element ref="beans:bean" />
+                               <xs:element ref="beans:ref" />
+                       </xs:choice>
+               </xs:sequence>
+               <xs:attribute name="name" use="required" type="xs:string" />
+       </xs:complexType>
 </xs:schema>
\ No newline at end of file


Reply via email to