Source code: com/flexstor/common/io/xfile/webnfs/WebNfsFile.java
1 /*
2 * WebNfsFile.java
3 *
4 * Copyright $Date: 2003/08/11 02:22:31 $ FLEXSTOR.net Inc.
5 *
6 * This work is licensed for use and distribution under license terms found at
7 * http://www.flexstor.org/license.html
8 *
9 */
10
11 package com.flexstor.common.io.xfile.webnfs;
12
13 import java.io.BufferedInputStream;
14 import java.io.BufferedOutputStream;
15 import java.io.BufferedReader;
16 import java.io.BufferedWriter;
17 import java.io.IOException;
18 import java.net.UnknownHostException;
19 import java.util.Vector;
20
21 import com.flexstor.common.io.xfile.FlexXFileI;
22 import com.flexstor.common.io.xfile.XFilenameFilterI;
23 import com.flexstor.common.io.xfile.parsers.XStringValidator;
24 import com.flexstor.common.util.FlexDbServerHost;
25 import com.flexstor.common.util.InetUtil;
26 import com.sun.xfile.XFile;
27
28 /**
29 * This subclass of XFile overwrites some methods which otherwise will fail if:
30 *
31 * - The protocol used is a NFS URL and the path specified is mounted from another server
32 * OR
33 * - The path contains some escape codes and special characters that must be preserved.
34 *
35 * Inside these overwriten methods we first determine if the path is a NFS URL; if it is, use
36 * the super class method; if that fails and the file is local to the JVM server we create a
37 * new XFile instance (not FlexXFile) with a local path as argument where all special characters
38 * have been replaced.
39 *
40 * David C. 03/01/00
41 */
42 public class WebNfsFile
43 extends XFile implements FlexXFileI
44 {
45 private String sServer = null;
46 private String sLocalPath = null;
47 private boolean bSolaris = true;
48 private boolean bLocalFile = false;
49 private static String sLocalHost = null;
50
51 public WebNfsFile(XFile file, String str)
52 {
53 super(new WebNfsFile(file.toString()), str);
54 setServerAndPath( super.getAbsolutePath() );
55 }
56
57 public WebNfsFile(String str)
58 {
59 super(str);
60 setServerAndPath( super.getAbsolutePath() );
61 }
62
63 public BufferedInputStream getBufferedInputStream()
64 throws IOException
65 {
66 return new WebNfsBufferedInputStream(this);
67 }
68
69 public BufferedInputStream getBufferedInputStream(int bufferSize)
70 throws IOException
71 {
72 return new WebNfsBufferedInputStream(this, bufferSize);
73 }
74
75 public BufferedOutputStream getBufferedOutputStream()
76 throws IOException
77 {
78 return new WebNfsBufferedOutputStream(this);
79 }
80
81 public BufferedOutputStream getBufferedOutputStream(int bufferSize)
82 throws IOException
83 {
84 return new WebNfsBufferedOutputStream(this,bufferSize);
85 }
86
87 public BufferedReader getBufferedReader()
88 throws IOException
89 {
90 return new WebNfsBufferedReader(this);
91 }
92
93 public BufferedReader getBufferedReader(int bufferSize)
94 throws IOException
95 {
96 return new WebNfsBufferedReader(this,bufferSize);
97 }
98
99
100 public BufferedWriter getBufferedWriter()
101 throws IOException
102 {
103 return new WebNfsBufferedWriter(this);
104 }
105
106 public BufferedWriter getBufferedWriter(int bufferSize)
107 throws IOException
108 {
109 return new WebNfsBufferedWriter(this, bufferSize);
110 }
111
112 public String[] list(XFilenameFilterI filter)
113 {
114 String names[] = this.list();
115
116 if (names == null)
117 return null;
118
119 // Fill in the Vector
120 Vector v = new Vector();
121 for (int i = 0 ; i < names.length ; i++)
122 {
123 if ((filter == null) || filter.accept((WebNfsFile)this, names[i]))
124 v.addElement(names[i]);
125 }
126
127 // Create the array
128 String files[] = new String[v.size()];
129 v.copyInto(files);
130
131 return files;
132 }
133
134 public String[] list()
135 {
136 String[] list = null;
137 if ( (list = super.list()) != null )
138 return list;
139
140 if ( bLocalFile )
141 return (new XFile( encodeURLString(sLocalPath) )).list();
142 else
143 return null;
144 }
145
146 public boolean mkdir()
147 {
148 if ( super.mkdir() )
149 return true;
150
151 if ( bLocalFile )
152 return (new XFile( encodeURLString(sLocalPath) )).mkdir();
153 else
154 return false;
155 }
156
157 public boolean mkdirs()
158 {
159 if ( super.mkdirs() )
160 return true;
161
162 if ( bLocalFile )
163 return (new XFile( encodeURLString(sLocalPath) )).mkdirs();
164 else
165 return false;
166 }
167
168 public String[] extendedList()
169 {
170 return list();
171 }
172
173 public String[] extendedList(XFilenameFilterI filter)
174 {
175 return list(filter);
176 }
177
178 public String getName()
179 {
180 // WebNFS doesn't return the right name when the object represents a local
181 // directory (no nfs url) and the path ends with a slash.
182 // It only returns it right when it is a nfs URL.
183 // To take no chances, we will always test if the file ends with a slash, if
184 // it does we remove it and then get the name.
185 String sFile = super.getAbsolutePath();
186 if ( sFile.endsWith(getFileSeparator(sFile)) )
187 {
188 sFile = sFile.substring( 0, sFile.length() - 1 );
189 return (new XFile(sFile)).getName();
190 }
191 else
192 return super.getName();
193 }
194
195 public String getParent()
196 {
197 // WebNFS doesn't return the right parent when the object represents a local
198 // directory (no nfs url) and the path ends with a slash.
199 // It only returns it right when it is a nfs URL.
200 // To take no chances, we will always test if the file ends with a slash, if
201 // it does we remove it and then get the parent.
202 String sFile = super.getAbsolutePath();
203 if ( sFile.endsWith(getFileSeparator(sFile)) )
204 {
205 sFile = sFile.substring( 0, sFile.length() - 1 );
206 return (new XFile(sFile)).getParent();
207 }
208 else
209 return super.getParent();
210 }
211
212 public boolean exists()
213 {
214 if ( super.exists() )
215 return true;
216
217 if ( bLocalFile )
218 return (new XFile( encodeURLString(sLocalPath) )).exists();
219 else
220 return false;
221 }
222
223 public boolean canRead()
224 {
225 if ( super.canRead() )
226 return true;
227
228 if ( bLocalFile )
229 return (new XFile( encodeURLString(sLocalPath) )).canRead();
230 else
231 return false;
232 }
233
234 public boolean canWrite()
235 {
236 if ( super.canWrite() )
237 return true;
238
239 if ( bLocalFile )
240 return (new XFile( encodeURLString(sLocalPath) )).canWrite();
241 else
242 return false;
243 }
244
245 public boolean isDirectory()
246 {
247 if ( super.isDirectory() )
248 return true;
249
250 if ( bLocalFile )
251 return (new XFile( encodeURLString(sLocalPath) )).isDirectory();
252 else
253 return false;
254 }
255
256 public boolean isFile()
257 {
258 if ( super.isFile() )
259 return true;
260
261 if ( bLocalFile )
262 return (new XFile( encodeURLString(sLocalPath) )).isFile();
263 else
264 return false;
265 }
266
267 public boolean isAbsolute()
268 {
269 if ( super.isAbsolute() )
270 return true;
271
272 if ( bLocalFile )
273 return (new XFile( encodeURLString(sLocalPath) )).isAbsolute();
274 else
275 return false;
276 }
277
278 public long lastModified()
279 {
280 long nLastMod = 0;
281 if ( (nLastMod = super.lastModified()) != 0 )
282 return nLastMod;
283
284 if ( bLocalFile )
285 return (new XFile( encodeURLString(sLocalPath) )).lastModified();
286 else
287 return 0;
288 }
289
290 public long length()
291 {
292 long nLength = 0;
293 if ( (nLength = super.length()) != 0 )
294 return nLength;
295
296 if ( bLocalFile )
297 return (new XFile( encodeURLString(sLocalPath) )).length();
298 else
299 return 0;
300 }
301
302 public boolean delete()
303 {
304 if ( super.delete() )
305 return true;
306
307 if ( bLocalFile )
308 return (new XFile( encodeURLString(sLocalPath) )).delete();
309 else
310 return false;
311 }
312
313 public boolean renameTo( FlexXFileI xFile )
314 {
315 if(!(xFile instanceof WebNfsFile))
316 return false;
317
318 if ( super.renameTo( (WebNfsFile)xFile ) )
319 return true;
320
321 if ( bLocalFile )
322 // When passes as an argument to XFile, we don't need to encodeURLString the local path
323 return (new XFile( encodeURLString(sLocalPath) )).renameTo( new XFile(xFile.getLocalPath()) );
324 else
325 return false;
326 }
327
328 public String getServer()
329 {
330 return sServer;
331 }
332
333 /**
334 * returns the path, without the nfs://sServer portion.
335 */
336 public String getLocalPath()
337 {
338 return sLocalPath;
339 }
340
341 /**
342 * Returns true if the files resides in this server; false otherwise
343 */
344 public boolean isLocalPath()
345 {
346 return bLocalFile;
347 }
348
349 /**
350 * Returns true if the OS is Solaris
351 */
352 public boolean isOSSolaris()
353 {
354 return bSolaris;
355 }
356
357 public String getLocalParent()
358 {
359 return (new WebNfsFile(sLocalPath)).getParent();
360 }
361
362 /**
363 * Returns the path of this file as a UNC (Universal Naming Convension)
364 * e.g. \\SERVER_NAME\location\filename
365 */
366 public String getUNCPath()
367 {
368 StringBuffer sbUNCPath = new StringBuffer( "\\\\" );
369 sbUNCPath.append( this.getServer() );
370
371 String sPath = this.getLocalPath();
372 sPath = sPath.replace( '/', '\\' );
373 sbUNCPath.append( sPath );
374 return sbUNCPath.toString();
375 }
376
377 /**
378 * Returns the path of this file as a UNC (Universal Naming Convension), excluding the
379 * server name.
380 * e.g. \location\filename
381 */
382 public String getLocalUNCPath()
383 {
384 String sPath = this.getLocalPath();
385 sPath = sPath.replace( '/', '\\' );
386 return sPath;
387 }
388
389 /**
390 * Set the information for the Server DNS and local path (without the nfs://server portion)
391 */
392 private void setServerAndPath( String sFile )
393 {
394 // Get the local host
395 if ( sLocalHost == null )
396 {
397 // If this host if the FlexDBServer machine, use the FlexDbServerHost class to
398 // determine the name of the local host, otherwise use the InetUtil class
399 if ( FlexDbServerHost.isLocalHost() )
400 sLocalHost = FlexDbServerHost.getLocalHostName();
401 else
402 sLocalHost = InetUtil.getLocalHostName();
403 }
404
405 sServer = sFile.substring(6, sFile.indexOf("/", 6));
406 sLocalPath = sFile.substring( sServer.length() + 6);
407
408 String sFileSeparator = getFileSeparator( sFile );
409 // Store local path without slash at the end
410 // some methods like mkdir(), mkdirs() will fail if the directory has
411 // a trailing slash
412 if ( sLocalPath.endsWith( sFileSeparator ) )
413 sLocalPath = sLocalPath.substring( 0, sLocalPath.length() - 1 );
414
415 // Lets determine if the file is in this server or not; all overwriten method
416 // will need to known this for proper procedure
417 // NOTE: Some operating systems, other than Solaris, doesn't have a proper
418 // implementation of WebNFS, therefore we will need to threat every path in
419 // those operating systems as local.
420 String osName = System.getProperty("os.name");
421 if ( osName.equals("Irix") || osName.equals("HP-UX") || osName.equals("Linux") )
422 {
423 bSolaris = false;
424 bLocalFile = true;
425 }
426 else
427 {
428 try
429 {
430 // If this host if the FlexDBServer machine, use the FlexDbServerHost class to
431 // determine if this is the local host, otherwise use the InetUtil class
432 if ( FlexDbServerHost.isLocalHost() )
433 bLocalFile = FlexDbServerHost.isLocalHost( sServer );
434 else
435 bLocalFile = InetUtil.isLocalHost( sServer );
436 }
437 catch ( UnknownHostException uhe )
438 {
439 bLocalFile = false;
440 }
441 }
442 }
443
444 /**
445 * Replace occurrencies of special characters with its %<something> translation
446 *
447 * Make sure to call this method before passing the file path
448 * argument to the super constructor.
449 */
450 protected static String encodeURLString(String str)
451 {
452 if(str != null)
453 str = XStringValidator.encodeURLString(str);
454
455 return str;
456 }
457
458 public String getFileSeparator()
459 {
460 return getFileSeparator(this.getAbsolutePath());
461 }
462
463 public static String getFileSeparator(String sFile)
464 {
465 if ( sFile.startsWith("nfs") ||
466 sFile.startsWith("file") ||
467 sFile.startsWith("/") )
468 return "/";
469 else
470 return "\\";
471 }
472
473 public String toString()
474 {
475 return getAbsolutePath();
476 }
477 }