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