KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > cruisecontrol > util > AbstractFTPClass


1 /********************************************************************************
2  * CruiseControl, a Continuous Integration Toolkit
3  * Copyright (c) 2001-2003, ThoughtWorks, Inc.
4  * 651 W Washington Ave. Suite 600
5  * Chicago, IL 60661 USA
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * + Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * + Redistributions in binary form must reproduce the above
16  * copyright notice, this list of conditions and the following
17  * disclaimer in the documentation and/or other materials provided
18  * with the distribution.
19  *
20  * + Neither the name of ThoughtWorks, Inc., CruiseControl, nor the
21  * names of its contributors may be used to endorse or promote
22  * products derived from this software without specific prior
23  * written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
29  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  ********************************************************************************/

37 package net.sourceforge.cruisecontrol.util;
38
39 import java.io.BufferedInputStream JavaDoc;
40 import java.io.ByteArrayInputStream JavaDoc;
41 import java.io.File JavaDoc;
42 import java.io.FileInputStream JavaDoc;
43 import java.io.InputStream JavaDoc;
44 import java.io.IOException JavaDoc;
45 import java.util.Vector JavaDoc;
46 import java.util.StringTokenizer JavaDoc;
47
48 import org.apache.log4j.Logger;
49 import org.apache.commons.net.ftp.FTPClient;
50 import org.apache.commons.net.ftp.FTPReply;
51 import org.apache.commons.net.ftp.FTP;
52 import net.sourceforge.cruisecontrol.CruiseControlException;
53
54 /**
55  * Generic class that acts as a parent to FTP related tasks to push files
56  * out to a host.
57  *
58  * @author <a HREF="groboclown@users.sourceforge.net">Matt Albrecht</a>
59  */

