diff --git a/src/etc/testcases/taskdefs/optional/net/ftp.xml b/src/etc/testcases/taskdefs/optional/net/ftp.xml
index 5603ce7a8..2fb6e3ca2 100644
--- a/src/etc/testcases/taskdefs/optional/net/ftp.xml
+++ b/src/etc/testcases/taskdefs/optional/net/ftp.xml
@@ -14,6 +14,7 @@
timestampGranularity
attribute.
+
+ * A timestamp adjustment may be used in file transfers for checking
+ * uptodateness. MINUTE means to add one minute to the server
+ * timestamp. This is done because FTP servers typically list
+ * timestamps HH:mm and client FileSystems typically use HH:mm:ss.
+ *
+ * The default is to use MINUTE for PUT actions and NONE for GET
+ * actions, since GETs have the preserveLastModified
+ * option, which takes care of the problem in most use cases where
+ * this level of granularity is an issue.
+ *
+ */
+ public static class Granularity extends EnumeratedAttribute {
+
+ private static final String[] VALID_GRANULARITIES = {
+ "", "MINUTE", "NONE"
+ };
+ /*
+ * @return the list of valid Granularity values
+ */
+ public String[] getValues() {
+ // TODO Auto-generated method stub
+ return VALID_GRANULARITIES;
+ }
+ /**
+ * returns the number of milliseconds associated with
+ * the attribute, which can vary in some cases depending
+ * on the value of the action parameter.
+ * @param action SEND_FILES or GET_FILES
+ * @return the number of milliseconds associated with
+ * the attribute, in the context of the supplied action
+ */
+ public long getMilliseconds(int action) {
+ String granularityU = getValue().toUpperCase(Locale.US);
+ long granularity = 0L;
+ if ("".equals(granularityU)) {
+ if (action == SEND_FILES) {
+ return GRANULARITY_MINUTE;
+ }
+ } else if ("MINUTE".equals(granularityU)) {
+ return GRANULARITY_MINUTE;
+ }
+ return 0L;
+ }
+ static final Granularity getDefault() {
+ Granularity g = new Granularity();
+ g.setValue("");
+ return g;
+ }
+
+ }
+ /**
+ * one of the valid system type keys recognized by the systemTypeKey
+ * attribute.
+ */
+ public static class FTPSystemType extends EnumeratedAttribute {
+
+ private static final String[] VALID_SYSTEM_TYPES = {
+ "", "UNIX", "VMS", "WINDOWS", "OS/2", "OS/400",
+ "MVS"
+ };
+
+
+ /*
+ * @return the list of valid system types.
+ */
+ public String[] getValues() {
+ return VALID_SYSTEM_TYPES;
+ }
+
+ static final FTPSystemType getDefault() {
+ FTPSystemType ftpst = new FTPSystemType();
+ ftpst.setValue("");
+ return ftpst;
+ }
+ }
}
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/net/FTPConfigurator.java b/src/main/org/apache/tools/ant/taskdefs/optional/net/FTPConfigurator.java
index 6fda45f1c..aafda1a02 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/net/FTPConfigurator.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/net/FTPConfigurator.java
@@ -37,14 +37,17 @@ class FTPConfigurator {
* @return the client as configured.
*/
static FTPClient configure(FTPClient client, FTP task) {
+ task.log("custom configuration", Project.MSG_VERBOSE);
FTPClientConfig config;
String systemTypeKey = task.getSystemTypeKey();
- if (systemTypeKey != null) {
+ if (systemTypeKey != null && !"".equals(systemTypeKey)) {
config = new FTPClientConfig(systemTypeKey);
task.log("custom config: system key = "
+ systemTypeKey, Project.MSG_VERBOSE);
} else {
config = new FTPClientConfig();
+ task.log("custom config: system key = default (UNIX)",
+ Project.MSG_VERBOSE);
}
String defaultDateFormatConfig = task.getDefaultDateFormatConfig();
diff --git a/src/testcases/org/apache/tools/ant/taskdefs/optional/net/FTPTest.java b/src/testcases/org/apache/tools/ant/taskdefs/optional/net/FTPTest.java
index fdef6b3be..9f9636ad9 100644
--- a/src/testcases/org/apache/tools/ant/taskdefs/optional/net/FTPTest.java
+++ b/src/testcases/org/apache/tools/ant/taskdefs/optional/net/FTPTest.java
@@ -16,25 +16,23 @@
*/
package org.apache.tools.ant.taskdefs.optional.net;
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+
+import org.apache.commons.net.ftp.FTPClient;
import org.apache.tools.ant.BuildEvent;
import org.apache.tools.ant.BuildFileTest;
-import org.apache.tools.ant.BuildListener;
-import org.apache.tools.ant.BuildLogger;
import org.apache.tools.ant.DefaultLogger;
import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.condition.Os;
import org.apache.tools.ant.types.FileSet;
-import org.apache.tools.ant.taskdefs.optional.net.FTP;
-import org.apache.tools.ant.util.JavaEnvUtils;
import org.apache.tools.ant.util.regexp.RegexpMatcher;
import org.apache.tools.ant.util.regexp.RegexpMatcherFactory;
-import org.apache.tools.ant.taskdefs.condition.Os;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Vector;
-
-import org.apache.commons.net.ftp.FTPClient;
public class FTPTest extends BuildFileTest{
// keep track of what operating systems are supported here.
@@ -592,6 +590,42 @@ public class FTPTest extends BuildFileTest{
}
}
+ /**
+ * This class enables the use of the log to count the number
+ * of times a message has been emitted.
+ */
+ private class LogCounter extends DefaultLogger {
+ private Map searchMap = new HashMap();
+ private int matchCount;
+
+ public void addLogMessageToSearch(String message) {
+ searchMap.put(message, new Integer(0));
+ }
+
+ /*
+ * @param event the build event that is being logged.
+ */
+ public void messageLogged(BuildEvent event) {
+ String message = event.getMessage();
+ Integer mcnt = (Integer) searchMap.get(message);
+ if (null != mcnt) {
+ searchMap.put(message, new Integer(mcnt.intValue() + 1));
+ }
+ super.messageLogged(event);
+ }
+
+ /**
+ * @return the number of times that the looked for message was sent
+ * to the log
+ */
+ public int getMatchCount(String message) {
+ Integer mcnt = (Integer) searchMap.get(message);
+ if (null != mcnt) {
+ return mcnt.intValue();
+ }
+ return 0;
+ }
+ }
/**
* Tests the combination of the newer parameter and the
* serverTimezoneConfig parameter in the PUT action. The default
@@ -619,7 +653,76 @@ public class FTPTest extends BuildFileTest{
getProject().executeTarget("timed.test.get.older");
assertEquals(3, log.getCount());
}
+
+
+ /**
+ * Tests that the presence of one of the server config params forces
+ * the system type to Unix if not specified.
+ */
+ public void testConfiguration1() {
+ int[] expectedCounts = {
+ 1,1,0,1,0,0
+ };
+ performConfigTest("configuration.1", expectedCounts);
+
+ }
+ /**
+ * Tests the systemTypeKey attribute.
+ */
+ public void testConfiguration2() {
+ int[] expectedCounts = {
+ 1,0,0,1,1,0
+ };
+ performConfigTest("configuration.2", expectedCounts);
+
+ }
+
+ /**
+ * Tests the systemTypeKey attribute with UNIX specified.
+ */
+ public void testConfiguration3() {
+ int[] expectedCounts = {
+ 1,0,1,0,0,1
+ };
+ performConfigTest("configuration.3", expectedCounts);
+
+ }
+ /**
+ * Tests the systemTypeKey attribute.
+ */
+ public void testConfigurationNone() {
+ int[] expectedCounts = {
+ 0,0,0,0,0,0
+ };
+ performConfigTest("configuration.none", expectedCounts);
+
+ }
+
+ private void performConfigTest(String target, int[] expectedCounts) {
+ String[] messages = new String[]{
+ "custom configuration",
+ "custom config: system key = default (UNIX)",
+ "custom config: system key = UNIX",
+ "custom config: server time zone ID = " + getProject().getProperty("ftp.server.timezone"),
+ "custom config: system key = WINDOWS",
+ "custom config: default date format = yyyy/MM/dd HH:mm"
+
+ };
+ LogCounter counter = new LogCounter();
+ for (int i=0; i < messages.length; i++) {
+ counter.addLogMessageToSearch(messages[i]);
+ }
+
+ getProject().addBuildListener(counter);
+ getProject().executeTarget(target);
+ for (int i=0; i < messages.length; i++) {
+ assertEquals("target "+target+":message "+ i, expectedCounts[i], counter.getMatchCount(messages[i]));
+ }
+
+ }
+
+
/**
* this test is inspired by a user reporting that deletions of directories with the ftp task do not work
*/