View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.net.ftp.parser;
19  
20  import org.apache.commons.net.ftp.Configurable;
21  import org.apache.commons.net.ftp.FTPClientConfig;
22  import org.apache.commons.net.ftp.FTPFileEntryParser;
23  
24  
25  /**
26   * This is the default implementation of the
27   * FTPFileEntryParserFactory interface.  This is the
28   * implementation that will be used by
29   * org.apache.commons.net.ftp.FTPClient.listFiles()
30   * if no other implementation has been specified.
31   *
32   * @see org.apache.commons.net.ftp.FTPClient#listFiles
33   * @see org.apache.commons.net.ftp.FTPClient#setParserFactory
34   */
35  public class DefaultFTPFileEntryParserFactory
36      implements FTPFileEntryParserFactory
37  {
38  	private FTPClientConfig config = null;
39  
40  	/**
41       * This default implementation of the FTPFileEntryParserFactory
42       * interface works according to the following logic:
43       * First it attempts to interpret the supplied key as a fully
44       * qualified classname of a class implementing the
45       * FTPFileEntryParser interface.  If that succeeds, a parser
46       * object of this class is instantiated and is returned; 
47       * otherwise it attempts to interpret the key as an identirier
48       * commonly used by the FTP SYST command to identify systems.
49       * <p/>
50       * If <code>key</code> is not recognized as a fully qualified
51       * classname known to the system, this method will then attempt
52       * to see whether it <b>contains</b> a string identifying one of
53       * the known parsers.  This comparison is <b>case-insensitive</b>.
54       * The intent here is where possible, to select as keys strings
55       * which are returned by the SYST command on the systems which
56       * the corresponding parser successfully parses.  This enables
57       * this factory to be used in the auto-detection system.
58       * <p/>
59       *
60       * @param key    should be a fully qualified classname corresponding to
61       *               a class implementing the FTPFileEntryParser interface<br/>
62       *               OR<br/>
63       *               a string containing (case-insensitively) one of the
64       *               following keywords:
65       *               <ul>
66       *               <li>{@link FTPClientConfig#SYST_UNIX UNIX}</li>
67       *               <li>{@link FTPClientConfig#SYST_NT WINDOWS}</li>
68       *               <li>{@link FTPClientConfig#SYST_OS2 OS/2}</li>
69       *               <li>{@link FTPClientConfig#SYST_OS400 OS/400}</li>
70       *               <li>{@link FTPClientConfig#SYST_VMS VMS}</li>
71       *               <li>{@link FTPClientConfig#SYST_MVS MVS}</li>
72       *               <li>{@link FTPClientConfig#SYST_NETWARE}</li>
73       *               </ul>
74       * @return the FTPFileEntryParser corresponding to the supplied key.
75       * @throws ParserInitializationException thrown if for any reason the factory cannot resolve
76       *                   the supplied key into an FTPFileEntryParser.
77       * @see FTPFileEntryParser
78       */
79      public FTPFileEntryParser createFileEntryParser(String key)
80      {
81      	if (key == null)
82      		throw new ParserInitializationException("Parser key cannot be null");
83      		
84          Class<?> parserClass = null;
85          FTPFileEntryParser parser = null;
86          try
87          {
88              parserClass = Class.forName(key);
89              parser = (FTPFileEntryParser) parserClass.newInstance();
90          }
91          catch (ClassNotFoundException e)
92          {
93              try 
94              {
95  	            String ukey = null;
96  	            if (null != key)
97  	            {
98  	                ukey = key.toUpperCase(java.util.Locale.ENGLISH);
99  	            }
100 	            if ((ukey.indexOf(FTPClientConfig.SYST_UNIX) >= 0) 
101 	            		|| (ukey.indexOf(FTPClientConfig.SYST_L8) >= 0))
102 	            {
103 	                parser = createUnixFTPEntryParser();
104 	            }
105 	            else if (ukey.indexOf(FTPClientConfig.SYST_VMS) >= 0)
106 	            {
107 	                parser = createVMSVersioningFTPEntryParser();
108 	            }
109 	            else if (ukey.indexOf(FTPClientConfig.SYST_NT) >= 0)
110 	            {
111 	                parser = createNTFTPEntryParser();
112 	            }
113 	            else if (ukey.indexOf(FTPClientConfig.SYST_OS2) >= 0)
114 	            {
115 	                parser = createOS2FTPEntryParser();
116 	            }
117 	            else if (ukey.indexOf(FTPClientConfig.SYST_OS400) >= 0 ||
118 	            		ukey.indexOf(FTPClientConfig.SYST_AS400) >= 0)
119 	            {
120 	                parser = createOS400FTPEntryParser();
121 	            }
122 	            else if (ukey.indexOf(FTPClientConfig.SYST_MVS) >= 0)
123 	            {
124 	                parser = createMVSEntryParser();
125 	        	}
126 	            else if (ukey.indexOf(FTPClientConfig.SYST_NETWARE) >= 0) 
127 	            {
128 	            	parser = createNetwareFTPEntryParser();
129 	            }
130 	            else
131 	            {
132 	                throw new ParserInitializationException("Unknown parser type: " + key);
133 	            }
134             } 
135             catch (NoClassDefFoundError nf) {
136                     throw new ParserInitializationException("Error initializing parser", nf);
137             }
138 
139         }
140         catch (NoClassDefFoundError e)
141         { 	
142             throw new ParserInitializationException("Error initializing parser", e);
143         }
144         catch (ClassCastException e)
145         {
146             throw new ParserInitializationException(parserClass.getName()
147                 + " does not implement the interface "
148                 + "org.apache.commons.net.ftp.FTPFileEntryParser.", e);
149         }
150         catch (Throwable e)
151         {
152             throw new ParserInitializationException("Error initializing parser", e);
153         }
154 
155         if (parser instanceof Configurable) {
156             ((Configurable)parser).configure(this.config);
157         }    
158         return parser;
159     }
160     
161     /**
162      * <p>Implementation extracts a key from the supplied 
163      * {@link  FTPClientConfig FTPClientConfig}
164      * parameter and creates an object implementing the
165      * interface FTPFileEntryParser and uses the supplied configuration
166      * to configure it.
167      * </p><p>
168      * Note that this method will generally not be called in scenarios
169      * that call for autodetection of parser type but rather, for situations
170      * where the user knows that the server uses a non-default configuration
171      * and knows what that configuration is.
172      * </p>
173      * @param config  A {@link  FTPClientConfig FTPClientConfig}  
174      * used to configure the parser created
175      *
176      * @return the @link  FTPFileEntryParser FTPFileEntryParser} so created.
177      * @exception ParserInitializationException
178      *                   Thrown on any exception in instantiation
179      * @since 1.4
180      */
181 	public FTPFileEntryParser createFileEntryParser(FTPClientConfig config) 
182 	throws ParserInitializationException 
183 	{
184 	    this.config = config;
185 		String key = config.getServerSystemKey();
186 		return createFileEntryParser(key);
187 	}
188 
189 
190     public FTPFileEntryParser createUnixFTPEntryParser()
191     {
192         return new UnixFTPEntryParser();
193     }
194 
195     public FTPFileEntryParser createVMSVersioningFTPEntryParser()
196     {
197         return new VMSVersioningFTPEntryParser();
198     }
199     
200     public FTPFileEntryParser createNetwareFTPEntryParser() {
201     	return new NetwareFTPEntryParser();
202     }
203 
204     public FTPFileEntryParser createNTFTPEntryParser()
205     {
206     	if (config != null && FTPClientConfig.SYST_NT.equals(
207     	        config.getServerSystemKey())) 
208     	{
209             return new NTFTPEntryParser();
210     	} else {
211             return new CompositeFileEntryParser(new FTPFileEntryParser[]
212 	   	        {
213 	   	            new NTFTPEntryParser(),
214 	   	            new UnixFTPEntryParser()
215 	   	        });
216     	}
217     }
218     
219      public FTPFileEntryParser createOS2FTPEntryParser()
220     {
221         return new OS2FTPEntryParser();
222     }
223 
224     public FTPFileEntryParser createOS400FTPEntryParser()
225     {
226     	if (config != null && 
227     	        FTPClientConfig.SYST_OS400.equals(config.getServerSystemKey())) 
228     	{
229             return new OS400FTPEntryParser();
230     	} else {
231 	        return new CompositeFileEntryParser(new FTPFileEntryParser[]
232 	            {
233 	                new OS400FTPEntryParser(),
234 	                new UnixFTPEntryParser()
235 	            });
236     	}
237     }
238 
239     public FTPFileEntryParser createMVSEntryParser()
240     {
241         return new MVSFTPEntryParser();
242     }
243 
244 
245 	
246 }
247