You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by bo...@locus.apache.org on 2000/11/08 18:01:32 UTC
cvs commit: jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/net FTP.java TelnetTask.java
bodewig 00/11/08 09:01:22
Modified: . build.xml
src/main/org/apache/tools/ant/taskdefs defaults.properties
Added: src/main/org/apache/tools/ant/taskdefs/optional/net FTP.java
TelnetTask.java
Removed: src/main/org/apache/tools/ant/taskdefs/optional FTP.java
Log:
Added a new optional telnet task.
Submitted by: Scott Carlson <sc...@yahoo.com>
Moved optional FTP task to the new net package.
Revision Changes Path
1.96 +2 -2 jakarta-ant/build.xml
Index: build.xml
===================================================================
RCS file: /home/cvs/jakarta-ant/build.xml,v
retrieving revision 1.95
retrieving revision 1.96
diff -u -r1.95 -r1.96
--- build.xml 2000/11/07 20:42:48 1.95
+++ build.xml 2000/11/08 17:00:07 1.96
@@ -68,7 +68,7 @@
<available property="ejb.DDCreator.present" classname="weblogic.ejb.utils.DDCreator" />
<available property="ejb.wls.present" classname="weblogic.Server" />
<available property="junit.present" classname="junit.framework.TestCase" />
- <available property="ftp.present" classname="com.oroinc.net.ftp.FTPClient" />
+ <available property="netcomp.present" classname="com.oroinc.net.ftp.FTPClient" />
<available property="starteam.present" classname="com.starbase.util.Platform" />
<available property="antlr.present" classname="antlr.Tool" />
<available property="vaj.present" classname="com.ibm.ivj.util.base.Workspace" />
@@ -106,7 +106,7 @@
<exclude name="**/EjbJar.java" unless="jdk1.2+" />
<exclude name="**/*DeploymentTool.java" unless="jdk1.2+" />
<exclude name="**/junit/*" unless="junit.present" />
- <exclude name="**/FTP*.java" unless="ftp.present" />
+ <exclude name="**/net/*.java" unless="netcomp.present" />
<exclude name="**/AntStarTeam*.java" unless="starteam.present" />
<exclude name="**/ANTLR.java" unless="antlr.present" />
<exclude name="**/ide/VAJ*.java" unless="vaj.present" />
1.51 +2 -1 jakarta-ant/src/main/org/apache/tools/ant/taskdefs/defaults.properties
Index: defaults.properties
===================================================================
RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/defaults.properties,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -r1.50 -r1.51
--- defaults.properties 2000/11/07 20:31:00 1.50
+++ defaults.properties 2000/11/08 17:00:25 1.51
@@ -56,7 +56,7 @@
mparse=org.apache.tools.ant.taskdefs.optional.metamata.MParse
junit=org.apache.tools.ant.taskdefs.optional.junit.JUnitTask
cab=org.apache.tools.ant.taskdefs.optional.Cab
-ftp=org.apache.tools.ant.taskdefs.optional.FTP
+ftp=org.apache.tools.ant.taskdefs.optional.net.FTP
javacc=org.apache.tools.ant.taskdefs.optional.javacc.JavaCC
jjtree=org.apache.tools.ant.taskdefs.optional.javacc.JJTree
starteam=org.apache.tools.ant.taskdefs.optional.scm.AntStarTeamCheckOut
@@ -70,6 +70,7 @@
vajload=org.apache.tools.ant.taskdefs.optional.ide.VAJLoadProjects
vajexport=org.apache.tools.ant.taskdefs.optional.ide.VAJExport
vajimport=org.apache.tools.ant.taskdefs.optional.ide.VAJImport
+telnet=org.apache.tools.ant.taskdefs.optional.net.TelnetTask
# deprecated ant tasks (kept for back compatibility)
javadoc2=org.apache.tools.ant.taskdefs.Javadoc
1.1 jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/net/FTP.java
Index: FTP.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.tools.ant.taskdefs.optional.net;
import org.apache.tools.ant.*;
import org.apache.tools.ant.types.*;
import java.io.*;
import java.net.*;
import java.util.*;
import com.oroinc.net.ftp.*;
/**
* Basic FTP client that performs the following actions:
* <ul>
* <li><strong>send</strong> - send files to a remote server. This is the
* default action.</li>
* <li><strong>get</strong> - retrive files from a remote server.</li>
* <li><strong>del</strong> - delete files from a remote server.</li>
* <li><strong>list</strong> - create a file listing.</li>
* </ul>
*
* @author Roger Vaughn <a href="mailto:rvaughn@seaconinc.com">rvaughn@seaconinc.com</a>
* @author Glenn McAllister <a href="mailto:glennm@ca.ibm.com">glennm@ca.ibm.com</a>
*/
public class FTP
extends Task
{
protected final static int SEND_FILES = 0;
protected final static int GET_FILES = 1;
protected final static int DEL_FILES = 2;
protected final static int LIST_FILES = 3;
private String remotedir;
private String server;
private String userid;
private String password;
private File listing;
private boolean binary = true;
private boolean verbose = false;
private boolean newerOnly = false;
private int action = SEND_FILES;
private Vector filesets = new Vector();
private Vector dirCache = new Vector();
private int transferred = 0;
private String remoteFileSep = "/";
private int port = 21;
protected final static String[] ACTION_STRS = {
"sending",
"getting",
"deleting",
"listing"
};
protected final static String[] COMPLETED_ACTION_STRS = {
"sent",
"retrieved",
"deleted",
"listed"
};
protected class FTPDirectoryScanner extends DirectoryScanner {
protected FTPClient ftp = null;
public FTPDirectoryScanner(FTPClient ftp) {
super();
this.ftp = ftp;
}
public void scan() {
if (includes == null) {
// No includes supplied, so set it to 'matches all'
includes = new String[1];
includes[0] = "**";
}
if (excludes == null) {
excludes = new String[0];
}
filesIncluded = new Vector();
filesNotIncluded = new Vector();
filesExcluded = new Vector();
dirsIncluded = new Vector();
dirsNotIncluded = new Vector();
dirsExcluded = new Vector();
try {
String cwd = ftp.printWorkingDirectory();
scandir(".", "", true); // always start from the current ftp working dir
ftp.changeWorkingDirectory(cwd);
} catch (IOException e) {
throw new BuildException("Unable to scan FTP server: ", e);
}
}
protected void scandir(String dir, String vpath, boolean fast) {
try {
if (!ftp.changeWorkingDirectory(dir)) {
return;
}
FTPFile[] newfiles = ftp.listFiles();
if (newfiles == null) {
return; // no files in directory.
}
for (int i = 0; i < newfiles.length; i++) {
FTPFile file = newfiles[i];
String name = vpath + file.getName();
if (file.isDirectory()) {
if (isIncluded(name)) {
if (!isExcluded(name)) {
dirsIncluded.addElement(name);
if (fast) {
scandir(name, name + File.separator, fast);
}
} else {
dirsExcluded.addElement(name);
}
} else {
dirsNotIncluded.addElement(name);
if (fast && couldHoldIncluded(name)) {
scandir(name, name + File.separator, fast);
}
}
if (!fast) {
scandir(name, name + File.separator, fast);
}
} else {
if (file.isFile()) {
if (isIncluded(name)) {
if (!isExcluded(name)) {
filesIncluded.addElement(name);
} else {
filesExcluded.addElement(name);
}
} else {
filesNotIncluded.addElement(name);
}
}
}
}
} catch (IOException e) {
throw new BuildException("Error while communicating with FTP server: ", e);
}
}
}
/**
* Sets the remote directory where files will be placed. This may
* be a relative or absolute path, and must be in the path syntax
* expected by the remote server. No correction of path syntax will
* be performed.
*/
public void setRemotedir(String dir)
{
this.remotedir = dir;
}
/**
* Sets the FTP server to send files to.
*/
public void setServer(String server)
{
this.server = server;
}
/**
* Sets the FTP port used by the remote server.
*/
public void setPort(int port)
{
this.port = port;
}
/**
* Sets the login user id to use on the specified server.
*/
public void setUserid(String userid)
{
this.userid = userid;
}
/**
* Sets the login password for the given user id.
*/
public void setPassword(String password)
{
this.password = password;
}
/**
* Specifies whether to use binary-mode or text-mode transfers. Set
* to true to send binary mode. Binary mode is enabled by default.
*/
public void setBinary(boolean binary)
{
this.binary = binary;
}
/**
* Set to true to receive notification about each file as it is
* transferred.
*/
public void setVerbose(boolean verbose)
{
this.verbose = verbose;
}
/**
* Set to true to transmit only files that are new or changed from their
* remote counterparts. The default is to transmit all files.
*/
public void setNewer(boolean newer)
{
this.newerOnly = newer;
}
/**
* A synonym for setNewer. Set to true to transmit only new or changed
* 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.
*/
public void setSeparator(String separator)
{
remoteFileSep = separator;
}
/**
* Adds a set of files (nested fileset attribute).
*/
public void addFileset(FileSet set) {
filesets.addElement(set);
}
/**
* Sets the FTP action to be taken. Currently accepts "put", "get",
* "del", and "list".
*/
public void setAction(String action) throws BuildException
{
if (action.toLowerCase().equals("send") ||
action.toLowerCase().equals("put"))
{
this.action = SEND_FILES;
}
else if (action.toLowerCase().equals("recv") ||
action.toLowerCase().equals("get"))
{
this.action = GET_FILES;
}
else if (action.toLowerCase().equals("del") ||
action.toLowerCase().equals("delete" ))
{
this.action = DEL_FILES;
}
else if (action.toLowerCase().equals("list"))
{
this.action = LIST_FILES;
}
else
{
throw new BuildException("action " + action + " is not supported");
}
}
/**
* The output file for the "list" action. This attribute is ignored for
* any other actions.
*/
public void setListing(File listing) throws BuildException {
this.listing = listing;
}
/**
* Checks to see that all required parameters are set.
*/
protected void checkConfiguration() 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!");
}
}
/**
* For each file in the fileset, do the appropriate action: send, get, delete,
* or list.
*/
protected int transferFiles(FTPClient ftp, FileSet fs)
throws IOException, BuildException
{
FileScanner ds;
if (action == SEND_FILES) {
ds = fs.getDirectoryScanner(project);
} else {
ds = new FTPDirectoryScanner(ftp);
fs.setupDirectoryScanner(ds, project);
ds.scan();
}
String[] dsfiles = ds.getIncludedFiles();
String dir = null;
if ((ds.getBasedir() == null) && ((action == SEND_FILES) || (action == GET_FILES))) {
throw new BuildException( "the dir attribute must be set for send and get actions" );
} else {
if ((action == SEND_FILES) || (action == GET_FILES)) {
dir = ds.getBasedir().getAbsolutePath();
}
}
// If we are doing a listing, we need the output stream created now.
BufferedWriter bw = null;
if (action == LIST_FILES) {
File pd = new File(listing.getParent());
if (!pd.exists()) {
pd.mkdirs();
}
bw = new BufferedWriter(new FileWriter(listing));
}
for (int i = 0; i < dsfiles.length; i++)
{
switch (action) {
case SEND_FILES: {
sendFile(ftp, dir, dsfiles[i]);
break;
}
case GET_FILES: {
getFile(ftp, dir, dsfiles[i]);
break;
}
case DEL_FILES: {
delFile(ftp, dsfiles[i]);
break;
}
case LIST_FILES: {
listFile(ftp, bw, dsfiles[i]);
break;
}
default: {
throw new BuildException("unknown ftp action " + action );
}
}
}
if (action == LIST_FILES) {
bw.close();
}
return dsfiles.length;
}
/**
* Sends all files specified by the configured filesets to the remote
* server.
*/
protected void transferFiles(FTPClient ftp)
throws IOException, BuildException
{
transferred = 0;
if (filesets.size() == 0)
{
throw new BuildException("at least one fileset must be specified.");
}
else
{
// get files from filesets
for (int i = 0; i < filesets.size(); i++)
{
FileSet fs = (FileSet) filesets.elementAt(i);
if (fs != null)
{
transferFiles(ftp, fs);
}
}
}
log(transferred + " files " + COMPLETED_ACTION_STRS[action]);
}
/**
* Correct a file path to correspond to the remote host requirements.
* This implementation currently assumes that the remote end can
* handle Unix-style paths with forward-slash separators. This can
* be overridden with the <code>separator</code> task parameter. No
* attempt is made to determine what syntax is appropriate for the
* remote host.
*/
protected String resolveFile(String file)
{
return file.replace(System.getProperty("file.separator").charAt(0),
remoteFileSep.charAt(0));
}
/**
* Creates all parent directories specified in a complete relative
* pathname. Attempts to create existing directories will not cause
* errors.
*/
protected void createParents(FTPClient ftp, String filename)
throws IOException, BuildException
{
Vector parents = new Vector();
File dir = new File(filename);
String dirname;
while ((dirname = dir.getParent()) != null)
{
dir = new File(dirname);
parents.addElement(dir);
}
for (int i = parents.size() - 1; i >= 0; i--)
{
dir = (File)parents.elementAt(i);
if (!dirCache.contains(dir))
{
log("creating remote directory " + resolveFile(dir.getPath()),
Project.MSG_VERBOSE);
ftp.makeDirectory(resolveFile(dir.getPath()));
if (!FTPReply.isPositiveCompletion(ftp.getReplyCode()) &&
(ftp.getReplyCode() != 550))
{
throw new BuildException(
"could not create directory: " +
ftp.getReplyString());
}
dirCache.addElement(dir);
}
}
}
/**
* Checks to see if the remote file is current as compared with the
* local file. Returns true if the remote file is up to date.
*/
protected boolean isUpToDate(FTPClient ftp, File localFile, String remoteFile)
throws IOException, BuildException
{
log("checking date for " + remoteFile, Project.MSG_VERBOSE);
FTPFile[] files = ftp.listFiles(remoteFile);
if (!FTPReply.isPositiveCompletion(ftp.getReplyCode()))
{
throw new BuildException(
"could not date test remote file: " +
ftp.getReplyString());
}
if (files == null)
{
return false;
}
long remoteTimestamp = files[0].getTimestamp().getTime().getTime();
long localTimestamp = localFile.lastModified();
if (this.action == SEND_FILES) {
return remoteTimestamp > localTimestamp;
} else {
return localTimestamp > remoteTimestamp;
}
}
/**
* Sends a single file to the remote host.
* <code>filename</code> may contain a relative path specification.
* When this is the case, <code>sendFile</code> will attempt to create
* any necessary parent directories before sending the file. The file
* will then be sent using the entire relative path spec - no attempt
* is made to change directories. It is anticipated that this may
* eventually cause problems with some FTP servers, but it simplifies
* the coding.
*/
protected void sendFile(FTPClient ftp, String dir, String filename)
throws IOException, BuildException
{
InputStream instream = null;
try
{
File file = project.resolveFile(new File(dir, filename).getPath());
if (newerOnly && isUpToDate(ftp, file, resolveFile(filename)))
return;
if (verbose)
{
log("transferring " + file.getAbsolutePath());
}
instream = new BufferedInputStream(new FileInputStream(file));
createParents(ftp, filename);
ftp.storeFile(resolveFile(filename), instream);
if (!FTPReply.isPositiveCompletion(ftp.getReplyCode()))
{
throw new BuildException(
"could not transfer file: " +
ftp.getReplyString());
}
log("File " + file.getAbsolutePath() + " copied to " + server,
Project.MSG_VERBOSE);
transferred++;
}
finally
{
if (instream != null)
{
try
{
instream.close();
}
catch(IOException ex)
{
// ignore it
}
}
}
}
/**
* Delete a file from the remote host.
*/
protected void delFile(FTPClient ftp, String filename)
throws IOException, BuildException {
if (verbose) {
log("deleting " + filename);
}
if (!ftp.deleteFile(resolveFile(filename))) {
throw new BuildException("could not delete file: " + ftp.getReplyString());
}
log("File " + filename + " deleted from " + server, Project.MSG_VERBOSE);
transferred++;
}
/**
* Retrieve a single file to the remote host.
* <code>filename</code> may contain a relative path specification.
* The file will then be retreived using the entire relative path spec -
* no attempt is made to change directories. It is anticipated that this may
* eventually cause problems with some FTP servers, but it simplifies
* the coding.
*/
protected void getFile(FTPClient ftp, String dir, String filename)
throws IOException, BuildException
{
OutputStream outstream = null;
try
{
File file = project.resolveFile(new File(dir, filename).getPath());
if (newerOnly && isUpToDate(ftp, file, resolveFile(filename)))
return;
if (verbose)
{
log("transferring " + filename + " to " + file.getAbsolutePath());
}
File pdir = new File(file.getParent()); // stay 1.1 compatible
if (!pdir.exists()) {
pdir.mkdirs();
}
outstream = new BufferedOutputStream(new FileOutputStream(file));
ftp.retrieveFile(resolveFile(filename), outstream);
if (!FTPReply.isPositiveCompletion(ftp.getReplyCode()))
{
throw new BuildException(
"could not transfer file: " +
ftp.getReplyString());
}
log("File " + file.getAbsolutePath() + " copied from " + server,
Project.MSG_VERBOSE);
transferred++;
}
finally
{
if (outstream != null)
{
try
{
outstream.close();
}
catch(IOException ex)
{
// ignore it
}
}
}
}
/**
* List information about a single file from the remote host.
* <code>filename</code> may contain a relative path specification.
* The file listing will then be retrieved using the entire relative path spec
* - no attempt is made to change directories. It is anticipated that this may
* eventually cause problems with some FTP servers, but it simplifies
* the coding.
*/
protected void listFile(FTPClient ftp, BufferedWriter bw, String filename)
throws IOException, BuildException
{
if (verbose) {
log("listing " + filename);
}
FTPFile ftpfile = ftp.listFiles(resolveFile(filename))[0];
bw.write(ftpfile.toString());
bw.newLine();
transferred++;
}
/**
* Runs the task.
*/
public void execute()
throws BuildException
{
checkConfiguration();
FTPClient ftp = null;
try
{
log("Opening FTP connection to " + server, Project.MSG_VERBOSE);
ftp = new FTPClient();
ftp.connect(server, port);
if (!FTPReply.isPositiveCompletion(ftp.getReplyCode()))
{
throw new BuildException("FTP connection failed: " + ftp.getReplyString());
}
log("connected", Project.MSG_VERBOSE);
log("logging in to FTP server", Project.MSG_VERBOSE);
if (!ftp.login(userid, password))
{
throw new BuildException("Could not login to FTP server");
}
log("login succeeded", Project.MSG_VERBOSE);
if (binary)
{
ftp.setFileType(com.oroinc.net.ftp.FTP.IMAGE_FILE_TYPE);
if (!FTPReply.isPositiveCompletion(ftp.getReplyCode()))
{
throw new BuildException(
"could not set transfer type: " +
ftp.getReplyString());
}
}
if (remotedir != null)
{
log("changing the remote directory", Project.MSG_VERBOSE);
ftp.changeWorkingDirectory(remotedir);
if (!FTPReply.isPositiveCompletion(ftp.getReplyCode()))
{
throw new BuildException(
"could not change remote directory: " +
ftp.getReplyString());
}
}
log(ACTION_STRS[action] + " files");
transferFiles(ftp);
}
catch(IOException ex)
{
throw new BuildException("error during FTP transfer: " + ex);
}
finally
{
/*
if (ftp != null && ftp.isConnected())
{
try
{
// this hangs - I don't know why.
ftp.disconnect();
}
catch(IOException ex)
{
// ignore it
}
}
*/
}
}
}
1.1 jakarta-ant/src/main/org/apache/tools/ant/taskdefs/optional/net/TelnetTask.java
Index: TelnetTask.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Ant", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.tools.ant.taskdefs.optional.net;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.taskdefs.MatchingTask;
import com.oroinc.net.telnet.*;
import org.apache.tools.ant.BuildException;
import java.io.*;
import java.lang.*;
import java.util.*;
/**
* Class to provide automated telnet protocol support for the Ant build tool
*
* @author Scott Carlson<a href="mailto:ScottCarlson@email.com">ScottCarlson@email.com</a>
* @version $Revision: 1.1 $
*/
public class TelnetTask extends Task {
/**
* The userid to login with, if automated login is used
*/
private String userid = null;
/**
* The password to login with, if automated login is used
*/
private String password= null;
/**
* The server to connect to.
*/
private String server = null;
/**
* The tcp port to connect to.
*/
private int port = 23;
/**
* The Object which handles the telnet session.
*/
private AntTelnetClient telnet = null;
/**
* The list of read/write commands for this session
*/
private Vector telnetTasks = new Vector();
/**
* Verify that all parameters are included.
* Connect and possibly login
* Iterate through the list of Reads and writes
*/
public void execute() throws BuildException
{
/** A server name is required to continue */
if (server== null)
throw new BuildException("No Server Specified");
/** A userid and password must appear together
* if they appear. They are not required.
*/
if (userid == null && password != null)
throw new BuildException("No Userid Specified");
if (password == null && userid != null)
throw new BuildException("No Password Specified");
/** Create the telnet client object */
telnet = new AntTelnetClient();
try {
telnet.connect(server, port);
} catch(IOException e) {
throw new BuildException("Can't connect to "+server);
}
/** Login if userid and password were specified */
if (userid != null && password != null)
login();
/** Process each sub command */
Enumeration tasksToRun = telnetTasks.elements();
while (tasksToRun!=null && tasksToRun.hasMoreElements())
{
TelnetSubTask task = (TelnetSubTask) tasksToRun.nextElement();
task.execute(telnet);
}
}
/**
* Process a 'typical' login. If it differs, use the read
* and write tasks explicitely
*/
private void login()
{
telnet.waitForString("ogin:");
telnet.sendString(userid);
telnet.waitForString("assword:");
telnet.sendString(password);
}
/**
* Set the userid attribute
*/
public void setUserid(String u) { this.userid = u; }
/**
* Set the password attribute
*/
public void setPassword(String p) { this.password = p; }
/**
* Set the server address attribute
*/
public void setServer(String m) { this.server = m; }
/**
* Set the tcp port to connect to attribute
*/
public void setPort(int p) { this.port = p; }
/**
* A subTask <read> tag was found. Create the object,
* Save it in our list, and return it.
*/
public TelnetSubTask createRead()
{
TelnetSubTask task = (TelnetSubTask)new TelnetRead();
telnetTasks.addElement(task);
return task;
}
/**
* A subTask <write> tag was found. Create the object,
* Save it in our list, and return it.
*/
public TelnetSubTask createWrite()
{
TelnetSubTask task = (TelnetSubTask)new TelnetWrite();
telnetTasks.addElement(task);
return task;
}
/**
* This class is the parent of the Read and Write tasks.
* It handles the common attributes for both.
*/
public class TelnetSubTask
{
protected String taskString= "";
public void execute(AntTelnetClient telnet)
throws BuildException
{
throw new BuildException("Shouldn't be able instantiate a SubTask directly");
}
public void addText(String s) { setString(s);}
public void setString(String s)
{
taskString += s;
}
}
/**
* This class sends text to the connected server
*/
public class TelnetWrite extends TelnetSubTask
{
public void execute(AntTelnetClient telnet)
throws BuildException
{
telnet.sendString(taskString);
}
}
/**
* This class reads the output from the connected server
* until the required string is found.
*/
public class TelnetRead extends TelnetSubTask
{
public void execute(AntTelnetClient telnet)
throws BuildException
{
telnet.waitForString(taskString);
}
}
/**
* This class handles the abstraction of the telnet protocol.
* Currently it is a wrapper around <a href="www.oroinc.com">ORO</a>'s
* NetComponents
*/
public class AntTelnetClient extends TelnetClient
{
public void waitForString(String s)
{
InputStream is =this.getInputStream();
try {
StringBuffer sb = new StringBuffer();
while (sb.toString().indexOf(s) == -1)
{
while (is.available() == 0);
int iC = is.read();
Character c = new Character((char)iC);
sb.append(c);
}
log(sb.toString(), Project.MSG_INFO);
} catch (Exception e)
{
throw new BuildException(e, getLocation());
}
}
public void sendString(String s)
{
OutputStream os =this.getOutputStream();
try {
os.write((s + "\n").getBytes());
log(s, Project.MSG_INFO);
os.flush();
} catch (Exception e)
{
throw new BuildException(e, getLocation());
}
}
}
}