Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/finj/FTPReply.java


1   package org.finj;
2   
3   import java.util.Locale;
4   import java.util.MissingResourceException;
5   import java.util.ResourceBundle;
6   
7   /**
8    * This class contains constants and methods that 
9    * simplify handling and internationalization of 
10   * FTP server replies.
11   *
12   * Codes according to RFC959-4.2 
13   * <TT>http://www.cis.ohio-state.edu/htbin/rfc/rfc959.html</TT>
14   * (October 1995).
15   *
16   * @author Javier Iglesias -- jiglesias@users.sourceforge.net 
17   * @version $Id$
18   */
19  public class FTPReply extends Object {
20  
21      // ----- 100 SERIES CODES -----
22      // Requested action is being initiated, expect 
23      // another reply before proceeding with a new command
24      /** 
25       * Restart marker reply. 
26       *
27       * In this case, the text is exact and not 
28       * left to the particular implementation; it must read :
29       * <CODE>MARK yyyy = mmmm</CODE>
30       * Where <CODE>yyyy</CODE> is User-process data stream marker, 
31       * and <CODE>mmmm</CODE> server's equivalent marker 
32       * (note the spaces between markers and '=`).
33       *
34       * @see "RFC959-4:2:'110'"
35       * @since v1.0
36       */
37      public static final int RESTART_MARKER_REPLY_CODE = 110;
38      /** 
39       * Service ready in <CODE>nnn</CODE> minutes.
40       *  
41       * @see "RFC959-4:2:'120'"
42       * @since v1.0
43       */
44      public static final int WILL_BE_READY_IN_MINUTES_CODE = 120;
45      /** 
46       * Data Connection already open; transfer starting.
47       *
48       * @see "RFC959-4:2:'125'"
49       * @since v1.0
50       */
51      public static final int DATA_CONNECTION_ALREADY_OPENED_CODE = 125;
52      /** 
53       * File status okay; about to open data connection.
54       *
55       * @see "RFC959-4:2:'150'"
56       * @since v1.0
57       */
58      public static final int DATA_CONNECTION_ABOUT_TO_BE_OPENED_CODE = 150;
59  
60      // ----- 200 SERIES CODES -----
61      // Requested action has been successfully completed
62      /** 
63       * Command okay.
64       *
65       * @see "RFC959-4:2:'200'"
66       * @since v1.0
67       */
68      public static final int POSITIVE_COMPLETION_REPLY_CODE = 200;
69      /** 
70       * Command not implemented, superfluous at this site.
71       *
72       * @see "RFC959-4:2:'202'"
73       * @since v1.0
74       */
75      public static final int SUPERFLOUS_COMMAND_CODE = 202;
76      /** 
77       * System status, or system help reply.
78       *
79       * @see "RFC959-4:2:'211'"
80       * @since v1.0
81       */
82      public static final int SYSTEM_STATUS_OR_HELP_REPLY_CODE = 211;
83      /** 
84       * Directory status
85       *
86       * @see "RFC959-4:2:'212'"
87       * @since v1.0
88       */
89      public static final int DIRECTORY_STATUS_CODE = 212;
90      /** 
91       * File status.
92       *
93       * @see "RFC959-4:2:'213'"
94       * @since v1.0
95       */
96      public static final int FILE_STATUS_CODE = 213;
97      /** 
98       * Help message.
99       *
100      * On how to use the server or the meaning of a particular 
101      * non-standard command. This reply is useful only to the 
102      * human user.
103      *
104      * @see "RFC959-4:2:'214'"
105      * @since v1.0
106      */
107     public static final int HELP_MESSAGE_CODE = 214;
108     /** 
109      * <CODE>NAME</CODE> system type.
110      *
111      * Where <CODE>NAME</CODE> is an official system name from 
112      * the list in the Assigned Numbers document.
113      *
114      * @see "RFC959-4:2:'215'"
115      * @see "RFC1700"
116      * @since v1.0
117      */
118     public static final int SYSTEM_TYPE_NAME_CODE = 215;
119     /** 
120      * Service ready for new user.
121      *
122      * @see "RFC959-4:2:'220'"
123      * @since v1.0
124      */
125     public static final int CONTROL_CONNECTION_OPENED_CODE = 220;
126     /** 
127      * Service closing control connection.
128      *
129      * Logged out if appropriate.
130      *
131      * @see "RFC959-4:2:'221'"
132      * @since v1.0
133      */
134     public static final int CONTROL_CONNECTION_CLOSED_CODE = 221;
135     /** 
136      * Data connection open; no transfer in progress.
137      *
138      * @see "RFC959-4:2:'225'"
139      * @since v1.0
140      */
141     public static final int DATA_CONNECTION_OPENED_CODE = 225;
142     /** 
143      * Closing data connection.
144      *
145      * Requested file action successful (e.g., file transfer or 
146      * file abort).
147      *
148      * @see "RFC959-4:2:'226'"
149      * @since v1.0
150      */
151     public static final int DATA_CONNECTION_CLOSED_CODE = 226;
152     /** 
153      * Entering Passive Mode (h1,h2,h3,h4,p1,p2).
154      *
155      * @see "RFC959-4:2:'227'"
156      * @since v1.0
157      */
158     public static final int ENTERING_PASSIVE_MODE_CODE = 227;
159     /** 
160      * User logged in, proceed.
161      *
162      * @see "RFC959-4:2:'230'"
163      * @since v1.0
164      */
165     public static final int USER_LOGGED_IN_CODE = 230;
166     /** 
167      * Requested file action okay, completed.
168      *
169      * @see "RFC959-4:2:'250'"
170      * @since v1.0
171      */
172     public static final int REQUESTED_FILE_ACTION_OK_CODE = 250;
173     /** 
174      * "PATHNAME" created.
175      *
176      * @see "RFC959-4:2:'257'"
177      * @since v1.0
178      */
179     public static final int PATHNAME_CREATED_CODE = 257;
180 
181     // ----- 300 SERIES CODES -----
182     // Command has been accepted, but requested action 
183     // is  being held abeyance, pending receipt of 
184     // further information
185     /** 
186      * User name okay, need password.
187      *
188      * @see "RFC959-4:2;'331'"
189      * @since v1.0
190      */
191     public static final int USERNAME_OK_NEED_PASSWORD_CODE = 331;
192     /** 
193      * Need account for login.
194      *
195      * @see "RFC959-4:2:'332'"
196      * @since v1.0
197      */
198     public static final int NEED_ACCOUNT_FOR_LOGIN_CODE = 332;
199     /** 
200      * Requested file action pending further information.
201      *
202      * @see "RFC959-4:2:'350'"
203      * @since v1.0
204      */
205     public static final int REQUESTED_FILE_ACTION_PENDING_CODE = 350;
206 
207     // ----- 400 SERIES CODES -----
208     // Command was not accepted and the requested action 
209     // did NOT take place, but the error condition is 
210     // temporary and the action may be requested again
211     /** 
212      * Service not available, closing control connection.
213      *
214      * This may be a reply to any command if the service 
215      * knows it must shut down.
216      *
217      * @see "RFC959-4:2:'421'"
218      * @since v1.0
219      */
220     public static final int SERVICE_NOT_AVAILABLE_CODE = 421;
221     /** 
222      * Can't open data connection.
223      *
224      * @see "RFC959-4:2:'425'"
225      * @since v1.0
226      */
227     public static final int CAN_T_OPEN_DATA_CONNECTION_CODE = 425;
228     /** 
229      * Connection closed; transfer aborted.
230      *
231      * @see "RFC959-4:2:'426'"
232      * @since v1.0
233      */
234     public static final int DATA_CONNECTION_ABORTED_CODE = 426;
235     /** 
236      * Requested file action not taken.
237      *
238      * File unavailable (e.g., file busy).
239      *
240      * @see "RFC959-4:2:'450'"
241      * @since v1.0
242      */
243     public static final int TRANSIENT_UNAVAILABLE_FILE_CODE = 450;
244     /** 
245      * Requested action aborted: local error in processing.
246      *
247      * @see "RFC959-4:2:'451'"
248      * @since v1.0
249      */
250     public static final int TRANSIENT_LOCAL_PROCESSING_ERROR_CODE = 451;
251     /** 
252      * Requested action not taken.
253      *
254      * Insufficient storage space in system.
255      *
256      * @see "RFC959-4:2:'452'"
257      * @since v1.0
258      */
259     public static final int TRANSIENT_INSUFFICIENT_STORAGE_SPACE_CODE = 452;
260 
261     // ----- 500 SERIES CODES -----
262     // Command was not accepted and the requested action 
263     // did NOT take place
264     /** 
265      * Syntax error, command unrecognized.
266      *
267      * This may include errors such as command line too long.
268      *
269      * @see "RFC959-4:2:'500'"
270      * @since v1.0
271      */
272     public static final int PERMANENT_NEGATIVE_COMPLETION_REPLY_CODE = 500;
273     /** 
274      * Syntax error n parameters or arguments.
275      *
276      * @see "RFC959-4:2:'501'"
277      * @since v1.0
278      */
279     public static final int SYNTAX_ERROR_IN_ARGUMENTS_CODE = 501;
280     /** 
281      * Command not implemented.
282      *
283      * @see "RFC959-4:2:'502'"
284      * @since v1.0
285      */
286     public static final int COMMAND_NOT_IMPLEMENTED_CODE = 502;
287     /** 
288      * Bad sequence of commands.
289      *
290      * @see "RFC959-4:2:'503'"
291      * @since v1.0
292      */
293     public static final int BAD_COMMAND_SEQUENCE_CODE = 503;
294     /** 
295      * Command not implemented for that parameter.
296      *
297      * @see "RFC959-4:2:'504'"
298      * @since v1.0
299      */
300     public static final int COMMAND_NOT_IMPLEMENTED_FOR_THAT_PARAMETER_CODE = 504;
301     /** 
302      * Not logged in.
303      *
304      * @see "RFC959-4:2:'530'"
305      * @since v1.0
306      */
307     public static final int NOT_LOGGED_IN_CODE = 530;
308     /** 
309      * Need account for storing files.
310      *
311      * @see "RFC959-4:2:'532'"
312      * @since v1.0
313      */
314     public static final int NEED_ACCOUNT_FOR_STORING_FILES_CODE = 532;
315     /** 
316      * Requested action not taken.
317      *
318      * File unavailable (e.g., file not found, no access).
319      *
320      * @see "RFC959-4:2:'550'"
321      * @since v1.0
322      */
323     public static final int PERMANENTLY_UNAVAILABLE_FILE_CODE = 550;
324     /** 
325      * Requested action aborted: page type unknown.
326      *
327      * @see "RFC959-4:2:'551'"
328      * @since v1.0
329      */
330     public static final int PAGE_TYPE_UNKNOWN_CODE = 551;
331     /** 
332      * Requested file action aborted.
333      *
334      * Exceed storage allocation (for current directory or dataset).
335      *
336      * @see "RFC959-4:2:'552'"
337      * @since v1.0
338      */
339     public static final int EXCEEDED_STORAGE_ALLOCATION_CODE = 552;
340     /** 
341      * Requested action not taken.
342      *
343      * File name not allowed.
344      *
345      * @see "RFC959-4:2:'553'"
346      * @since v1.0
347      */
348     public static final int FINE_NAME_NOT_ALLOWED_CODE = 553;
349 
350 
351     // Messages are stored in resource files
352     private static final String MESSAGE_BUNDLE_NAME  = "org/finj/FTPMessage";
353     private static final String MESSAGE_NAME_PREFIX  = "code_";
354     private static final String DEFAULT_MESSAGE_NAME = "code_default";
355     private ResourceBundle resources = null;
356 
357     private int     code = 0;
358     private String  text = null;
359     private boolean multi = false;
360 
361     /**
362      * Defeat parameterless constructor.
363      *
364      * @since v1.0
365      */
366     private FTPReply ( ) {;}
367 
368     /**
369      * Constructs a new instance of this class 
370      * that will use <CODE>Locale.US</CODE> as 
371      * default locale.
372      *
373      * @param text original reply message received on the 
374      *             control connection.
375      * @since v1.0
376      */
377     public FTPReply ( String text ) {
378   this ( text, Locale.US );
379     }
380 
381     /**
382      * Constructs a new instance of this class 
383      * that will use <CODE>locale</CODE> as 
384      * message language. If not available, 
385      * messages for default language 
386      * (<CODE>Locale.US</CODE>) will be used.
387      *
388      * @param text original reply message received on the 
389      *             control connection.
390      * @param locale language to use for message.
391      * @since v1.0
392      */
393     public FTPReply ( String text,
394           Locale locale ) throws IllegalArgumentException {
395   this.code  = getCodeFromMessage (text);
396   this.multi = (text.charAt (3) == '-');
397   this.text  = text.substring (4, text.length ()).trim ();
398   resources  = ResourceBundle.getBundle (MESSAGE_BUNDLE_NAME, locale);
399     }
400 
401     /**
402      * Returns the FTP code of this reply.
403      *
404      * @return FTP code
405      * @since v1.0
406      */
407     public int getCode ( ) {
408   return code;
409     }
410 
411     /**
412      * Returns a localized version of the message corresponding 
413      * to the original one's code. This will only work if a 
414      * localized version of the messages are provided.
415      *
416      * @return code of the reply sent by FTP server.
417      * @since v1.0
418      */
419     public String getMessage ( ) {
420   return getMessageFromCode (code);
421     }
422 
423     /**
424      * Returns the original message received from the FTP server 
425      * and passed at construction time.
426      * 
427      * @return original message text.
428      * @since v1.0
429      */
430     public String getOriginalMessage ( ) {
431   return text;
432     }
433 
434     /**
435      * Returns true if this reply anounces a multi line reply, 
436      * e.g., <CODE>STAT</CODE> command.
437      *
438      * @return <CODE>true</CODE> if more lines are coming next 
439      *         the one used to construct this instance.
440      * @see "RFC959-4:2"
441      * @since v1.0
442      */
443     public boolean isMultiline ( ) {
444   return multi;
445     }
446 
447     /**
448      * Returns the message that corresponds to the 
449      * <CODE>code</CODE> given as parameter.
450      *
451      * @param code one of the codes defined in this class.
452      * @since v1.0
453      */
454     protected String getMessageFromCode ( int code ) {
455   try {
456       return resources.getString (new StringBuffer (MESSAGE_NAME_PREFIX).append (code).toString ());
457   } catch ( MissingResourceException mre ) {
458       return resources.getString (DEFAULT_MESSAGE_NAME);
459   }
460     }
461 
462     /**
463      * Returns the code contained in the 
464      * <CODE>reply</CODE> passed as parameter.
465      * This code are in fact the 3 first characters 
466      * of the <CODE>reply</CODE>.
467      *
468      * @param reply FTP server reply to interpret.
469      * @exception IllegalArgumentException 
470      *            when <CODE>reply</CODE>'s 3 first characters 
471      *            are not a valid three digit number
472      * @since v1.0
473      */
474     public static int getCodeFromMessage ( String reply ) throws IllegalArgumentException {
475   try {
476       return Integer.parseInt (reply.substring (0, 3));
477   } catch ( Exception e ) {
478       throw new IllegalArgumentException (reply.substring (0, 3) + " is obviously not a valid FTP error code !");
479   }
480     }
481 }