001: /*
002: * Copyright 2004-2005 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.apache.commons.net.ftp.parser;
017:
018: import org.apache.commons.net.ftp.Configurable;
019: import org.apache.commons.net.ftp.FTPClientConfig;
020: import org.apache.commons.net.ftp.FTPFileEntryParser;
021:
022: /**
023: * This is the default implementation of the
024: * FTPFileEntryParserFactory interface. This is the
025: * implementation that will be used by
026: * org.apache.commons.net.ftp.FTPClient.listFiles()
027: * if no other implementation has been specified.
028: *
029: * @see org.apache.commons.net.ftp.FTPClient#listFiles
030: * @see org.apache.commons.net.ftp.FTPClient#setParserFactory
031: */
032: public class DefaultFTPFileEntryParserFactory implements
033: FTPFileEntryParserFactory {
034: private FTPClientConfig config = null;
035:
036: /**
037: * This default implementation of the FTPFileEntryParserFactory
038: * interface works according to the following logic:
039: * First it attempts to interpret the supplied key as a fully
040: * qualified classname of a class implementing the
041: * FTPFileEntryParser interface. If that succeeds, a parser
042: * object of this class is instantiated and is returned;
043: * otherwise it attempts to interpret the key as an identirier
044: * commonly used by the FTP SYST command to identify systems.
045: * <p/>
046: * If <code>key</code> is not recognized as a fully qualified
047: * classname known to the system, this method will then attempt
048: * to see whether it <b>contains</b> a string identifying one of
049: * the known parsers. This comparison is <b>case-insensitive</b>.
050: * The intent here is where possible, to select as keys strings
051: * which are returned by the SYST command on the systems which
052: * the corresponding parser successfully parses. This enables
053: * this factory to be used in the auto-detection system.
054: * <p/>
055: *
056: * @param key should be a fully qualified classname corresponding to
057: * a class implementing the FTPFileEntryParser interface<br/>
058: * OR<br/>
059: * a string containing (case-insensitively) one of the
060: * following keywords:
061: * <ul>
062: * <li>{@link FTPClientConfig#SYST_UNIX UNIX}</li>
063: * <li>{@link FTPClientConfig#SYST_NT WINDOWS}</li>
064: * <li>{@link FTPClientConfig#SYST_OS2 OS/2}</li>
065: * <li>{@link FTPClientConfig#SYST_OS400 OS/400}</li>
066: * <li>{@link FTPClientConfig#SYST_VMS VMS}</li>
067: * <li>{@link FTPClientConfig#SYST_MVS MVS}</li>
068: * </ul>
069: * @return the FTPFileEntryParser corresponding to the supplied key.
070: * @throws ParserInitializationException thrown if for any reason the factory cannot resolve
071: * the supplied key into an FTPFileEntryParser.
072: * @see FTPFileEntryParser
073: */
074: public FTPFileEntryParser createFileEntryParser(String key) {
075: Class parserClass = null;
076: FTPFileEntryParser parser = null;
077: try {
078: parserClass = Class.forName(key);
079: parser = (FTPFileEntryParser) parserClass.newInstance();
080: } catch (ClassNotFoundException e) {
081: String ukey = null;
082: if (null != key) {
083: ukey = key.toUpperCase();
084: }
085: if (ukey.indexOf(FTPClientConfig.SYST_UNIX) >= 0) {
086: parser = createUnixFTPEntryParser();
087: } else if (ukey.indexOf(FTPClientConfig.SYST_VMS) >= 0) {
088: parser = createVMSVersioningFTPEntryParser();
089: } else if (ukey.indexOf(FTPClientConfig.SYST_NT) >= 0) {
090: parser = createNTFTPEntryParser();
091: } else if (ukey.indexOf(FTPClientConfig.SYST_OS2) >= 0) {
092: parser = createOS2FTPEntryParser();
093: } else if (ukey.indexOf(FTPClientConfig.SYST_OS400) >= 0) {
094: parser = createOS400FTPEntryParser();
095: } else if (ukey.indexOf(FTPClientConfig.SYST_MVS) >= 0) {
096: parser = createMVSEntryParser();
097: } else {
098: throw new ParserInitializationException(
099: "Unknown parser type: " + key);
100: }
101: } catch (ClassCastException e) {
102: throw new ParserInitializationException(parserClass
103: .getName()
104: + " does not implement the interface "
105: + "org.apache.commons.net.ftp.FTPFileEntryParser.",
106: e);
107: } catch (Throwable e) {
108: throw new ParserInitializationException(
109: "Error initializing parser", e);
110: }
111:
112: if (parser instanceof Configurable) {
113: ((Configurable) parser).configure(this .config);
114: }
115: return parser;
116: }
117:
118: /**
119: * <p>Implementation extracts a key from the supplied
120: * {@link FTPClientConfig FTPClientConfig}
121: * parameter and creates an object implementing the
122: * interface FTPFileEntryParser and uses the supplied configuration
123: * to configure it.
124: * </p><p>
125: * Note that this method will generally not be called in scenarios
126: * that call for autodetection of parser type but rather, for situations
127: * where the user knows that the server uses a non-default configuration
128: * and knows what that configuration is.
129: * </p>
130: * @param config A {@link FTPClientConfig FTPClientConfig}
131: * used to configure the parser created
132: *
133: * @return the @link FTPFileEntryParser FTPFileEntryParser} so created.
134: * @exception ParserInitializationException
135: * Thrown on any exception in instantiation
136: * @since 1.4
137: */
138: public FTPFileEntryParser createFileEntryParser(
139: FTPClientConfig config)
140: throws ParserInitializationException {
141: this .config = config;
142: String key = config.getServerSystemKey();
143: return createFileEntryParser(key);
144: }
145:
146: public FTPFileEntryParser createUnixFTPEntryParser() {
147: return (FTPFileEntryParser) new UnixFTPEntryParser();
148: }
149:
150: public FTPFileEntryParser createVMSVersioningFTPEntryParser() {
151: return (FTPFileEntryParser) new VMSVersioningFTPEntryParser();
152: }
153:
154: public FTPFileEntryParser createNTFTPEntryParser() {
155: if (config != null
156: && FTPClientConfig.SYST_NT.equals(config
157: .getServerSystemKey())) {
158: return new NTFTPEntryParser();
159: } else {
160: return new CompositeFileEntryParser(
161: new FTPFileEntryParser[] { new NTFTPEntryParser(),
162: new UnixFTPEntryParser() });
163: }
164: }
165:
166: public FTPFileEntryParser createOS2FTPEntryParser() {
167: return (FTPFileEntryParser) new OS2FTPEntryParser();
168: }
169:
170: public FTPFileEntryParser createOS400FTPEntryParser() {
171: if (config != null
172: && FTPClientConfig.SYST_OS400.equals(config
173: .getServerSystemKey())) {
174: return new OS400FTPEntryParser();
175: } else {
176: return new CompositeFileEntryParser(
177: new FTPFileEntryParser[] {
178: new OS400FTPEntryParser(),
179: new UnixFTPEntryParser() });
180: }
181: }
182:
183: public FTPFileEntryParser createMVSEntryParser() {
184: return new MVSFTPEntryParser();
185: }
186:
187: }
|