1   /*
2    * Copyright 2005 The Apache Software Foundation
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.commons.net.ftp.parser;
17  
18  import java.text.ParseException;
19  import java.text.SimpleDateFormat;
20  import java.util.Calendar;
21  import java.util.Date;
22  import java.util.TimeZone;
23  
24  import org.apache.commons.net.ftp.FTPClientConfig;
25  
26  import junit.framework.TestCase;
27  import junit.framework.TestSuite;
28  
29  /**
30   * @author scohen
31   *
32   * To change the template for this generated type comment go to
33   * Window - Preferences - Java - Code Generation - Code and Comments
34   */
35  public class FTPTimestampParserImplTest extends TestCase {
36  	
37  	private static final int TWO_HOURS_OF_MILLISECONDS = 2 * 60 * 60 * 1000;
38  
39  	public void testParseTimestamp() {
40  		Calendar cal = Calendar.getInstance();
41  		int timeZoneOffset = cal.getTimeZone().getRawOffset();
42  		cal.add(Calendar.HOUR_OF_DAY, 1);
43  		cal.set(Calendar.SECOND,0);
44  		cal.set(Calendar.MILLISECOND,0);
45  		Date anHourFromNow = cal.getTime();
46  		FTPTimestampParserImpl parser = new FTPTimestampParserImpl();
47  		SimpleDateFormat sdf = 
48  			new SimpleDateFormat(parser.getRecentDateFormatString());
49  		String fmtTime = sdf.format(anHourFromNow);
50  		try {
51  			Calendar parsed = parser.parseTimestamp(fmtTime);
52  			// since the timestamp is ahead of now (by one hour),
53  			// this must mean the file's date refers to a year ago.
54  			assertEquals("test.roll.back.year", 1, cal.get(Calendar.YEAR) - parsed.get(Calendar.YEAR));
55  		} catch (ParseException e) {
56  			fail("Unable to parse");
57  		}
58  	}
59  		
60  	public void testParseTimestampAcrossTimeZones() {
61  	    
62  	    
63  	    Calendar cal = Calendar.getInstance();
64  		cal.set(Calendar.SECOND,0);
65  		cal.set(Calendar.MILLISECOND,0);
66  
67  		cal.add(Calendar.HOUR_OF_DAY, 1);
68  		Date anHourFromNow = cal.getTime();
69  		
70  		cal.add(Calendar.HOUR_OF_DAY, 2);
71  		Date threeHoursFromNow = cal.getTime();
72  		cal.add(Calendar.HOUR_OF_DAY, -2);
73  		
74  		FTPTimestampParserImpl parser = new FTPTimestampParserImpl();
75  
76  		// assume we are FTPing a server in Chicago, two hours ahead of 
77  		// L. A.
78  		FTPClientConfig config = 
79  		    new FTPClientConfig(FTPClientConfig.SYST_UNIX);
80  		config.setDefaultDateFormatStr(FTPTimestampParser.DEFAULT_SDF);
81  		config.setRecentDateFormatStr(FTPTimestampParser.DEFAULT_RECENT_SDF);
82  	    // 2 hours difference
83  		config.setServerTimeZoneId("America/Chicago");
84  		parser.configure(config);
85  		
86  		SimpleDateFormat sdf = (SimpleDateFormat)
87  			parser.getRecentDateFormat().clone();
88  		
89  	    // assume we're in the US Pacific Time Zone
90  	    TimeZone tzla = TimeZone.getTimeZone("America/Los_Angeles");
91  		sdf.setTimeZone(tzla);
92  		
93  		// get formatted versions of time in L.A. 
94  		String fmtTimePlusOneHour = sdf.format(anHourFromNow);
95  		String fmtTimePlusThreeHours = sdf.format(threeHoursFromNow);
96  		
97  		
98  		try {
99  			Calendar parsed = parser.parseTimestamp(fmtTimePlusOneHour);
100 			// the only difference should be the two hours
101 			// difference, no rolling back a year should occur.
102 			assertEquals("no.rollback.because.of.time.zones",
103 				(long)TWO_HOURS_OF_MILLISECONDS, 
104 				cal.getTime().getTime() - parsed.getTime().getTime());
105 		} catch (ParseException e){
106 			fail("Unable to parse " + fmtTimePlusOneHour);
107 		}
108 		
109 		//but if the file's timestamp is THREE hours ahead of now, that should 
110 		//cause a rollover even taking the time zone difference into account.
111 		//Since that time is still later than ours, it is parsed as occurring
112 		//on this date last year.
113 		try {
114 			Calendar parsed = parser.parseTimestamp(fmtTimePlusThreeHours);
115 			// rollback should occur here.
116 			assertEquals("rollback.even.with.time.zones", 
117 					1, cal.get(Calendar.YEAR) - parsed.get(Calendar.YEAR));
118 		} catch (ParseException e){
119 			fail("Unable to parse" + fmtTimePlusThreeHours);
120 		}
121 	}
122 
123 
124 	public void testParser() {
125 		FTPTimestampParserImpl parser = new FTPTimestampParserImpl();
126 		try {
127 			parser.parseTimestamp("feb 22 2002");
128 		} catch (ParseException e) {
129 			fail("failed.to.parse.default");
130 		}
131 		try {
132 			parser.parseTimestamp("f\u00e9v 22 2002");
133 			fail("should.have.failed.to.parse.default");
134 		} catch (ParseException e) {
135 			// this is the success case
136 		}
137 
138 		FTPClientConfig config = new FTPClientConfig();
139 		config.setDefaultDateFormatStr("d MMM yyyy");
140 		config.setRecentDateFormatStr("d MMM HH:mm");
141 		config.setServerLanguageCode("fr");
142 		parser.configure(config);
143 		try {
144 			parser.parseTimestamp("d\u00e9c 22 2002");
145 			fail("incorrect.field.order");
146 		} catch (ParseException e) {
147 			// this is the success case
148 		}
149 		try {
150 			parser.parseTimestamp("22 d\u00e9c 2002");
151 		} catch (ParseException e) {
152 			fail("failed.to.parse.french");
153 		}
154 		
155 		try {
156 			parser.parseTimestamp("22 dec 2002");
157 			fail("incorrect.language");
158 		} catch (ParseException e) {
159 			// this is the success case
160 		}
161 		try {
162 			parser.parseTimestamp("29 f\u00e9v 2002");
163 			fail("nonexistent.date");
164 		} catch (ParseException e) {
165 			// this is the success case
166 		}
167 
168 		try {
169 			parser.parseTimestamp("22 ao\u00fb 30:02");
170 			fail("bad.hour");
171 		} catch (ParseException e) {
172 			// this is the success case
173 		}
174 		
175 		try {
176 			parser.parseTimestamp("22 ao\u00fb 20:74");
177 			fail("bad.minute");
178 		} catch (ParseException e) {
179 			// this is the success case
180 		}
181 		try {
182 			parser.parseTimestamp("28 ao\u00fb 20:02");
183 		} catch (ParseException e) {
184 			fail("failed.to.parse.french.recent");
185 		}
186 	}
187 	
188     /**
189      * Method suite.
190      *
191      * @return TestSuite
192      */
193     public static TestSuite suite()
194     {
195         return(new TestSuite(FTPTimestampParserImplTest.class));
196     }
197 
198 
199 
200 }