Project Report: fawkez

Packagesummary org.jcoderz.commons.connector.file

org.jcoderz.commons.connector.file.FsConnectionImpl

LineHitsNoteSource
1  /*
2   * $Id: FsConnectionImpl.java 1011 2008-06-16 17:57:36Z amandel $
3   *
4   * Copyright 2006, The jCoderZ.org Project. All rights reserved.
5   *
6   * Redistribution and use in source and binary forms, with or without
7   * modification, are permitted provided that the following conditions are
8   * met:
9   *
10   *    * Redistributions of source code must retain the above copyright
11   *      notice, this list of conditions and the following disclaimer.
12   *    * Redistributions in binary form must reproduce the above
13   *      copyright notice, this list of conditions and the following
14   *      disclaimer in the documentation and/or other materials
15   *      provided with the distribution.
16   *    * Neither the name of the jCoderZ.org Project nor the names of
17   *      its contributors may be used to endorse or promote products
18   *      derived from this software without specific prior written
19   *      permission.
20   *
21   * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
22   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24   * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS
25   * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28   * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30   * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32   */
33  package org.jcoderz.commons.connector.file;
34  
35  import java.io.File;
36  import java.io.FileFilter;
37  import java.io.FileInputStream;
38  import java.io.FileNotFoundException;
39  import java.io.FileOutputStream;
40  import java.io.IOException;
41  import java.io.RandomAccessFile;
42  import java.nio.channels.FileChannel;
43  import java.util.HashSet;
44  import java.util.Iterator;
45  import java.util.Properties;
46  import java.util.Random;
47  import java.util.Set;
48  import java.util.logging.Level;
49  import java.util.logging.Logger;
50  
51  import javax.resource.ResourceException;
52  import javax.resource.spi.SecurityException;
53  
54  import org.jcoderz.commons.connector.ConnectionBase;
55  import org.jcoderz.commons.connector.ConnectionNotificationListener;
56  import org.jcoderz.commons.util.IoUtil;
57  
58  
59  /**
60   * Implements the File System Connection.
61   * This connection handle provides physical interraction to the File System.
62   * This behavior is not really conform to the JCA specification, but satisfy
63   * requirenments to provide set of base operations on the underlying File
64   * System.
65   *
66   */
67  class FsConnectionImpl
68        extends ConnectionBase
69        implements FsConnection
70  {
71     public static final String TMP_FILE_PREFIX = "FWK";
72     public static final String TMP_FILE_SUFFIX = "fwk";
73  
74  
75     /** The full qualified name of this class. */
7675    private static final String CLASSNAME = FsConnectionImpl.class.getName();
77  
78     /** The logger to use. */
79100    private static final Logger logger = Logger.getLogger(CLASSNAME);
80  
81     /** Random instance to use for generating of backup file names. */
82100    private static final Random RANDOM = new Random();
83  
84     /** Helds closable instances. */
85100    private final Set mCloseables = new HashSet();
86  
87     /** Random handle for debug logging. */
88     private final int mIndex;
89     /** To string holder. */
90     private final String mStringified;
91  
92     /** The file temp dir. **/
93     private final File mTmpDir;
94  
95     private final long mFileTransferChunkSize;
96  
97     /**
98      * Constructor.
99      * @param cnl The listener interesting on this connection.
100      * @param props Configuration properties.
101      */
102     public FsConnectionImpl (ConnectionNotificationListener cnl,
103           Properties props)
104     {
105100       super(cnl);
106100       synchronized (RANDOM)
107        {
108100          mIndex = RANDOM.nextInt(Integer.MAX_VALUE);
109100          mStringified = "FsConnectionImpl[" + mIndex + "]";
11050       }
111  
112100       String tmp = null;
113100       if (props != null)
114        {
115100          tmp = props.getProperty(FsConnectionFactory.PROP_TEMP_DIR);
116        }
117100       if (tmp == null)
118        {
119100          tmp = System.getProperty("java.io.tmpdir");
120        }
121100       mTmpDir = new File(tmp);
122  
123100       if (props != null)
124        {
125100           mFileTransferChunkSize
126                = Long.getLong(FsConnectionFactory.PROP_FILE_TRANSFER_CHUNK_SIZE,
127                    FsConnectionFactory.FILE_TRANSFER_CHUNK_SIZE_DEF_VALUE)
128                    .longValue();
129        }
130        else
131        {
1320           mFileTransferChunkSize
133                = FsConnectionFactory.FILE_TRANSFER_CHUNK_SIZE_DEF_VALUE;
134        }
135  
136100       if (logger.isLoggable(Level.FINER))
137        {
138100          logger.finer("Created FsConnection with attributes TempDir " + mTmpDir
139                 + ", FileTransferChunkSize " + mFileTransferChunkSize);
140        }
141100    }
142  
143     /** {@inheritDoc} */
144     public void close ()
145           throws ResourceException
146     {
147100       logger.entering(CLASSNAME, "close");
148100       setClosed();
149  
150        // be sure that all file access handles are closed
151100       closeAllCloseables();
152100       logger.exiting(CLASSNAME, "close");
153100    }
154  
155     /** {@inheritDoc} */
156     public boolean isExists (String file)
157           throws ResourceException
158     {
159100       final String method = "isExists";
160100       logger.entering(CLASSNAME, method, file);
161100       assertValid();
162  
163100       final boolean result = isFileExists(new File(file));
164  
165100       logger.exiting(CLASSNAME, method, Boolean.valueOf(result));
166100       return result;
167     }
168  
169     static javax.resource.spi.SecurityException
170           createReadAccessSecurityException (String file,
171                 java.lang.SecurityException se)
172     {
1730       final javax.resource.spi.SecurityException rse
174              = new javax.resource.spi.SecurityException(
175                 "The SecurityManager denies read access to the file '"
176                       + file + "' or to the parent derectory.");
1770       se.initCause(se);
1780       return rse;
179     }
180  
181     /** {@inheritDoc} */
182     public boolean deleteFile (String file)
183           throws ResourceException
184     {
185100       assertValid();
186100       return deleteFile(new File(file));
187     }
188  
189     /** {@inheritDoc} */
190     public String [] listFiles (final String dir)
191           throws ResourceException
192     {
193100       final String method = "listFiles";
194100       logger.entering(CLASSNAME, method, dir);
195100       assertValid();
196  
197100       final File file = new File(dir);
198        final String [] result;
199  
200        try
201        {
202100          result = file.list();
203        }
2040       catch (java.lang.SecurityException se)
205        {
2060          final javax.resource.spi.SecurityException rse
207                 = new javax.resource.spi.SecurityException("The SecurityManager "
208                       + "denies read access to the directory '" + dir + "'.");
2090          rse.initCause(se);
2100          logger.throwing(CLASSNAME, method, rse);
2110          throw rse;
212100       }
213  
214100       logger.exiting(CLASSNAME, method, result);
215100       return result;
216     }
217  
218     /** {@inheritDoc} */
219     public void renameFile (final String from, final String to)
220           throws ResourceException
221     {
222100       final String method = "rename";
223100       logger.entering(CLASSNAME, method, new Object [] {from, to});
224100       assertValid();
225  
226100       moveFile(from, to);
227100       logger.exiting(CLASSNAME, method);
228100    }
229  
230     /** {@inheritDoc} */
231 (1)   public void moveFile (final String src, final String dest)
232           throws ResourceException
233     {
234100       final String method = "move";
235100       logger.entering(CLASSNAME, method, new Object [] {src, dest});
236100       assertValid();
237  
238100       final File srcFile = new File(src);
239100       final File destFile = new File(dest);
240  
241100       ResourceException re = null;
242100       File backupFile = null;
243  
244100       if (!isFileExists(srcFile))
245        {
246100          re = new ResourceException("File '" + srcFile.toString()
247                 + "' does not exist.");
248100          logger.throwing(CLASSNAME, method, re);
249100          throw re;
250        }
251  
252100       if (!srcFile.canWrite())
253        {
2540          re = new ResourceException("File '" + srcFile.toString()
255                 + "' is not writable.");
2560          logger.throwing(CLASSNAME, method, re);
2570          throw re;
258        }
259  
260100       if (isFileExists(destFile))
261        {
262  
2630          if (!destFile.canWrite())
264           {
2650             re = new ResourceException("The destination file '"
266                    + destFile.toString() + "' does already exist and is not "
267                    + "writable.");
2680             logger.throwing(CLASSNAME, method, re);
2690             throw re;
270           }
271  
2720          backupFile = getBackupFile(destFile);
2730          re = rename(destFile, backupFile);
274  
2750          if (re != null)
276           {
2770             logger.throwing(CLASSNAME, method, re);
2780             throw re;
279           }
280        }
281        else
282        {
283100          createParentDirs(destFile);
284        }
285  
286100       re = rename(srcFile, destFile);
287  
288100       if (re != null)
289        {
2900          if (backupFile != null)
291           {
292              // rollback
2930             final ResourceException e = rename(backupFile, destFile);
2940             if (e != null)
295              {
2960                logger.log(Level.WARNING, "Error while file renaming.", e);
297              }
298           }
299  
3000          logger.throwing(CLASSNAME, method, re);
3010          throw re;
302        }
303  
30450       if (backupFile != null && !backupFile.delete())
305        {
3060          re = new ResourceException("Could not delete file '"
307                 + backupFile.toString() + "'.");
308  
3090          logger.throwing(CLASSNAME, method, re);
3100          throw re;
311        }
312  
313100       logger.exiting(CLASSNAME, method);
314100    }
315  
316     /** {@inheritDoc} */
317     public String createTempFile ()
318           throws ResourceException
319     {
320100       final String method = "createTempFile";
321100       logger.entering(CLASSNAME, method);
322100       assertValid();
323  
324100       final String result = createNewFile(null);
325  
326100       logger.exiting(CLASSNAME, method, result);
327100       return result;
328     }
329  
330     /** {@inheritDoc} */
331     public String createTempFile (final String dir)
332           throws ResourceException
333     {
334100       final String method = "createTempFile";
335100       logger.entering(CLASSNAME, method, dir);
336100       assertValid();
337  
338100       final File f = new File(dir);
339100       if (!isFileExists(f) || !f.isDirectory())
340        {
3410          final ResourceException re = new ResourceException(
342              "Failed to create a new file. A directory named '" + dir
343                 + "' does not exist.");
344  
3450          logger.throwing(CLASSNAME, method, re);
3460          throw re;
347        }
348  
349100       final String result = createNewFile(dir);
350  
351100       logger.exiting(CLASSNAME, method, result);
352100       return result;
353     }
354  
355     /** {@inheritDoc} */
356     public boolean createFile (String file)
357           throws ResourceException
358     {
359100       final String method = "createFile";
360100       logger.entering(CLASSNAME, method, file);
361100       assertValid();
362  
363100       final File f = new File(file);
364  
365        // check if the file does already exist
366100       if (isFileExists(f))
367        {
3680          final ResourceException re = new ResourceException(
369              "Failed to create a new file. A file named '" + file
370                 + "' does already exist.");
3710          logger.throwing(CLASSNAME, method, re);
3720          throw re;
373        }
374  
375        // check all necessary parent directories do exist.
376100       createParentDirs(f);
377  
378        final boolean result;
379        try
380        {
381100          result = f.createNewFile();
382        }
3830       catch (IOException e)
384        {
3850          final ResourceException re = new ResourceException(
386                 "Failed to create a new file '" + file + "'.");
3870          re.initCause(e);
3880          logger.throwing(CLASSNAME, method, re);
3890          throw re;
390        }
3910       catch (java.lang.SecurityException se)
392        {
3930          final javax.resource.spi.SecurityException rse
394              = new javax.resource.spi.SecurityException(
395                    "Failed to create a new file.");
3960          rse.initCause(se);
3970          logger.throwing(CLASSNAME, method, rse);
3980(2)         throw rse;
399100       }
400  
401100       logger.exiting(CLASSNAME, method, Boolean.valueOf(result));
402  
403100       return result;
404     }
405  
406     /**
407      * @param method
408    * @throws ResourceException
409    * @throws SecurityException
410    */
411     private void createParentDirs (final File f)
412 (3)         throws ResourceException, SecurityException
413     {
414100       final String method = "createParentDirs";
415100       logger.entering(CLASSNAME, method, f);
416100       final File parent = f.getParentFile();
417100       if (!isFileExists(parent))
418        {
419           // if not -> creates all missing parent directories
420           try
421           {
422100             if (!parent.mkdirs())
423              {
4240                final ResourceException re = new ResourceException("Failed to "
425                       + "create all necessary file directories: "
426                          + parent.toString());
4270                logger.throwing(CLASSNAME, method, re);
4280                throw re;
429              }
430100             logger.finer("Created all necessary parant directories "
431                    + parent.toString());
432           }
4330          catch (java.lang.SecurityException se)
434           {
4350             final javax.resource.spi.SecurityException rse
436                    = new javax.resource.spi.SecurityException("Failed to create "
437                          + "all necessary file directories: "
438                          + parent.toString());
4390             rse.initCause(se);
4400             logger.throwing(CLASSNAME, method, rse);
4410             throw rse;
442100          }
443        }
444100       logger.exiting(CLASSNAME, method);
445100    }
446  
447     /** {@inheritDoc} */
448     public String renameToTempFile (String file)
449           throws ResourceException
450     {
451100       final String method = "renameToTempFile";
452100       logger.entering(CLASSNAME, method, file);
453100       assertValid();
454  
455        final String result;
456        try
457        {
458100          final File tempFile = createTempFileInTempDir();
459100(4)         tempFile.delete();
460100          final File srcFile = new File(file);
461  
462100          if (srcFile.renameTo(tempFile))
463           {
464100             result = tempFile.getAbsolutePath();
465           }
466           else
467           {
468100             final ResourceException re = new ResourceException(
469                    "The rename operation failed.");
470100             logger.throwing(CLASSNAME, method, re);
471100(5)            throw re;
472           }
473        }
4740       catch (SecurityException se)
475        {
4760          final javax.resource.spi.SecurityException rse
477                 = new javax.resource.spi.SecurityException("Security Manager "
478                       + "does not allow the file '" + file + "' to be renamed or"
479                             + " a temp file to be created");
4800          rse.initCause(se);
4810          logger.throwing(CLASSNAME, method, rse);
4820          throw rse;
483        }
4840       catch (IOException ioe)
485        {
4860          final ResourceException re = new ResourceException("The rename "
487                 + "operation failed.");
4880          re.initCause(ioe);
4890          logger.throwing(CLASSNAME, method, re);
4900(6)         throw re;
491100       }
492  
493100       logger.exiting(CLASSNAME, method, result);
494100       return result;
495     }
496  
497     private File createTempFileInTempDir ()
498           throws IOException
499     {
500100       return File.createTempFile(TMP_FILE_PREFIX, TMP_FILE_SUFFIX, mTmpDir);
501     }
502  
503     /**
504      * Creates a new file. If the parameter <code>file</code> is null - creates
505      * an empty file in the default temporary-file directory; if the parameter
506      * <code>file</code> denotes to an existing directory - creates an empty file
507      * in this directory; otherwise creates an empty file named
508      * <code>file</code>.
509      *
510      * @param file null, directory name or file name.
511      *
512      * @return The name of the created file.
513      *
514      * @throws ResourceException thrown if the file could not be created.
515      */
516     private String createNewFile (final String file)
517           throws ResourceException
518     {
519100       final String method = "createNewFile";
520100       logger.entering(CLASSNAME, method, file);
521100       assertValid();
522        final File resultFile;
523100       if (file == null)
524        {
525100          resultFile = createTempDir(mTmpDir);
526        }
527        else
528        {
529100          final File f = new File(file);
530100          if (isFileExists(f) && f.isDirectory())
531           {
532100             resultFile = createTempDir(f);
533           }
534           else
535           {
5360             resultFile = crateNewFile(f);
537           }
538        }
539100       final String result = resultFile.toString();
540100       logger.exiting(CLASSNAME, method, result);
541100       return result;
542     }
543  
544     /**
545      * Creates a new file <code>file</code>.
546      * @param file The file to be created.
547      * @return The <code>file</code>.
548      * @throws ResourceException thrown if the file could not be created.
549      */
550     File crateNewFile (final File file)
551           throws ResourceException
552     {
5530(7)      final String msg = "Failed to create '" + file.getAbsolutePath() + "'";
554        try
555        {
5560          if (!file.createNewFile())
557           {
5580             final ResourceException re = new ResourceException(
559                 "Failed to create a new file. The file '" + file.toString()
560                       + "' does already exist.");
5610             throw re;
562           }
563        }
5640       catch (IOException e)
565        {
5660          final ResourceException re = new ResourceException(msg);
5670          re.initCause(e);
5680          throw re;
569        }
5700       catch (java.lang.SecurityException se)
571        {
5720          final javax.resource.spi.SecurityException rse
573              = new javax.resource.spi.SecurityException(msg);
5740          rse.initCause(se);
5750          throw rse;
5760       }
5770       return file;
578     }
579  
580     /**
581      * Creates a new temp file within of the given temp dir.
582      * @param tempDirFile The temp dir
583      * @return The new temp file.
584      * @throws ResourceException thrown if the file could not be created.
585      */
586     File createTempDir (final File tempDirFile)
587 (8)(9)(10)         throws ResourceException, javax.resource.spi.SecurityException
588     {
589        final File result;
590100       final String msg = "Failed to create a new temp file, temp dir '"
591           + tempDirFile.toString() + "'";
592        try
593        {
594100          result = File.createTempFile(TMP_FILE_PREFIX, TMP_FILE_SUFFIX,
595                 tempDirFile);
596        }
5970       catch (IOException e)
598        {
5990          final ResourceException re = new ResourceException(msg);
6000          re.initCause(e);
6010          throw re;
602        }
6030       catch (java.lang.SecurityException se)
604        {
6050          final javax.resource.spi.SecurityException rse
606              = new javax.resource.spi.SecurityException(msg);
6070          rse.initCause(se);
6080          throw rse;
609100       }
610100       return result;
611     }
612  
613     /**
614      * Renames file <code>src</code> to <code>dest</code>.
615      * @param src file to be renamed.
616      * @param dest the new file name.
617      * @return ResourceException in case of the rename operation failes.
618      */
619     private ResourceException rename (final File src, final File dest)
620     {
621100       if (logger.isLoggable(Level.FINER))
622        {
623100          logger.entering(CLASSNAME, "rename", new Object [] {src, dest});
624        }
625  
626100       ResourceException re = null;
627  
628100       if (!src.renameTo(dest))
629        {
630           // probably the underlying native implementation does not support
631           // renameTo on different file systems.
632           try
633           {
634              // copy the file
6350             copyFilesChunk(src, dest, mFileTransferChunkSize);
636  
637              // delete the source file
6380             deleteFile(src);
639           }
6400          catch (ResourceException r)
641           {
6420             re = r;
6430          }
644        }
645  
646100       if (logger.isLoggable(Level.FINER))
647        {
648100          logger.exiting(CLASSNAME, "rename", re);
649        }
650100       return re;
651     }
652  
653     /**
654      * @param file The original file.
655      * @return The File instance that can be used for back up. The File does yet
656      * not exist.
657      * @throws SecurityException thown in case of security problem
658      */
659     public static File getBackupFile (final File file)
660           throws SecurityException
661     {
6620       File backupFile = getSuggestionForBackupFile(file);
6630       while (isFileExists(backupFile))
664        {
6650          backupFile = getSuggestionForBackupFile(file);
666        }
6670       return backupFile;
668     }
669  
670     /**
671      * @param file The original file.
672      * @return The suggestion for a backup file.
673      */
674     public static File getSuggestionForBackupFile (final File file)
675     {
6760       return new File(file.getParent(),
677              file.getName() + Integer.toString(RANDOM.nextInt()));
678     }
679  
680     /** {@inheritDoc} */
681     public RandomAccessFile getRandomAccessFile (String file, String mode)
682 (11)         throws ResourceException, FileNotFoundException
683     {
684100       final String method = "getRandomAccessFile";
685100       logger.entering(CLASSNAME, method, new Object [] {file, mode});
686100       assertValid();
687  
688        final RandomAccessFileWrapper raf;
689        try
690        {
691100          raf = new RandomAccessFileWrapper(this, file, mode);
692        }
6930       catch (java.lang.SecurityException se)
694        {
6950          final javax.resource.spi.SecurityException rse
696                 = createReadAccessSecurityException(file, se);
6970          logger.throwing(CLASSNAME, method, rse);
6980(12)         throw rse;
699100       }
700  
701100       mCloseables.add(raf);
702100       logger.exiting(CLASSNAME, method, raf);
703100       return raf;
704     }
705  
706     /** {@inheritDoc} */
707     public FileInputStream getFileInputStream (String file)
708 (13)         throws ResourceException, FileNotFoundException
709     {
710100       final String method = "getFileInputStream";
711  
712100       logger.entering(CLASSNAME, method, file);
713100       assertValid();
714  
715        final FileInputStreamWrapper fis;
716  
717        try
718        {
719100          fis = new FileInputStreamWrapper(this, file);
720        }
7210       catch (java.lang.SecurityException se)
722        {
7230          final javax.resource.spi.SecurityException rse
724                 = createReadAccessSecurityException(file, se);
7250          logger.throwing(CLASSNAME, method, rse);
7260(14)         throw rse;
727100       }
728  
729100       mCloseables.add(fis);
730100       logger.exiting(CLASSNAME, method, fis);
731100       return fis;
732     }
733  
734     /**
735      * Sets this connection to the state cleaned up. All futher calls on the
736      * public methods of this connection will throw a ResourceException.
737      */
738     public void cleanUp ()
739     {
740100       logger.entering(CLASSNAME, "cleanUp");
741100       super.cleanUp();
742100       closeAllCloseables();
743100       logger.exiting(CLASSNAME, "cleanUp");
744100    }
745  
746     /**
747      * Closess all RandomAccessFile handles, if yet not closed
748      */
749     private void closeAllCloseables ()
750     {
751100       logger.entering(CLASSNAME, "closeAllCloseables");
752100       final Iterator itr = mCloseables.iterator();
753100       Closeable c = null;
754100       while (itr.hasNext())
755        {
756100          c = (Closeable) itr.next();
757           try
758           {
759100             c.close();
760           }
7610          catch (IOException e)
762           {
7630             logger.log(Level.FINE, "Could not close the Closeable '" + c + "'.",
764                    e);
76550          }
766        }
767100       mCloseables.clear();
768  
769100       logger.exiting(CLASSNAME, "closeAllCloseables");
770100    }
771  
772     /**
773      * Removes the Closeable <code>c</code> from the list of closeable objects.
774      * @param c Closeable to be removed from the list of closeable objects.
775      */
776     public void closeableClosed (Closeable c)
777     {
778100       logger.entering(CLASSNAME, "closeableClosed", c);
779100       mCloseables.remove(c);
780100       logger.exiting(CLASSNAME, "closeableClosed");
781100    }
782  
783     /**
784      * Deletes the supplied file or directory <code>file</code>.
785      *
786      * @param file The file or directory to be deleted.
787      *
788      * @return if and only if the file or directory is successfully deleted;
789      *    false otherwise
790      *
791      * @throws ResourceException If a security manager does not allow the file to
792      *    be deleted.
793      */
794     static boolean deleteFile (final File file)
795           throws SecurityException
796     {
797100(15)      final String method = "deleteFile";
798100       logger.entering(CLASSNAME, method, file);
799        final boolean result;
800        try
801        {
802100          result = file.delete();
803        }
8040       catch (java.lang.SecurityException se)
805        {
8060          final javax.resource.spi.SecurityException rse
807                 = new javax.resource.spi.SecurityException(
808                       "The SecurityManager denies delete access to the file '"
809                          + file.toString() + "'.");
8100          rse.initCause(se);
8110          logger.throwing(CLASSNAME, method, rse);
8120          throw rse;
813100       }
814100       logger.exiting(CLASSNAME, method, Boolean.valueOf(result));
815100       return result;
816     }
817  
818     static void copyFilesChunk (File src, File dist, long chunkSize)
819           throws ResourceException
820     {
8210       final String method = "copyFiles";
8220       final boolean finer = logger.isLoggable(Level.FINER);
8230       if (finer)
824        {
8250          logger.entering(CLASSNAME, method, new Object [] {src, dist});
826        }
8270       FileInputStream fis = null;
8280       FileOutputStream fos = null;
8290       FileChannel srcChannel = null;
8300       FileChannel dstChannel = null;
831        try
832        {
833           // Create input stream on the source
8340          fis = new FileInputStream(src);
835  
836           // Create output stream on the source
8370          fos = new FileOutputStream(dist);
838  
839           // Create channel on the source
8400          srcChannel = fis.getChannel();
841  
842           // Create channel on the destination
8430          dstChannel = fos.getChannel();
844  
845           // Determine the channel size
8460          final long size = srcChannel.size();
847  
8480          logger.finer("srcChannel.size() " + size);
8490          long chunk = chunkSize < size ? chunkSize : size;
8500          long currentpos = 0;
8510          long chunkTransfered = 1L;
8520          long transfered = 0;
853  
8540          while (chunkTransfered > 0 && transfered != size)
855           {
856              // Copy file contents from source to destination
8570             chunkTransfered = dstChannel.transferFrom(srcChannel, currentpos,
858                    chunk);
8590             currentpos = chunk + currentpos;
860  
8610             if (finer)
862              {
8630                logger.finer("Using chunk " + chunk + "Copied next chunk "
864                       + chunkTransfered + ", new pos " + currentpos);
865              }
866  
8670             if (chunk != chunkTransfered)
868              {
8690                final ResourceException re = new ResourceException(
870                    "Failed to copy file '" + src.toString() + "' to '"
871                       + dist.toString()
872                       + "' Not all bytes could be transfered.");
8730                logger.throwing(CLASSNAME, method, re);
8740                throw re;
875              }
8760             transfered = transfered + chunkTransfered;
8770             if (chunkSize >= size - transfered)
878              {
8790                chunk = size - transfered;
880              }
881  
8820             if (finer)
883              {
8840                logger.finer("Transfered " + transfered + " bytes from " + src
885                       + " to " + dist + ".");
886              }
887           }
888        }
8890       catch (IOException e)
890        {
8910          final ResourceException re = new ResourceException(
892              "Failed to copy file '" + src.toString() + "' to '"
893                 + dist.toString() + "'.");
8940          re.initCause(e);
8950          logger.throwing(CLASSNAME, method, re);
8960          throw re;
897        }
898        finally
899        {
900           // Close the channels
9010          IoUtil.close(srcChannel);
9020          IoUtil.close(dstChannel);
903  
904           // Close the streams
9050          IoUtil.close(fis);
9060          IoUtil.close(fos);
9070       }
908  
9090       logger.exiting(CLASSNAME, method);
9100    }
911  
912  
913     /** {@inheritDoc} */
914     public String toString ()
915     {
916100       return mStringified;
917     }
918  
919     /** {@inheritDoc} */
920     public int hashCode ()
921     {
922100       return mIndex;
923     }
924  
925     /** {@inheritDoc} */
926     public boolean equals (Object obj)
927     {
9280       return (obj instanceof FsConnectionImpl
929              && ((FsConnectionImpl) obj).mIndex == this.mIndex);
930     }
931  
932     static boolean isFileExists (final File file)
933           throws SecurityException
934     {
935100       boolean result = false;
936        try
937        {
938100          result = file.exists();
939  
940100          if (!result)
941           {
942100             final File parent = file.getParentFile();
943100             if (parent != null)
944              {
945100                final File [] lst = parent.listFiles(new SingleFileFilter(file));
94666                if (lst != null && lst.length == 1 && lst[0].equals(file))
947                 {
9480                   result = true;
949                 }
950              }
951           }
952        }
9530       catch (java.lang.SecurityException se)
954        {
9550          final javax.resource.spi.SecurityException rse
956                 = createReadAccessSecurityException(file.toString(), se);
9570(16)         throw rse;
958100       }
959100       return result;
960     }
961  
962     private static final class SingleFileFilter
963           implements FileFilter
964     {
965        private final File mFile;
966  
967        public SingleFileFilter (File org)
968100       {
969100          mFile = org;
970100       }
971        public boolean accept (File pathname)
972        {
973100          return mFile.equals(pathname);
974        }
975     }
976  
977  }