60 public abstract class AbstractFTPClass {
61
62     private static final Logger LOG = Logger.getLogger(AbstractFTPClass.class);
63
64     private String JavaDoc targetHost;
65     private int targetPort = 21;
66     private String JavaDoc targetUser = "anonymous";
67     private String JavaDoc targetPasswd = "eat@joes.com";
68     private String JavaDoc targetDir = ".";
69     private String JavaDoc targetSeparator = "/";
70     
71     private boolean passive = false;
72     
73
74     public void setTargetUser(String JavaDoc targetUser) {
75         this.targetUser = targetUser;
76     }
77
78     public void setTargetHost(String JavaDoc targetHost) {
79         this.targetHost = targetHost;
80     }
81     
82     public void setTargetPort(int targetPort) {
83         this.targetPort = targetPort;
84     }
85
86     public void setTargetPasswd(String JavaDoc targetPasswd) {
87         this.targetPasswd = targetPasswd;
88     }
89
90     public void setTargetDir(String JavaDoc targetDir) {
91         this.targetDir = targetDir;
92     }
93
94     public void setTargetSeparator(String JavaDoc targetSeparator) {
95         this.targetSeparator = targetSeparator;
96     }
97     
98     public void setPassive(boolean p) {
99         this.passive = p;
100     }
101     
102
103     /**
104      * Called after the configuration is read to make sure that all the mandatory parameters
105      * were specified..
106      *
107      * @throws net.sourceforge.cruisecontrol.CruiseControlException if there was a configuration error.
108      */

109     public void validate() throws CruiseControlException {
110         if (targetHost == null) {
111             throw new CruiseControlException("'targethost' not specified in configuration file");
112         }
113         if (targetDir == null) {
114             targetDir = ".";
115         }
116     }
117
118
119     protected FTPClient openFTP() throws CruiseControlException {
120         LOG.info("Opening FTP connection to " + targetHost);
121
122         FTPClient ftp = new FTPClient();
123
124         try {
125             ftp.connect(targetHost, targetPort);
126             if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
127                 throw new CruiseControlException("FTP connection failed: "
128                      + ftp.getReplyString());
129             }
130     
131             LOG.info("logging in to FTP server");
132             if (!ftp.login(targetUser, targetPasswd)) {
133                 throw new CruiseControlException("Could not login to FTP server");
134             }
135             LOG.info("login succeeded");
136             
137             if (passive) {
138                 setPassive(ftp);
139             }
140         } catch (IOException JavaDoc ioe) {
141             LOG.error(ioe);
142             throw new CruiseControlException(ioe.getMessage());
143         }
144         return ftp;
145     }
146     
147     
148     protected void closeFTP(FTPClient ftp) throws CruiseControlException {
149         if (ftp != null && ftp.isConnected()) {
150             try {
151                 LOG.info("disconnecting");
152                 ftp.logout();
153                 ftp.disconnect();
154             } catch (IOException JavaDoc ex) {
155                 // ignore it
156
}
157         }
158     }
159     
160     
161     protected void setBinary(FTPClient ftp) throws CruiseControlException {
162         try {
163             ftp.setFileType(FTP.IMAGE_FILE_TYPE);
164             if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
165                 throw new CruiseControlException(
166                     "could not set transfer type: "
167                     + ftp.getReplyString());
168             }
169         } catch (IOException JavaDoc ex) {
170             LOG.error(ex);
171             throw new CruiseControlException(ex.getMessage());
172         }
173     }
174     
175     
176     private void setPassive(FTPClient ftp) throws CruiseControlException {
177         LOG.info("entering passive mode");
178         ftp.enterLocalPassiveMode();
179         if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
180             throw new CruiseControlException("could not enter into passive "
181                  + "mode: " + ftp.getReplyString());
182         }
183     }
184     
185     
186     protected void makeDir(FTPClient ftp, String JavaDoc dir, boolean ignoreFailures)
187             throws CruiseControlException {
188         dir = targetDir + targetSeparator + dir;
189         try {
190             if (!ftp.makeDirectory(dir)) {
191                 // codes 521, 550 and 553 can be produced by FTP Servers
192
// to indicate that an attempt to create a directory has
193
// failed because the directory already exists.
194
int rc = ftp.getReplyCode();
195                 if (!(ignoreFailures
196                      && (rc == 550 || rc == 553 || rc == 521))) {
197                     throw new CruiseControlException(
198                         "could not create directory: "
199                         + ftp.getReplyString());
200                 }
201                 LOG.info("directory already exists");
202             } else {
203                 LOG.info("directory created OK");
204             }
205         } catch (IOException JavaDoc ex) {
206             LOG.error(ex);
207             throw new CruiseControlException(ex.getMessage());
208         }
209     }
210     
211     
212     /**
213      * The parent directories need to exist before putting this file.
214      */

215     protected void sendFile(FTPClient ftp, File JavaDoc infile, String JavaDoc outfilename)
216             throws CruiseControlException {
217         InputStream JavaDoc instream = null;
218         try {
219             LOG.info("transferring " + infile.getAbsolutePath());
220
221             instream = new BufferedInputStream JavaDoc(new FileInputStream JavaDoc(infile));
222             sendStream(ftp, instream, outfilename);
223         } catch (IOException JavaDoc ioe) {
224             throw new CruiseControlException(ioe.getMessage());
225         } finally {
226             if (instream != null) {
227                 try {
228                     instream.close();
229                 } catch (IOException JavaDoc ex) {
230                     // ignore it
231
}
232             }
233         }
234     }
235     
236     
237     /**
238      * The parent directories need to exist before putting this file.
239      */

