001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.net.ftp;
018    
019    import java.io.IOException;
020    import java.net.SocketException;
021    import java.util.Calendar;
022    import java.util.Comparator;
023    import java.util.TreeSet;
024    
025    import junit.framework.TestCase;
026    
027    /*
028     * This test was contributed in a different form by W. McDonald Buck
029     * of Boulder, Colorado, to help fix some bugs with the FTPClientConfig
030     * in a real world setting.  It is a perfect functional test for the
031     * Time Zone functionality of FTPClientConfig.
032     * 
033     * A publicly accessible FTP server at the US National Oceanographic and
034     * Atmospheric Adminstration houses a directory which contains 
035     * 300 files, named sn.0000 to sn.0300. Every ten minutes or so 
036     * the next file in sequence is rewritten with new data. Thus the directory 
037     * contains observations for more than 24 hours of data.  Since the server
038     * has its clock set to GMT this is an excellent functional test for any
039     * machine in a different time zone. 
040     * 
041     * Noteworthy is the fact that the ftp routines in some web browsers don't 
042     * work as well as this.  They can't, since they have no way of knowing the 
043     * server's time zone.  Depending on the local machine's position relative 
044     * to GMT and the time of day, the browsers may decide that a timestamp 
045     * would be in the  future if given the current year, so they assume the 
046     * year to be  last year.  This illustrates the value of FTPClientConfig's 
047     * time zone functionality.
048     */
049    
050    public class FTPClientConfigFunctionalTest extends TestCase {
051    
052        private FTPClient FTP = new FTPClient(); 
053        private FTPClientConfig FTPConf; 
054    
055    
056        /**
057         * 
058         */
059        public FTPClientConfigFunctionalTest() {
060            super();
061    
062        }
063    
064        /* 
065         * @throws java.lang.Exception
066         */
067        @Override
068        protected void setUp() throws Exception {
069            super.setUp();
070            FTPConf = new FTPClientConfig(FTPClientConfig.SYST_UNIX);
071            FTPConf.setServerTimeZoneId("GMT"); 
072            FTP.configure(FTPConf); 
073            try {
074                FTP.connect("tgftp.nws.noaa.gov");
075                FTP.login("anonymous","testing@apache.org");
076                FTP.changeWorkingDirectory("SL.us008001/DF.an/DC.sflnd/DS.metar");
077                FTP.enterLocalPassiveMode();
078            } catch (SocketException e) {
079                e.printStackTrace();
080            } catch (IOException e) {
081                e.printStackTrace();
082            }
083        }
084        /* 
085         * @throws java.lang.Exception
086         */
087        @Override
088        protected void tearDown() throws Exception {
089            FTP.disconnect();
090            super.tearDown();
091        }
092        /**
093         * @param arg0
094         */
095        public FTPClientConfigFunctionalTest(String arg0) {
096            super(arg0);
097        }
098    
099        
100        @SuppressWarnings("unchecked")
101        private TreeSet<FTPFile> getSortedList(FTPFile[] files) {
102            // create a TreeSet which will sort each element
103            // as it is added.
104            TreeSet<FTPFile> sorted = new TreeSet<FTPFile>(new Comparator() {
105    
106                public int compare(Object o1, Object o2) {
107                    FTPFile f1 = (FTPFile) o1;
108                    FTPFile f2 = (FTPFile) o2;
109                    return f1.getTimestamp().getTime().compareTo(f2.getTimestamp().getTime());
110                }
111                
112            });
113            
114             
115            for (int i=0; i < files.length; i++) {
116                // The directory contains a few additional files at the beginning
117                // which aren't in the series we want. The series we want consists
118                // of files named sn.dddd. This adjusts the file list to get rid 
119                // of the uninteresting ones. 
120                if (files[i].getName().startsWith("sn")) {
121                    sorted.add(files[i]);
122                }    
123            }
124            return sorted;
125        }
126    
127        
128        public static void main(String[] args) {
129            FTPClientConfigFunctionalTest F = new FTPClientConfigFunctionalTest();
130        }
131        
132        public void testTimeZoneFunctionality() throws Exception {
133            java.util.Date now = new java.util.Date();
134            FTPFile[] files = FTP.listFiles();
135            TreeSet<FTPFile> sorted = getSortedList(files);
136            //SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm z" );
137            FTPFile lastfile = null;
138            FTPFile firstfile = null;
139            for (FTPFile thisfile : sorted) {
140                if (firstfile == null) {
141                    firstfile = thisfile;
142                }
143                //System.out.println(sdf.format(thisfile.getTimestamp().getTime()) 
144                //        + " " +thisfile.getName());
145                if (lastfile != null) {
146                    // verify that the list is sorted earliest to latest.
147                    assertTrue(lastfile.getTimestamp()
148                            .before(thisfile.getTimestamp()));
149                }
150                lastfile = thisfile;
151            }
152            
153            // test that notwithstanding any time zone differences, the newest file
154            // is older than now.
155            assertTrue(lastfile.getTimestamp().getTime().before(now));
156            Calendar first = firstfile.getTimestamp();
157    
158            // test that the oldest is less than two days older than the newest 
159            // and, in particular, that no files have been considered "future" 
160            // by the parser and therefore been relegated to the same date a 
161            // year ago.
162            first.add(Calendar.DATE, 2);
163            assertTrue(lastfile.getTimestamp().before(first));
164    
165        }
166    }
167    
168    
169    
170