1 package ch
.cyberduck
.connection
;
4 * ch.cyberduck.connection.Path.java
11 * Copyright (c) 2003 David Kocher. All rights reserved.
12 * http://icu.unizh.ch/~dkocher/
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * Bug fixes, suggestions and comments should be sent to:
25 * dkocher@cyberduck.ch
28 import java
.text
.DateFormat
;
29 import java
.util
.Date
;
30 import java
.awt
.datatransfer
.Transferable
;
31 import java
.awt
.datatransfer
.DataFlavor
;
32 import java
.awt
.datatransfer
.UnsupportedFlavorException
;
33 import java
.io
.Serializable
;
35 import ch
.cyberduck
.Cyberduck
;
38 * A path is a remote directory or file.
41 public class Path
implements Serializable
, Transferable
{
43 private String name
= null;
44 private String path
= null;
45 private Path parent
= null;
48 private long modified
;
52 private String access
;
53 private Permission permission
;
55 private boolean visible
= true;
57 public static final DataFlavor pathFlavor
58 = new DataFlavor(ch
.cyberduck
.connection
.Path
.class, "ch.cyberduck.connection.Path");
60 public DataFlavor
[] getTransferDataFlavors() {
61 return new DataFlavor
[]{pathFlavor
};
64 public boolean isDataFlavorSupported(DataFlavor flavor
) {
65 return flavor
.equals(pathFlavor
);
68 public Object
getTransferData(DataFlavor flavor
) throws UnsupportedFlavorException
{
69 if(flavor
.equals(pathFlavor
))
71 throw new UnsupportedFlavorException(flavor
);
75 * @param path the absolute directory
76 * @param name the file relative to param path
78 public Path(String path
, String name
) {
79 //Cyberduck.DEBUG("[Path] Path(" + path+","+name+")");
80 if(path
.charAt(path
.length() -1) == '/')
81 this.init(path
+ name
);
83 this.init(path
+ "/" + name
);
87 * @param path The absolute path of the file
89 public Path(String path
) {
93 private void init(String pathname
) {
94 //Cyberduck.DEBUG("[Path] init(" + pathname + ")");
95 String p
= pathname
.trim();
97 if(this.isDirectory()) {
99 this.parent
= this.getPathFragment(this.getPathDepth() - 1);
101 if(this.getPathDepth() > 1) {
102 this.name
= p
.substring(parent
.toString().length(), p
.lastIndexOf('/'));
104 else if(this.getPathDepth() > 0) {// must always be true if this.isDirectory()
105 this.name
= p
.substring(1, p
.lastIndexOf('/'));
108 else if(this.isFile()) {
109 this.parent
= this.getPathFragment(this.getPathDepth());
110 this.name
= p
.substring(p
.lastIndexOf('/') + 1);
112 // Cyberduck.DEBUG("Path:" + this.path + ", Name:" + this.getName() + ", Parent:" + this.getParent());
116 * Only use this if you know what you do! Use constructor by default.
117 * @see #Path(String, String)
119 public void setPath(String p
) {
120 Cyberduck
.DEBUG("[Path] setPath(" + p
+ ")");
121 StringBuffer buffer
= new StringBuffer();
122 for(int i
= 0; i
< p
.length(); i
++) {
123 if(! Character
.isWhitespace(p
.charAt(i
)))
124 buffer
.append(p
.charAt(i
));
126 this.path
= buffer
.toString();
131 * even if the file doesn't exist on the local filesystem
132 * but seems to be a file because there isn't a '/' at
133 * the end of the path.
135 public boolean isFile() {
136 String path
= this.toString();
137 if(path
.lastIndexOf('/') == path
.length() - 1) {
145 * even if the directory doesn't exist on the local filesystem
146 * but seems to be a directory because it ends with '/'
148 public boolean isDirectory() {
149 // Cyberduck.DEBUG("[Path] isDirectory()");
150 String path
= this.toString();
151 if(path
.lastIndexOf('/') == path
.length() - 1) {
158 * @return The filename if the path is a file
159 * or the full path if it is a directory
161 public String
getName() {
166 * @return the absolute path name
168 public String
getPath() {
173 * @return my parent directory
175 public Path
getParent() {
180 * @return Returns the number of '/' characters in a path
182 public int getPathDepth() {
185 while((length
= this.toString().indexOf('/', length
+ 1)) != -1) {
192 * Returns a path relative the parameter
195 public Path
getRelativePath(Path relative
) {
196 int index
= this.getPath().indexOf(relative
.getPath());
198 throw new IllegalArgumentException("The argument must be part of this path");
201 return new Path(this.getPath().substring(index
+ relative
.getPath().length()));
206 * @ param depth the '/'
207 * @ return a new Path cut to the length of parameter <code>depth</code>
209 public Path
getPathFragment(int depth
) throws IllegalArgumentException
{
210 // Cyberduck.DEBUG("[Path] getPathFragment(" + depth + ")");
211 if(depth
> this.getPathDepth())
212 throw new IllegalArgumentException("Path is not that long: " + depth
+ " > " + this.getPathDepth());
214 int length
= 1; //@modification
215 for (int n
= 0; n
< depth
; n
++) {
216 if((length
= this.toString().indexOf('/', length
+ 1)) < 0) {
221 return new Path(this.toString().substring(0, length
+ 1));
223 return new Path(this.toString());
227 return new Path("/");
232 public static String encode(String path) {
233 return java.net.URLEncoder.encode(path);
238 * @param size The size of the file
240 public void setSize(int size
) {
244 private static final int KILO
= 1024; //2^10
245 private static final int MEGA
= 1048576; // 2^20
246 private static final int GIGA
= 1073741824; // 2^30
249 * @return The size of the file
251 public String
getSize() {
255 else if(size
< MEGA
) {
256 return new Double(size
/KILO
).intValue() + " KB";
258 else if(size
< GIGA
) {
259 return new Double(size
/MEGA
).intValue() + " MB";
262 return new Double(size
/GIGA
).intValue() + " GB";
267 * Set the modfication returned by ftp directory listings
269 public void setModified(long m
) {
274 * @return the modification date of this file
276 public String
getModified() {
277 return (DateFormat
.getDateTimeInstance(DateFormat
.SHORT
, DateFormat
.SHORT
)).format(new Date(this.modified
));
281 * @param access unix access permitions, i.e. -rwxrwxrwx
283 public void setMode(String access
) {
284 this.access
= access
;
288 * @return The unix access permissions
290 public String
getMode() {
294 public void setPermission(Permission p
) {
298 public Permission
getPermission() {
299 return this.permission
;
302 public void setOwner(String o
) {
306 public String
getOwner() {
310 public void setGroup(String g
) {
314 public String
getGroup() {
319 * @param visible If this path should be shown in the directory listing
321 public void setVisible(boolean visible
) {
322 this.visible
= visible
;
326 * @return If this path is shown in the directory listing
328 public boolean isVisible() {
333 * @return true if this paths points to '/'
335 public boolean isRoot() {
336 return this.toString().equals("/");
339 public String
toString() {
340 return this.getPath().toString();