240     protected void sendStream(FTPClient ftp, InputStream JavaDoc instream,
241             String JavaDoc outfilename) throws CruiseControlException {
242         LOG.info("transferring to file " + outfilename);
243         outfilename = targetDir + targetSeparator + resolveFile(outfilename);
244
245         try {
246             ftp.storeFile(outfilename, instream);
247             boolean success = FTPReply.isPositiveCompletion(ftp.getReplyCode());
248     
249             if (!success) {
250                 throw new CruiseControlException("could not put file: "
251                     + ftp.getReplyString());
252             }
253         } catch (IOException JavaDoc ex) {
254             LOG.error(ex);
255             throw new CruiseControlException(ex.getMessage());
256         }
257     }
258     
259     
260     protected String JavaDoc resolveFile(String JavaDoc file) {
261         return file.replace(File.separatorChar, targetSeparator.charAt(0));
262     }
263     
264     
265     protected void makeDirsForFile(FTPClient ftp, String JavaDoc filename,
266             Vector JavaDoc knownPaths) throws CruiseControlException {
267         String JavaDoc fname = resolveFile(filename);
268         LOG.info("making dirs for file " + fname);
269         int pos = fname.lastIndexOf(targetSeparator);
270         if (pos > 0) {
271             makeDirs(ftp, fname.substring(0, pos), knownPaths);
272         }
273     }
274     
275     
276     /**
277      * Creates all parent directories specified in a complete relative
278      * pathname. Attempts to create existing directories will not cause
279      * errors.
280      */

281     protected void makeDirs(FTPClient ftp, String JavaDoc pathname,
282             Vector JavaDoc knownPaths) throws CruiseControlException {
283         if (knownPaths == null) {
284             knownPaths = new Vector JavaDoc();
285         }
286         
287         StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(targetDir + targetSeparator
288             + resolveFile(pathname), targetSeparator, false);
289         
290         try {
291             String JavaDoc cwd = ftp.printWorkingDirectory();
292             LOG.info("makeDirs: current dir = " + cwd);
293             String JavaDoc fullPath = targetDir;
294             while (st.hasMoreTokens()) {
295                 String JavaDoc dir = st.nextToken();
296                 if (dir == null || dir.length() <= 0) {
297                     continue;
298                 }
299                 fullPath += targetSeparator + dir;
300                 LOG.info("makeDirs: dir = " + dir + ", fullPath = "
301                     + fullPath);
302                 /* we need to CD into the directory, whether it exists
303                 or not.
304                 if (knownPaths != null && knownPaths.contains(fullPath)) {
305                     continue;
306                 }
307                 */

308                 if (!ftp.changeWorkingDirectory(dir)) {
309                     LOG.info("makeDirs: could not CD into " + dir);
310                     if (!ftp.makeDirectory(dir)) {
311                         throw new CruiseControlException(
312                             "could not create directory [" + dir + ", full="
313                             + fullPath + "]: "
314                             + ftp.getReplyString());
315                     }
316                     LOG.info("makeDirs: created dir " + dir);
317                     if (!ftp.changeWorkingDirectory(dir)) {
318                         throw new CruiseControlException(
319                             "could not change to directory: "
320                             + ftp.getReplyString());
321                     }
322                     LOG.info("makeDirs: CDed into " + dir);
323                 }
324                 knownPaths.addElement(fullPath);
325             }
326             ftp.changeWorkingDirectory(cwd);
327         } catch (IOException JavaDoc ex) {
328             LOG.error(ex);
329             throw new CruiseControlException(ex.getMessage());
330         }
331     }
332
333     /**
334      * Sends the specified text into the specified path on the FTP server
335      * @param text
336      * @param path
337      * @throws CruiseControlException
338      */

339     protected void sendFileToFTPPath(String JavaDoc text, String JavaDoc path) throws CruiseControlException {
340         ByteArrayInputStream JavaDoc bais = new ByteArrayInputStream JavaDoc(
341             text.getBytes());
342
343         FTPClient ftp = openFTP();
344
345         // we're sending text; don't set binary!
346

347         try {
348             makeDirsForFile(ftp, path, null);
349             sendStream(ftp, bais, path);
350         } finally {
351             closeFTP(ftp);
352         }
353     }
354 }
355
Popular Tags