/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.tools.ant.taskdefs.optional.net; import java.io.File; import java.lang.reflect.Constructor; import java.util.Locale; import java.util.Vector; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Task; import org.apache.tools.ant.types.EnumeratedAttribute; import org.apache.tools.ant.types.FileSet; import org.apache.tools.ant.types.Path; import org.apache.tools.ant.util.LoaderUtils; import org.apache.tools.ant.util.Retryable; import org.apache.tools.ant.util.SplitClassLoader; /** * Basic FTP client. Performs the following actions: *
newer
*
* @param timeDiffMillis number of milliseconds
*
* @since ant 1.6
*/
public void setTimeDiffMillis(long timeDiffMillis) {
this.timeDiffMillis = timeDiffMillis;
}
public long getTimeDiffMillis() {
return timeDiffMillis;
}
/**
* "true" to find out automatically the time difference
* between local and remote machine.
*
* This requires right to create
* and delete a temporary file in the remote directory.
*
* @param timeDiffAuto true = find automatically the time diff
*
* @since ant 1.6
*/
public void setTimeDiffAuto(boolean timeDiffAuto) {
this.timeDiffAuto = timeDiffAuto;
}
public boolean isTimeDiffAuto() {
return timeDiffAuto;
}
/**
* Set to true to preserve modification times for "gotten" files.
*
* @param preserveLastModified if true preserver modification times.
*/
public void setPreserveLastModified(boolean preserveLastModified) {
this.preserveLastModified = preserveLastModified;
}
public boolean isPreserveLastModified() {
return preserveLastModified;
}
/**
* Set to true to transmit only files that are new or changed from their
* remote counterparts. The default is to transmit all files.
*
* @param depends if true only transfer newer files.
*/
public void setDepends(boolean depends) {
this.newerOnly = depends;
}
/**
* Sets the remote file separator character. This normally defaults to the
* Unix standard forward slash, but can be manually overridden using this
* call if the remote server requires some other separator. Only the first
* character of the string is used.
*
* @param separator the file separator on the remote system.
*/
public void setSeparator(String separator) {
remoteFileSep = separator;
}
public String getSeparator() {
return remoteFileSep;
}
/**
* Sets the file permission mode (Unix only) for files sent to the
* server.
*
* @param theMode unix style file mode for the files sent to the remote
* system.
*/
public void setChmod(String theMode) {
this.chmod = theMode;
}
public String getChmod() {
return chmod;
}
/**
* Sets the default mask for file creation on a unix server.
*
* @param theUmask unix style umask for files created on the remote server.
*/
public void setUmask(String theUmask) {
this.umask = theUmask;
}
public String getUmask() {
return umask;
}
/**
* A set of files to upload or download
*
* @param set the set of files to be added to the list of files to be
* transferred.
*/
public void addFileset(FileSet set) {
filesets.addElement(set);
}
public VectorFTPClientConfig
remote system key.
*
* @param systemKey the key to be set - BUT if blank
* the default value of null (which signifies "autodetect") will be kept.
* @see org.apache.commons.net.ftp.FTPClientConfig
*/
public void setSystemTypeKey(FTPSystemType systemKey) {
if (systemKey != null && !systemKey.getValue().isEmpty()) {
this.systemTypeKey = systemKey;
configurationHasBeenSet();
}
}
/**
* Sets the defaultDateFormatConfig attribute.
* @param defaultDateFormat configuration to be set, unless it is
* null or empty string, in which case ignored.
* @see org.apache.commons.net.ftp.FTPClientConfig
*/
public void setDefaultDateFormatConfig(String defaultDateFormat) {
if (defaultDateFormat != null && !defaultDateFormat.isEmpty()) {
this.defaultDateFormatConfig = defaultDateFormat;
configurationHasBeenSet();
}
}
/**
* Sets the recentDateFormatConfig attribute.
* @param recentDateFormat configuration to be set, unless it is
* null or empty string, in which case ignored.
* @see org.apache.commons.net.ftp.FTPClientConfig
*/
public void setRecentDateFormatConfig(String recentDateFormat) {
if (recentDateFormat != null && !recentDateFormat.isEmpty()) {
this.recentDateFormatConfig = recentDateFormat;
configurationHasBeenSet();
}
}
/**
* Sets the serverLanguageCode attribute.
* @param serverLanguageCode configuration to be set, unless it is
* null or empty string, in which case ignored.
* @see org.apache.commons.net.ftp.FTPClientConfig
*/
public void setServerLanguageCodeConfig(String serverLanguageCode) {
if (serverLanguageCode != null && !serverLanguageCode.isEmpty()) {
this.serverLanguageCodeConfig = serverLanguageCode;
configurationHasBeenSet();
}
}
/**
* Sets the serverTimeZoneConfig attribute.
* @param serverTimeZoneId configuration to be set, unless it is
* null or empty string, in which case ignored.
* @see org.apache.commons.net.ftp.FTPClientConfig
*/
public void setServerTimeZoneConfig(String serverTimeZoneId) {
if (serverTimeZoneId != null && !serverTimeZoneId.isEmpty()) {
this.serverTimeZoneConfig = serverTimeZoneId;
configurationHasBeenSet();
}
}
/**
* Sets the shortMonthNamesConfig attribute
*
* @param shortMonthNames configuration to be set, unless it is
* null or empty string, in which case ignored.
* @see org.apache.commons.net.ftp.FTPClientConfig
*/
public void setShortMonthNamesConfig(String shortMonthNames) {
if (shortMonthNames != null && !shortMonthNames.isEmpty()) {
this.shortMonthNamesConfig = shortMonthNames;
configurationHasBeenSet();
}
}
/**
* Defines how many times to retry executing FTP command before giving up.
* Default is 0 - try once and if failure then give up.
*
* @param retriesAllowed number of retries to allow. -1 means
* keep trying forever. "forever" may also be specified as a
* synonym for -1.
*/
public void setRetriesAllowed(String retriesAllowed) {
if ("FOREVER".equalsIgnoreCase(retriesAllowed)) {
this.retriesAllowed = Retryable.RETRY_FOREVER;
} else {
try {
int retries = Integer.parseInt(retriesAllowed);
if (retries < Retryable.RETRY_FOREVER) {
throw new BuildException(
"Invalid value for retriesAllowed attribute: %s",
retriesAllowed);
}
this.retriesAllowed = retries;
} catch (NumberFormatException px) {
throw new BuildException(
"Invalid value for retriesAllowed attribute: %s",
retriesAllowed);
}
}
}
public int getRetriesAllowed() {
return retriesAllowed;
}
/**
* @return Returns the systemTypeKey.
*/
@Override
public String getSystemTypeKey() {
return systemTypeKey.getValue();
}
/**
* @return Returns the defaultDateFormatConfig.
*/
@Override
public String getDefaultDateFormatConfig() {
return defaultDateFormatConfig;
}
/**
* @return Returns the recentDateFormatConfig.
*/
@Override
public String getRecentDateFormatConfig() {
return recentDateFormatConfig;
}
/**
* @return Returns the serverLanguageCodeConfig.
*/
@Override
public String getServerLanguageCodeConfig() {
return serverLanguageCodeConfig;
}
/**
* @return Returns the serverTimeZoneConfig.
*/
@Override
public String getServerTimeZoneConfig() {
return serverTimeZoneConfig;
}
/**
* @return Returns the shortMonthNamesConfig.
*/
@Override
public String getShortMonthNamesConfig() {
return shortMonthNamesConfig;
}
/**
* @return Returns the timestampGranularity.
*/
public Granularity getTimestampGranularity() {
return timestampGranularity;
}
/**
* Sets the timestampGranularity attribute
* @param timestampGranularity The timestampGranularity to set.
*/
public void setTimestampGranularity(Granularity timestampGranularity) {
if (null == timestampGranularity || timestampGranularity.getValue().isEmpty()) {
return;
}
this.timestampGranularity = timestampGranularity;
}
/**
* Sets the siteCommand attribute. This attribute
* names the command that will be executed if the action
* is "site".
* @param siteCommand The siteCommand to set.
*/
public void setSiteCommand(String siteCommand) {
this.siteCommand = siteCommand;
}
public String getSiteCommand() {
return siteCommand;
}
/**
* Sets the initialSiteCommand attribute. This attribute
* names a site command that will be executed immediately
* after connection.
* @param initialCommand The initialSiteCommand to set.
*/
public void setInitialSiteCommand(String initialCommand) {
this.initialSiteCommand = initialCommand;
}
public String getInitialSiteCommand() {
return initialSiteCommand;
}
public long getGranularityMillis() {
return this.granularityMillis;
}
public void setGranularityMillis(long granularity) {
this.granularityMillis = granularity;
}
/**
* Whether to verify that data and control connections are
* connected to the same remote host.
*
* @param b boolean
* @since Ant 1.8.0
*/
public void setEnableRemoteVerification(boolean b) {
enableRemoteVerification = b;
}
public boolean getEnableRemoteVerification() {
return enableRemoteVerification;
}
/**
* Checks to see that all required parameters are set.
*
* @throws BuildException if the configuration is not valid.
*/
protected void checkAttributes() throws BuildException {
if (server == null) {
throw new BuildException("server attribute must be set!");
}
if (userid == null) {
throw new BuildException("userid attribute must be set!");
}
if (password == null) {
throw new BuildException("password attribute must be set!");
}
if (action == LIST_FILES && listing == null) {
throw new BuildException(
"listing attribute must be set for list action!");
}
if (action == MK_DIR && remotedir == null) {
throw new BuildException(
"remotedir attribute must be set for mkdir action!");
}
if (action == CHMOD && chmod == null) {
throw new BuildException(
"chmod attribute must be set for chmod action!");
}
if (action == SITE_CMD && siteCommand == null) {
throw new BuildException(
"sitecommand attribute must be set for site action!");
}
if (this.isConfigurationSet) {
try {
Class.forName("org.apache.commons.net.ftp.FTPClientConfig");
} catch (ClassNotFoundException e) {
throw new BuildException(
"commons-net.jar >= 1.4.0 is required for at least one of the attributes specified.");
}
}
}
/**
* Runs the task.
*
* @throws BuildException if the task fails or is not configured
* correctly.
*/
@Override
public void execute() throws BuildException {
checkAttributes();
try {
setupFTPDelegate();
delegate.doFTP();
} finally {
if (mirrorLoader instanceof SplitClassLoader) {
((SplitClassLoader) mirrorLoader).cleanup();
}
mirrorLoader = null;
}
}
public Path createClasspath() {
if (classpath == null) {
classpath = new Path(getProject());
}
return classpath;
}
protected void setupFTPDelegate() {
ClassLoader myLoader = FTPTask.class.getClassLoader();
if (mustSplit()) {
mirrorLoader =
new SplitClassLoader(myLoader, classpath, getProject(),
new String[] {
"FTPTaskMirrorImpl",
"FTPConfigurator"
});
} else {
mirrorLoader = myLoader;
}
delegate = createMirror(this, mirrorLoader);
}
private static boolean mustSplit() {
return LoaderUtils.getResourceSource(FTPTask.class.getClassLoader(),
"/org/apache/commons/net/"
+ "ftp/FTP.class")
== null;
}
private static FTPTaskMirror createMirror(FTPTask task,
ClassLoader loader) {
try {
loader.loadClass("org.apache.commons.net.ftp.FTP"); // sanity check
} catch (ClassNotFoundException e) {
throw new BuildException(
"The 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"
};
/**
* Get the valid values.
* @return the list of valid Granularity values
*/
@Override
public String[] getValues() {
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.ENGLISH);
if (granularityU.isEmpty()) {
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"
};
/**
* Get the valid values.
* @return the list of valid system types.
*/
@Override
public String[] getValues() {
return VALID_SYSTEM_TYPES;
}
static final FTPSystemType getDefault() {
FTPSystemType ftpst = new FTPSystemType();
ftpst.setValue("");
return ftpst;
}
}
}