Coverage Report - org.apache.commons.cache.ShareableFileStash
 
Classes in this File Line Coverage Branch Coverage Complexity
RecursiveFileDeleter
0%
0/17
0%
0/12
3.095
ShareableFileStash
0%
0/136
0%
0/40
3.095
 
 1  
 /*
 2  
  * Copyright 2001-2004 The Apache Software Foundation
 3  
  *
 4  
  * Licensed under the Apache License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  *     http://www.apache.org/licenses/LICENSE-2.0
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 package org.apache.commons.cache;
 17  
 
 18  
 import java.util.StringTokenizer;
 19  
 import java.io.ByteArrayOutputStream;
 20  
 import java.io.ObjectOutputStream;
 21  
 import java.io.ObjectInputStream;
 22  
 import java.io.FileOutputStream;
 23  
 import java.io.FileInputStream;
 24  
 import java.io.BufferedInputStream;
 25  
 import java.io.BufferedOutputStream;
 26  
 import java.io.Serializable;
 27  
 import java.io.IOException;
 28  
 import java.io.File;
 29  
 
 30  
 /**
 31  
  * tk.
 32  
  * @version $Id: ShareableFileStash.java 155435 2005-02-26 13:17:27Z dirkv $
 33  
  * @author Rodney Waldhoff
 34  
  */
 35  
 public class ShareableFileStash extends BaseStash implements Stash {
 36  0
     protected int _numDirectories = 10;
 37  0
     protected File _rootdir = null;
 38  0
     protected int _maxFilenameLength = 128;
 39  
 
 40  
     /**
 41  
      * @param root the root directory to store objects in
 42  
      * @param numdirs the number of directories to create under root (must be >0)
 43  
      */
 44  0
     public ShareableFileStash(String root, int numdirs) {
 45  0
         _rootdir = new File(root);
 46  0
         _numDirectories = numdirs;
 47  0
     }
 48  
 
 49  
     /**
 50  
      * @param root the root directory to store objects in
 51  
      * @param numdirs the number of directories to create under root (must be >0)
 52  
      */
 53  0
     public ShareableFileStash(File root, int numdirs) {
 54  0
         _rootdir = root;
 55  0
         _numDirectories = numdirs;
 56  0
     }
 57  
 
 58  
     /**
 59  
      * @param root the root directory to store objects in
 60  
      * @param numdirs the number of directories to create under root (must be >0)
 61  
      * @param maxfilenamelength the maximum length filename to create
 62  
      */
 63  0
     public ShareableFileStash(File root, int numdirs, int maxfilenamelength) {
 64  0
         _rootdir = root;
 65  0
         _numDirectories = numdirs;
 66  0
         _maxFilenameLength = maxfilenamelength;
 67  0
     }
 68  
 
 69  
     /**
 70  
      * @param root the root directory to store objects in
 71  
      * @param numdirs the number of directories to create under root (must be >0)
 72  
      * @param maxfilenamelength the maximum length filename to create
 73  
      */
 74  0
     public ShareableFileStash(String root, int numdirs, int maxfilenamelength) {
 75  0
         _rootdir = new File(root);
 76  0
         _numDirectories = numdirs;
 77  0
         _maxFilenameLength = maxfilenamelength;
 78  0
     }
 79  
 
 80  
     protected byte[] getSerializedForm(Serializable val) {
 81  0
         byte[] serform = null;
 82  0
         if(null == val) {
 83  0
             return null;
 84  
         }
 85  0
         ByteArrayOutputStream byout = null;
 86  0
         ObjectOutputStream out = null;
 87  
         try {
 88  0
             byout = new ByteArrayOutputStream();
 89  0
             out = new ObjectOutputStream(byout);
 90  0
             out.writeObject(val);
 91  0
             out.flush();
 92  0
             serform = byout.toByteArray();
 93  0
         } catch(IOException e) {
 94  0
             serform = null;
 95  
         } finally {
 96  0
             try {
 97  0
                 byout.close();
 98  0
             } catch(Exception e) {
 99  0
             }
 100  
             try {
 101  0
                 out.close();
 102  0
             } catch(Exception e) {
 103  0
             }
 104  0
         }
 105  0
         return serform;
 106  
     }
 107  
 
 108  
     protected synchronized Serializable readFromFile(File file) {
 109  0
         ObjectInputStream oin = null;
 110  
         try {
 111  0
             oin = new ObjectInputStream(new BufferedInputStream(new FileInputStream(file)));
 112  0
             return(Serializable)(oin.readObject());
 113  0
         } catch(Exception e) {
 114  0
             return null;
 115  
         } finally {
 116  0
             try {
 117  0
                 oin.close();
 118  0
             } catch(Exception e) {
 119  0
             }
 120  
         }
 121  
     }
 122  
 
 123  
     protected File getFile(Serializable key, boolean mkdirs) {
 124  0
         String keystr = key.toString();
 125  0
         char[] chars = keystr.toCharArray();
 126  0
         StringBuffer buf = new StringBuffer();
 127  0
         File parent = new File(_rootdir,String.valueOf(Math.abs(keystr.hashCode()%_numDirectories)));
 128  0
         for(int i=0;i<chars.length;i++) {
 129  0
             if((chars[i] >= 'a' && chars[i] <= 'z') ||
 130  
                (chars[i] >= 'A' && chars[i] <= 'Z') ||
 131  
                (chars[i] >= '0' && chars[i] <= '9')) {
 132  0
                 if(buf.length() >= _maxFilenameLength) {
 133  0
                     buf.append("_");
 134  0
                     parent = new File(parent,buf.toString());
 135  0
                     buf.setLength(0);
 136  
                 }
 137  0
                 buf.append(chars[i]);
 138  
             } else {
 139  0
                 if(buf.length() + 5 >= _maxFilenameLength) {
 140  0
                     buf.append("_");
 141  0
                     parent = new File(parent,buf.toString());
 142  0
                     buf.setLength(0);
 143  
                 }
 144  0
                 buf.append("_");
 145  0
                 buf.append(Integer.toHexString((int)chars[i]));
 146  
             }
 147  
         }
 148  0
         if(buf.length() == 0) {
 149  0
             buf.append("_");
 150  
         }
 151  0
         if(mkdirs) {
 152  0
             parent.mkdirs();
 153  
         }
 154  0
         return new File(parent,buf.toString());
 155  
     }
 156  
 
 157  
     public int canStore(Serializable key, Serializable val, Long expiresAt, Long cost, Serializable group, byte[] serialized) {
 158  0
         if(null == serialized) {
 159  0
             serialized = getSerializedForm(val);
 160  
         }
 161  0
         if(null == serialized) {
 162  0
             return Stash.NO;
 163  
         } else {
 164  0
             return Stash.YES;
 165  
         }
 166  
     }
 167  
 
 168  
     public boolean store(Serializable key, Serializable val, Long expiresAt, Long cost, Serializable group, byte[] serialized) {
 169  0
         if(null == serialized) {
 170  0
             serialized = getSerializedForm(val);
 171  
         }
 172  0
         if(null == serialized) {
 173  0
             return false;
 174  
         }
 175  
 
 176  0
         File cachefile = getFile(key,true);
 177  0
         if(null == cachefile) {
 178  0
             return false;
 179  
         }
 180  
 
 181  0
         BufferedOutputStream fout = null;
 182  
         try {
 183  0
             fout = new BufferedOutputStream(new FileOutputStream(cachefile));
 184  0
             fout.write(serialized);
 185  0
             fout.flush();
 186  0
         } catch(Exception e) {
 187  
             try {
 188  0
                 fout.close();
 189  0
             } catch(Exception ex) {
 190  0
             }
 191  0
             fout = null;
 192  
             try {
 193  0
                 cachefile.delete();
 194  0
             } catch(Exception ex) {
 195  0
             }
 196  0
             return false;
 197  
         } finally {
 198  0
             try {
 199  0
                 fout.close();
 200  0
             } catch(Exception e) {
 201  0
             }
 202  0
         }
 203  0
         return true;
 204  
     }
 205  
 
 206  
     public Serializable retrieve(Serializable key) {
 207  0
         File cachefile = getFile(key,false);
 208  0
         if(cachefile.exists()) {
 209  0
             return readFromFile(cachefile);
 210  
         } else {
 211  0
             return null;
 212  
         }
 213  
     }
 214  
 
 215  
     public boolean contains(Serializable key) {
 216  0
         File cachefile = getFile(key,false);
 217  0
         return cachefile.exists();
 218  
     }
 219  
 
 220  
     public float capacity() {
 221  0
         return 0;
 222  
     }
 223  
 
 224  
     public void clear(Serializable key) {
 225  0
         File cachefile = getFile(key,false);
 226  0
         cachefile.delete();
 227  0
     }
 228  
 
 229  
     public synchronized void clear() {
 230  0
         File f = getMoveToLoc();
 231  
         try {
 232  0
             f.getParentFile().mkdirs();
 233  0
         } catch(NullPointerException e) {
 234  
             // ignored
 235  0
         }
 236  0
         _rootdir.renameTo(f);
 237  0
         _rootdir.mkdirs();
 238  0
         Thread t = new Thread(new RecursiveFileDeleter(f));
 239  0
         t.start();
 240  0
     }
 241  
 
 242  
     public boolean wantsSerializedForm() {
 243  0
         return true;
 244  
     }
 245  
 
 246  
     public void unsetCache() {
 247  0
     }
 248  
 
 249  
     public void setCache(Cache c) {
 250  0
     }
 251  
 
 252  
     protected File getMoveToLoc() {
 253  0
         File parent = _rootdir.getAbsoluteFile().getParentFile();
 254  0
         for(int i=0;i<100;i++) {
 255  0
             String fname = String.valueOf(System.currentTimeMillis() % 100000000L);
 256  0
             File f = new File(parent,fname);
 257  0
             if(!f.exists()) {
 258  0
                 return f;
 259  
             }
 260  
             try {
 261  0
                 Thread.currentThread().sleep(17);
 262  0
             } catch(Exception e) {
 263  
                 // ignored
 264  0
             }
 265  
         }
 266  0
         throw new RuntimeException("Couldn't create a temp file to move the shareable file stash to.");
 267  
     }
 268  
 }
 269  
 
 270  
 class RecursiveFileDeleter implements Runnable {
 271  0
     private File _root = null;
 272  
 
 273  0
     public RecursiveFileDeleter(File root) {
 274  0
         _root = root;
 275  0
     }
 276  
 
 277  
     public void run() {
 278  0
         boolean success = recursiveDelete(_root);
 279  0
         if(!success) {
 280  0
             System.err.println("Unable to fully delete the file at \"" + _root + "\". Please delete it manually.");
 281  
         }
 282  0
     }
 283  
 
 284  
     boolean recursiveDelete(File f) {
 285  0
         if(f.isDirectory()) {
 286  0
             File[] files = f.listFiles();
 287  0
             for(int i=0;i<files.length;i++) {
 288  0
                 if(files[i].isFile()) {
 289  0
                     if(!files[i].delete()) {
 290  0
                         return false;
 291  
                     }
 292  
                 } else {
 293  0
                     if(!recursiveDelete(files[i])) {
 294  0
                         return false;
 295  
                     }
 296  
                 }
 297  
             }
 298  
         }
 299  0
         return f.delete();
 300  
     }
 301  
 }
 302  
 
 303  
 
 304