Findings in this File

c (1) 231 : 11 The method moveFile() has an NPath complexity of 240
i (2) 398 : 0 method org.jcoderz.commons.connector.file.FsConnectionImpl.createFile(String) throws exception with static message string
c (3) 412 : 17 Unable to get class information for ResourceException.
w (4) 459 : 0 org.jcoderz.commons.connector.file.FsConnectionImpl.renameToTempFile(String) ignores exceptional return value of java.io.File.delete()
i (5) 471 : 0 method org.jcoderz.commons.connector.file.FsConnectionImpl.renameToTempFile(String) throws exception with static message string
i (6) 490 : 0 method org.jcoderz.commons.connector.file.FsConnectionImpl.renameToTempFile(String) throws exception with static message string
w (7) 553 : 0 Method org.jcoderz.commons.connector.file.FsConnectionImpl.crateNewFile(File) assigns a variable in a larger scope then is needed
c (8) 587 : 17 Unable to get class information for ResourceException.
w (9) 587 : 36 Redundant throws: 'javax.resource.spi.SecurityException' listed more then one time.
c (10) 587 : 36 Unable to get class information for javax.resource.spi.SecurityException.
c (11) 682 : 17 Unable to get class information for ResourceException.
w (12) 698 : 0 Method org.jcoderz.commons.connector.file.FsConnectionImpl.getRandomAccessFile(String, String) throws alternative exception from catch block without history
c (13) 708 : 17 Unable to get class information for ResourceException.
w (14) 726 : 0 Method org.jcoderz.commons.connector.file.FsConnectionImpl.getFileInputStream(String) throws alternative exception from catch block without history
w (15) 797 : 0 class org.jcoderz.commons.connector.file.FsConnectionImpl 'overloads' a method with both instance and static versions
w (16) 957 : 0 Method org.jcoderz.commons.connector.file.FsConnectionImpl.isFileExists(File) throws alternative exception from catch block without history