1 /*
2  * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 package sun.net.ftp;
26 
27 import java.util.Date;
28 import java.util.HashMap;
29 
30 /**
31  * A {@code FtpDirEntry} is a class agregating all the information that the FTP client
32  * can gather from the server by doing a {@code LST} (or {@code NLST}) command and
33  * parsing the output. It will typically contain the name, type, size, last modification
34  * time, owner and group of the file, although some of these could be unavailable
35  * due to specific FTP server limitations.
36  *
37  * @see sun.net.ftp.FtpDirParser
38  * @since 1.7
39  */
40 public class FtpDirEntry {
41 
42     public enum Type {
43 
44         FILE, DIR, PDIR, CDIR, LINK
45     };
46 
47     public enum Permission {
48 
49         USER(0), GROUP(1), OTHERS(2);
50         int value;
51 
Permission(int v)52         Permission(int v) {
53             value = v;
54         }
55     };
56     private final String name;
57     private String user = null;
58     private String group = null;
59     private long size = -1;
60     private java.util.Date created = null;
61     private java.util.Date lastModified = null;
62     private Type type = Type.FILE;
63     private boolean[][] permissions = null;
64     private HashMap<String, String> facts = new HashMap<String, String>();
65 
FtpDirEntry()66     private FtpDirEntry() {
67         name = null;
68     }
69 
70     /**
71      * Creates an FtpDirEntry instance with only the name being set.
72      *
73      * @param name The name of the file
74      */
FtpDirEntry(String name)75     public FtpDirEntry(String name) {
76         this.name = name;
77     }
78 
79     /**
80      * Returns the name of the remote file.
81      *
82      * @return a {@code String} containing the name of the remote file.
83      */
getName()84     public String getName() {
85         return name;
86     }
87 
88     /**
89      * Returns the user name of the owner of the file as returned by the FTP
90      * server, if provided. This could be a name or a user id (number).
91      *
92      * @return a {@code String} containing the user name or
93      *         {@code null} if that information is not available.
94      */
getUser()95     public String getUser() {
96         return user;
97     }
98 
99     /**
100      * Sets the user name of the owner of the file. Intended mostly to be
101      * used from inside a {@link java.net.FtpDirParser} implementation.
102      *
103      * @param user The user name of the owner of the file, or {@code null}
104      * if that information is not available.
105      * @return this FtpDirEntry
106      */
setUser(String user)107     public FtpDirEntry setUser(String user) {
108         this.user = user;
109         return this;
110     }
111 
112     /**
113      * Returns the group name of the file as returned by the FTP
114      * server, if provided. This could be a name or a group id (number).
115      *
116      * @return a {@code String} containing the group name or
117      *         {@code null} if that information is not available.
118      */
getGroup()119     public String getGroup() {
120         return group;
121     }
122 
123     /**
124      * Sets the name of the group to which the file belong. Intended mostly to be
125      * used from inside a {@link java.net.FtpDirParser} implementation.
126      *
127      * @param group The name of the group to which the file belong, or {@code null}
128      * if that information is not available.
129      * @return this FtpDirEntry
130      */
setGroup(String group)131     public FtpDirEntry setGroup(String group) {
132         this.group = group;
133         return this;
134     }
135 
136     /**
137      * Returns the size of the remote file as it was returned by the FTP
138      * server, if provided.
139      *
140      * @return the size of the file or -1 if that information is not available.
141      */
getSize()142     public long getSize() {
143         return size;
144     }
145 
146     /**
147      * Sets the size of that file. Intended mostly to be used from inside an
148      * {@link java.net.FtpDirParser} implementation.
149      *
150      * @param size The size, in bytes, of that file. or -1 if unknown.
151      * @return this FtpDirEntry
152      */
setSize(long size)153     public FtpDirEntry setSize(long size) {
154         this.size = size;
155         return this;
156     }
157 
158     /**
159      * Returns the type of the remote file as it was returned by the FTP
160      * server, if provided.
161      * It returns a FtpDirEntry.Type enum and the values can be:
162      * - FtpDirEntry.Type.FILE for a normal file
163      * - FtpDirEntry.Type.DIR for a directory
164      * - FtpDirEntry.Type.LINK for a symbolic link
165      *
166      * @return a {@code FtpDirEntry.Type} describing the type of the file
167      *         or {@code null} if that information is not available.
168      */
getType()169     public Type getType() {
170         return type;
171     }
172 
173     /**
174      * Sets the type of the file. Intended mostly to be used from inside an
175      * {@link java.net.FtpDirParser} implementation.
176      *
177      * @param type the type of this file or {@code null} if that information
178      * is not available.
179      * @return this FtpDirEntry
180      */
setType(Type type)181     public FtpDirEntry setType(Type type) {
182         this.type = type;
183         return this;
184     }
185 
186     /**
187      * Returns the last modification time of the remote file as it was returned
188      * by the FTP server, if provided, {@code null} otherwise.
189      *
190      * @return a <code>Date</code> representing the last time the file was
191      *         modified on the server, or {@code null} if that
192      *         information is not available.
193      */
getLastModified()194     public java.util.Date getLastModified() {
195         return this.lastModified;
196     }
197 
198     /**
199      * Sets the last modification time of the file. Intended mostly to be used
200      * from inside an {@link java.net.FtpDirParser} implementation.
201      *
202      * @param lastModified The Date representing the last modification time, or
203      * {@code null} if that information is not available.
204      * @return this FtpDirEntry
205      */
setLastModified(Date lastModified)206     public FtpDirEntry setLastModified(Date lastModified) {
207         this.lastModified = lastModified;
208         return this;
209     }
210 
211     /**
212      * Returns whether read access is granted for a specific permission.
213      *
214      * @param p the Permission (user, group, others) to check.
215      * @return {@code true} if read access is granted.
216      */
canRead(Permission p)217     public boolean canRead(Permission p) {
218         if (permissions != null) {
219             return permissions[p.value][0];
220         }
221         return false;
222     }
223 
224     /**
225      * Returns whether write access is granted for a specific permission.
226      *
227      * @param p the Permission (user, group, others) to check.
228      * @return {@code true} if write access is granted.
229      */
canWrite(Permission p)230     public boolean canWrite(Permission p) {
231         if (permissions != null) {
232             return permissions[p.value][1];
233         }
234         return false;
235     }
236 
237     /**
238      * Returns whether execute access is granted for a specific permission.
239      *
240      * @param p the Permission (user, group, others) to check.
241      * @return {@code true} if execute access is granted.
242      */
canExexcute(Permission p)243     public boolean canExexcute(Permission p) {
244         if (permissions != null) {
245             return permissions[p.value][2];
246         }
247         return false;
248     }
249 
250     /**
251      * Sets the permissions for that file. Intended mostly to be used
252      * from inside an {@link java.net.FtpDirParser} implementation.
253      * The permissions array is a 3x3 {@code boolean} array, the first index being
254      * the User, group or owner (0, 1 and 2 respectively) while the second
255      * index is read, write or execute (0, 1 and 2 respectively again).
256      * <p>E.G.: {@code permissions[1][2]} is the group/execute permission.</p>
257      *
258      * @param permissions a 3x3 {@code boolean} array
259      * @return this {@code FtpDirEntry}
260      */
setPermissions(boolean[][] permissions)261     public FtpDirEntry setPermissions(boolean[][] permissions) {
262         this.permissions = permissions;
263         return this;
264     }
265 
266     /**
267      * Adds a 'fact', as defined in RFC 3659, to the list of facts of this file.
268      * Intended mostly to be used from inside a {@link java.net.FtpDirParser}
269      * implementation.
270      *
271      * @param fact the name of the fact (e.g. "Media-Type"). It is not case-sensitive.
272      * @param value the value associated with this fact.
273      * @return this {@code FtpDirEntry}
274      */
addFact(String fact, String value)275     public FtpDirEntry addFact(String fact, String value) {
276         facts.put(fact.toLowerCase(), value);
277         return this;
278     }
279 
280     /**
281      * Returns the requested 'fact', as defined in RFC 3659, if available.
282      *
283      * @param fact The name of the fact *e.g. "Media-Type"). It is not case sensitive.
284      * @return The value of the fact or, {@code null} if that fact wasn't
285      * provided by the server.
286      */
getFact(String fact)287     public String getFact(String fact) {
288         return facts.get(fact.toLowerCase());
289     }
290 
291     /**
292      * Returns the creation time of the file, when provided by the server.
293      *
294      * @return The Date representing the creation time, or {@code null}
295      * if the server didn't provide that information.
296      */
getCreated()297     public Date getCreated() {
298         return created;
299     }
300 
301     /**
302      * Sets the creation time for that file. Intended mostly to be used from
303      * inside a {@link java.net.FtpDirParser} implementation.
304      *
305      * @param created the Date representing the creation time for that file, or
306      * {@code null} if that information is not available.
307      * @return this FtpDirEntry
308      */
setCreated(Date created)309     public FtpDirEntry setCreated(Date created) {
310         this.created = created;
311         return this;
312     }
313 
314     /**
315      * Returns a string representation of the object.
316      * The {@code toString} method for class {@code FtpDirEntry}
317      * returns a string consisting of the name of the file, followed by its
318      * type between brackets, followed by the user and group between
319      * parenthesis, then size between '{', and, finally, the lastModified of last
320      * modification if it's available.
321      *
322      * @return  a string representation of the object.
323      */
324     @Override
toString()325     public String toString() {
326         if (lastModified == null) {
327             return name + " [" + type + "] (" + user + " / " + group + ") " + size;
328         }
329         return name + " [" + type + "] (" + user + " / " + group + ") {" + size + "} " + java.text.DateFormat.getDateInstance().format(lastModified);
330     }
331 }
332