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 /** 024 * This is the default implementation of the 025 * FTPFileEntryParserFactory interface. This is the 026 * implementation that will be used by 027 * org.apache.commons.net.ftp.FTPClient.listFiles() 028 * if no other implementation has been specified. 029 * 030 * @see org.apache.commons.net.ftp.FTPClient#listFiles 031 * @see org.apache.commons.net.ftp.FTPClient#setParserFactory 032 */ 033 public class DefaultFTPFileEntryParserFactory 034 implements FTPFileEntryParserFactory 035 { 036 private FTPClientConfig config = null; 037 038 /** 039 * This default implementation of the FTPFileEntryParserFactory 040 * interface works according to the following logic: 041 * First it attempts to interpret the supplied key as a fully 042 * qualified classname of a class implementing the 043 * FTPFileEntryParser interface. If that succeeds, a parser 044 * object of this class is instantiated and is returned; 045 * otherwise it attempts to interpret the key as an identirier 046 * commonly used by the FTP SYST command to identify systems. 047 * <p/> 048 * If <code>key</code> is not recognized as a fully qualified 049 * classname known to the system, this method will then attempt 050 * to see whether it <b>contains</b> a string identifying one of 051 * the known parsers. This comparison is <b>case-insensitive</b>. 052 * The intent here is where possible, to select as keys strings 053 * which are returned by the SYST command on the systems which 054 * the corresponding parser successfully parses. This enables 055 * this factory to be used in the auto-detection system. 056 * <p/> 057 * 058 * @param key should be a fully qualified classname corresponding to 059 * a class implementing the FTPFileEntryParser interface<br/> 060 * OR<br/> 061 * a string containing (case-insensitively) one of the 062 * following keywords: 063 * <ul> 064 * <li>{@link FTPClientConfig#SYST_UNIX UNIX}</li> 065 * <li>{@link FTPClientConfig#SYST_NT WINDOWS}</li> 066 * <li>{@link FTPClientConfig#SYST_OS2 OS/2}</li> 067 * <li>{@link FTPClientConfig#SYST_OS400 OS/400}</li> 068 * <li>{@link FTPClientConfig#SYST_VMS VMS}</li> 069 * <li>{@link FTPClientConfig#SYST_MVS MVS}</li> 070 * </ul> 071 * @return the FTPFileEntryParser corresponding to the supplied key. 072 * @throws ParserInitializationException thrown if for any reason the factory cannot resolve 073 * the supplied key into an FTPFileEntryParser. 074 * @see FTPFileEntryParser 075 */ 076 public FTPFileEntryParser createFileEntryParser(String key) 077 { 078 Class parserClass = null; 079 FTPFileEntryParser parser = null; 080 try 081 { 082 parserClass = Class.forName(key); 083 parser = (FTPFileEntryParser) parserClass.newInstance(); 084 } 085 catch (ClassNotFoundException e) 086 { 087 String ukey = null; 088 if (null != key) 089 { 090 ukey = key.toUpperCase(); 091 } 092 if (ukey.indexOf(FTPClientConfig.SYST_UNIX) >= 0) 093 { 094 parser = createUnixFTPEntryParser(); 095 } 096 else if (ukey.indexOf(FTPClientConfig.SYST_VMS) >= 0) 097 { 098 parser = createVMSVersioningFTPEntryParser(); 099 } 100 else if (ukey.indexOf(FTPClientConfig.SYST_NT) >= 0) 101 { 102 parser = createNTFTPEntryParser(); 103 } 104 else if (ukey.indexOf(FTPClientConfig.SYST_OS2) >= 0) 105 { 106 parser = createOS2FTPEntryParser(); 107 } 108 else if (ukey.indexOf(FTPClientConfig.SYST_OS400) >= 0) 109 { 110 parser = createOS400FTPEntryParser(); 111 } 112 else if (ukey.indexOf(FTPClientConfig.SYST_MVS) >= 0) 113 { 114 parser = createMVSEntryParser(); 115 } 116 else 117 { 118 throw new ParserInitializationException("Unknown parser type: " + key); 119 } 120 } 121 catch (ClassCastException e) 122 { 123 throw new ParserInitializationException(parserClass.getName() 124 + " does not implement the interface " 125 + "org.apache.commons.net.ftp.FTPFileEntryParser.", e); 126 } 127 catch (Throwable e) 128 { 129 throw new ParserInitializationException("Error initializing parser", e); 130 } 131 132 if (parser instanceof Configurable) { 133 ((Configurable)parser).configure(this.config); 134 } 135 return parser; 136 } 137 138 /** 139 * <p>Implementation extracts a key from the supplied 140 * {@link FTPClientConfig FTPClientConfig} 141 * parameter and creates an object implementing the 142 * interface FTPFileEntryParser and uses the supplied configuration 143 * to configure it. 144 * </p><p> 145 * Note that this method will generally not be called in scenarios 146 * that call for autodetection of parser type but rather, for situations 147 * where the user knows that the server uses a non-default configuration 148 * and knows what that configuration is. 149 * </p> 150 * @param config A {@link FTPClientConfig FTPClientConfig} 151 * used to configure the parser created 152 * 153 * @return the @link FTPFileEntryParser FTPFileEntryParser} so created. 154 * @exception ParserInitializationException 155 * Thrown on any exception in instantiation 156 * @since 1.4 157 */ 158 public FTPFileEntryParser createFileEntryParser(FTPClientConfig config) 159 throws ParserInitializationException 160 { 161 this.config = config; 162 String key = config.getServerSystemKey(); 163 return createFileEntryParser(key); 164 } 165 166 167 public FTPFileEntryParser createUnixFTPEntryParser() 168 { 169 return (FTPFileEntryParser) new UnixFTPEntryParser(); 170 } 171 172 public FTPFileEntryParser createVMSVersioningFTPEntryParser() 173 { 174 return (FTPFileEntryParser) new VMSVersioningFTPEntryParser(); 175 } 176 177 public FTPFileEntryParser createNTFTPEntryParser() 178 { 179 if (config != null && FTPClientConfig.SYST_NT.equals( 180 config.getServerSystemKey())) 181 { 182 return new NTFTPEntryParser(); 183 } else { 184 return new CompositeFileEntryParser(new FTPFileEntryParser[] 185 { 186 new NTFTPEntryParser(), 187 new UnixFTPEntryParser() 188 }); 189 } 190 } 191 192 public FTPFileEntryParser createOS2FTPEntryParser() 193 { 194 return (FTPFileEntryParser) new OS2FTPEntryParser(); 195 } 196 197 public FTPFileEntryParser createOS400FTPEntryParser() 198 { 199 if (config != null && 200 FTPClientConfig.SYST_OS400.equals(config.getServerSystemKey())) 201 { 202 return new OS400FTPEntryParser(); 203 } else { 204 return new CompositeFileEntryParser(new FTPFileEntryParser[] 205 { 206 new OS400FTPEntryParser(), 207 new UnixFTPEntryParser() 208 }); 209 } 210 } 211 212 public FTPFileEntryParser createMVSEntryParser() 213 { 214 return new MVSFTPEntryParser(); 215 } 216 217 218 219 } 220