blob: 5a5ad1eed5e67e1080f53c16c4bd0b67275bc3af [file] [log] [blame]
/*
* 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.
*/
package org.apache.commons.net.ftp.parser;
import org.apache.commons.net.ftp.Configurable;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPFileEntryParser;
/**
* This is the default implementation of the
* FTPFileEntryParserFactory interface. This is the
* implementation that will be used by
* org.apache.commons.net.ftp.FTPClient.listFiles()
* if no other implementation has been specified.
*
* @see org.apache.commons.net.ftp.FTPClient#listFiles()
* @see org.apache.commons.net.ftp.FTPClient#setParserFactory
*/
public class DefaultFTPFileEntryParserFactory
implements FTPFileEntryParserFactory
{
private FTPClientConfig config = null;
/**
* This default implementation of the FTPFileEntryParserFactory
* interface works according to the following logic:
* First it attempts to interpret the supplied key as a fully
* qualified classname of a class implementing the
* FTPFileEntryParser interface. If that succeeds, a parser
* object of this class is instantiated and is returned;
* otherwise it attempts to interpret the key as an identirier
* commonly used by the FTP SYST command to identify systems.
* <p/>
* If <code>key</code> is not recognized as a fully qualified
* classname known to the system, this method will then attempt
* to see whether it <b>contains</b> a string identifying one of
* the known parsers. This comparison is <b>case-insensitive</b>.
* The intent here is where possible, to select as keys strings
* which are returned by the SYST command on the systems which
* the corresponding parser successfully parses. This enables
* this factory to be used in the auto-detection system.
* <p/>
*
* @param key should be a fully qualified classname corresponding to
* a class implementing the FTPFileEntryParser interface<br/>
* OR<br/>
* a string containing (case-insensitively) one of the
* following keywords:
* <ul>
* <li>{@link FTPClientConfig#SYST_UNIX UNIX}</li>
* <li>{@link FTPClientConfig#SYST_NT WINDOWS}</li>
* <li>{@link FTPClientConfig#SYST_OS2 OS/2}</li>
* <li>{@link FTPClientConfig#SYST_OS400 OS/400}</li>
* <li>{@link FTPClientConfig#SYST_VMS VMS}</li>
* <li>{@link FTPClientConfig#SYST_MVS MVS}</li>
* </ul>
* @return the FTPFileEntryParser corresponding to the supplied key.
* @throws ParserInitializationException thrown if for any reason the factory cannot resolve
* the supplied key into an FTPFileEntryParser.
* @see FTPFileEntryParser
*/
public FTPFileEntryParser createFileEntryParser(String key)
{
Class parserClass = null;
FTPFileEntryParser parser = null;
try
{
parserClass = Class.forName(key);
parser = (FTPFileEntryParser) parserClass.newInstance();
}
catch (ClassNotFoundException e)
{
try
{
String ukey = null;
if (null != key)
{
ukey = key.toUpperCase(java.util.Locale.ENGLISH);
}
if (ukey.indexOf(FTPClientConfig.SYST_UNIX) >= 0
|| (ukey.indexOf(FTPClientConfig.SYST_L8) >= 0))
{
parser = createUnixFTPEntryParser();
}
else if (ukey.indexOf(FTPClientConfig.SYST_VMS) >= 0)
{
parser = createVMSVersioningFTPEntryParser();
}
else if (ukey.indexOf(FTPClientConfig.SYST_NT) >= 0)
{
parser = createNTFTPEntryParser();
}
else if (ukey.indexOf(FTPClientConfig.SYST_OS2) >= 0)
{
parser = createOS2FTPEntryParser();
}
else if ((ukey.indexOf(FTPClientConfig.SYST_OS400) >= 0)
|| (ukey.indexOf(FTPClientConfig.SYST_AS400) >= 0))
{
parser = createOS400FTPEntryParser();
}
else if (ukey.indexOf(FTPClientConfig.SYST_MVS) >= 0)
{
parser = createMVSEntryParser();
}
else if (ukey.indexOf(FTPClientConfig.SYST_NETWARE) >= 0)
{
parser = createNetwareFTPEntryParser();
}
else
{
throw new ParserInitializationException("Unknown parser type: " + key);
}
}
catch (NoClassDefFoundError nf)
{
if (nf.getMessage().startsWith("org/apache/oro")) {
throw new ParserInitializationException(
" jakarta-oro-2.x.jar required on the runtime classpath. ", nf);
} else {
throw new ParserInitializationException("Error initializing parser", nf);
}
}
}
catch (NoClassDefFoundError e)
{
if (e.getMessage().startsWith("org/apache/oro")) {
throw new ParserInitializationException(
" jakarta-oro-2.x.jar required on the runtime classpath. ", e);
} else {
throw new ParserInitializationException("Error initializing parser", e);
}
}
catch (ClassCastException e)
{
throw new ParserInitializationException(parserClass.getName()
+ " does not implement the interface "
+ "org.apache.commons.net.ftp.FTPFileEntryParser.", e);
}
catch (Throwable e)
{
throw new ParserInitializationException("Error initializing parser", e);
}
if (parser instanceof Configurable) {
((Configurable)parser).configure(this.config);
}
return parser;
}
/**
* <p>Implementation extracts a key from the supplied
* {@link FTPClientConfig FTPClientConfig}
* parameter and creates an object implementing the
* interface FTPFileEntryParser and uses the supplied configuration
* to configure it.
* </p><p>
* Note that this method will generally not be called in scenarios
* that call for autodetection of parser type but rather, for situations
* where the user knows that the server uses a non-default configuration
* and knows what that configuration is.
* </p>
* @param config A {@link FTPClientConfig FTPClientConfig}
* used to configure the parser created
*
* @return the @link FTPFileEntryParser FTPFileEntryParser} so created.
* @exception ParserInitializationException
* Thrown on any exception in instantiation
* @since 1.4
*/
public FTPFileEntryParser createFileEntryParser(FTPClientConfig config)
throws ParserInitializationException
{
this.config = config;
String key = config.getServerSystemKey();
return createFileEntryParser(key);
}
public FTPFileEntryParser createUnixFTPEntryParser()
{
return new UnixFTPEntryParser();
}
public FTPFileEntryParser createVMSVersioningFTPEntryParser()
{
return new VMSVersioningFTPEntryParser();
}
/**
* @since 1.5
*/
public FTPFileEntryParser createNetwareFTPEntryParser() {
return new NetwareFTPEntryParser();
}
public FTPFileEntryParser createNTFTPEntryParser()
{
if (config != null && FTPClientConfig.SYST_NT.equals(
config.getServerSystemKey()))
{
return new NTFTPEntryParser();
} else {
return new CompositeFileEntryParser(new FTPFileEntryParser[]
{
new NTFTPEntryParser(),
new UnixFTPEntryParser()
});
}
}
public FTPFileEntryParser createOS2FTPEntryParser()
{
return new OS2FTPEntryParser();
}
public FTPFileEntryParser createOS400FTPEntryParser()
{
if (config != null &&
FTPClientConfig.SYST_OS400.equals(config.getServerSystemKey()))
{
return new OS400FTPEntryParser();
} else {
return new CompositeFileEntryParser(new FTPFileEntryParser[]
{
new OS400FTPEntryParser(),
new UnixFTPEntryParser()
});
}
}
public FTPFileEntryParser createMVSEntryParser()
{
return new MVSFTPEntryParser();
}
}