plugins/base2/uk.ac.ebi.tab2mage/trunk/AffyArrayDesignBatchImporter/src/uk/ac/ebi/nugo/common/ZipUnpacker.java

Code
Comments
Other
Rev Date Author Line
391 14 Aug 07 dominic 1 /* $Id: ZipUnpacker.java 2006-08-08 dominic $
391 14 Aug 07 dominic 2   This file is for NutriBASE - Nutrigenomics BioArray Software Environment.
391 14 Aug 07 dominic 3   A customisation of the BASE SOFTWARE.
391 14 Aug 07 dominic 4   Developed at the EBI , Cambridge.
391 14 Aug 07 dominic 5   Author: Dominic Oyeniran: oyeniran@ebi.ac.uk
391 14 Aug 07 dominic 6 */
391 14 Aug 07 dominic 7 package uk.ac.ebi.nugo.common;
391 14 Aug 07 dominic 8
391 14 Aug 07 dominic 9 import java.io.IOException;
391 14 Aug 07 dominic 10 import java.io.InputStream;
478 16 Nov 07 dominic 11 import java.text.SimpleDateFormat;
391 14 Aug 07 dominic 12 import java.util.Date;
478 16 Nov 07 dominic 13 import java.util.Locale;
391 14 Aug 07 dominic 14 import java.util.zip.ZipEntry;
391 14 Aug 07 dominic 15 import java.util.zip.ZipInputStream;
391 14 Aug 07 dominic 16
478 16 Nov 07 dominic 17 import net.sf.basedb.core.BaseException;
391 14 Aug 07 dominic 18 import net.sf.basedb.core.DbControl;
391 14 Aug 07 dominic 19 import net.sf.basedb.core.Directory;
391 14 Aug 07 dominic 20 import net.sf.basedb.core.File;
478 16 Nov 07 dominic 21 import net.sf.basedb.core.ItemAlreadyExistsException;
391 14 Aug 07 dominic 22 import net.sf.basedb.core.Location;
391 14 Aug 07 dominic 23 import net.sf.basedb.core.PluginDefinition;
391 14 Aug 07 dominic 24 import net.sf.basedb.core.Quota;
391 14 Aug 07 dominic 25 import net.sf.basedb.core.QuotaType;
391 14 Aug 07 dominic 26 import net.sf.basedb.core.SessionControl;
391 14 Aug 07 dominic 27 import net.sf.basedb.core.SystemItems;
391 14 Aug 07 dominic 28 import net.sf.basedb.core.User;
391 14 Aug 07 dominic 29 import net.sf.basedb.util.zip.FileUnpacker;
391 14 Aug 07 dominic 30
391 14 Aug 07 dominic 31 import org.apache.log4j.Logger;
391 14 Aug 07 dominic 32
391 14 Aug 07 dominic 33
391 14 Aug 07 dominic 34
391 14 Aug 07 dominic 35 /**
391 14 Aug 07 dominic 36     This class unpacks zip file provided by users into the base file structure
441 30 Oct 07 dominic 37     Note: Parts of the codes were authored by Misha Bayer - email: sbrn@scri.ac.uk,
391 14 Aug 07 dominic 38     @author Dominic Oyeniran 
421 12 Sep 07 dominic 39     @email oyeniran@ebi.ac.uk
421 12 Sep 07 dominic 40     
391 14 Aug 07 dominic 41  */
391 14 Aug 07 dominic 42
391 14 Aug 07 dominic 43 public class ZipUnpacker 
391 14 Aug 07 dominic 44 {
391 14 Aug 07 dominic 45   protected static Logger log = Logger.getLogger(ZipUnpacker.class);
391 14 Aug 07 dominic 46   private User user;
391 14 Aug 07 dominic 47   private File file; 
391 14 Aug 07 dominic 48   private Directory unzippedFilesDirectory;
391 14 Aug 07 dominic 49   private long zipFileSize;
391 14 Aug 07 dominic 50   private int numUnpackedFiles=0;
391 14 Aug 07 dominic 51   private SessionControl sc;
391 14 Aug 07 dominic 52   
391 14 Aug 07 dominic 53   public ZipUnpacker(File zipFile, User user, SessionControl sc)
391 14 Aug 07 dominic 54   {
391 14 Aug 07 dominic 55     this.user = user;
391 14 Aug 07 dominic 56     this.sc=sc;
391 14 Aug 07 dominic 57     this.file= zipFile;
391 14 Aug 07 dominic 58   }
391 14 Aug 07 dominic 59   /**
391 14 Aug 07 dominic 60      Unpacks a zip file, checking that there is enough space to accommodate 
391 14 Aug 07 dominic 61      the zip file once it is unpacked. 
478 16 Nov 07 dominic 62     */
478 16 Nov 07 dominic 63   public void unpack(String dirName)
478 16 Nov 07 dominic 64   {
478 16 Nov 07 dominic 65     log.info("Begin to unpack the files");
478 16 Nov 07 dominic 66     DbControl dc=null;
478 16 Nov 07 dominic 67     try
478 16 Nov 07 dominic 68     {
478 16 Nov 07 dominic 69       dc= sc.newDbControl();
478 16 Nov 07 dominic 70       if (file==null)
478 16 Nov 07 dominic 71         return;
478 16 Nov 07 dominic 72       InputStream inStream =  file.getDownloadStream(0);
478 16 Nov 07 dominic 73       //check if the logged in user has sufficient disk space. if yes go ahead with the unpacking
478 16 Nov 07 dominic 74       boolean hasSpace= checkUserQuota(inStream, dc);
478 16 Nov 07 dominic 75       if (hasSpace)
478 16 Nov 07 dominic 76       {
478 16 Nov 07 dominic 77         createSubDirectory( file, user, dirName);
478 16 Nov 07 dominic 78         // now call the method to unpack the zip files
478 16 Nov 07 dominic 79         PluginDefinition zipFilePlugin = PluginDefinition.getByClassName(dc, "net.sf.basedb.plugins.ZipFileUnpacker");
478 16 Nov 07 dominic 80         FileUnpacker unpacker = zipFilePlugin.newInstance(net.sf.basedb.plugins.ZipFileUnpacker.class, null, dc.getSessionControl(), null, null);
478 16 Nov 07 dominic 81         numUnpackedFiles=unpacker.unpack(dc, unzippedFilesDirectory,file.getDownloadStream(0), false,null);
478 16 Nov 07 dominic 82       }
478 16 Nov 07 dominic 83       else // if space is not enough
478 16 Nov 07 dominic 84       {
478 16 Nov 07 dominic 85         throw new BaseException("User do not have the required Disk Space. Please contact your BASE administrator or remove some files");
478 16 Nov 07 dominic 86       }
478 16 Nov 07 dominic 87       dc.commit(); 
478 16 Nov 07 dominic 88       inStream.close();
478 16 Nov 07 dominic 89     }
478 16 Nov 07 dominic 90     catch (Throwable exc)
478 16 Nov 07 dominic 91     {
478 16 Nov 07 dominic 92       dc.close();
478 16 Nov 07 dominic 93       log.info("File cannot be unpacked", exc);
478 16 Nov 07 dominic 94       new BaseException("File cannot be unpacked :" +exc.getMessage());
478 16 Nov 07 dominic 95     }
478 16 Nov 07 dominic 96     finally
478 16 Nov 07 dominic 97     {
478 16 Nov 07 dominic 98       if (dc!=null)
478 16 Nov 07 dominic 99         dc.close();
478 16 Nov 07 dominic 100     }
478 16 Nov 07 dominic 101   }
478 16 Nov 07 dominic 102   
478 16 Nov 07 dominic 103   
478 16 Nov 07 dominic 104   /**
478 16 Nov 07 dominic 105      Unpacks a zip file, checking that there is enough space to accommodate 
478 16 Nov 07 dominic 106      the zip file once it is unpacked. 
391 14 Aug 07 dominic 107       @throws NutribasePluginException
391 14 Aug 07 dominic 108    */
478 16 Nov 07 dominic 109   public void unpack()
391 14 Aug 07 dominic 110   {
391 14 Aug 07 dominic 111     log.info("Begin to unpack the files");
391 14 Aug 07 dominic 112     DbControl dc=null;
391 14 Aug 07 dominic 113     try
391 14 Aug 07 dominic 114     {
391 14 Aug 07 dominic 115       dc= sc.newDbControl();
391 14 Aug 07 dominic 116       if (file==null)
391 14 Aug 07 dominic 117         return;
391 14 Aug 07 dominic 118       InputStream inStream =  file.getDownloadStream(0);
391 14 Aug 07 dominic 119       //check if the logged in user has sufficient disk space. if yes go ahead with the unpacking
391 14 Aug 07 dominic 120       boolean hasSpace= checkUserQuota(inStream, dc);
391 14 Aug 07 dominic 121       if (hasSpace)
391 14 Aug 07 dominic 122       {
391 14 Aug 07 dominic 123         createSubDirectory( file, user);
441 30 Oct 07 dominic 124         // now call the method to unpack the zip files
391 14 Aug 07 dominic 125         PluginDefinition zipFilePlugin = PluginDefinition.getByClassName(dc, "net.sf.basedb.plugins.ZipFileUnpacker");
391 14 Aug 07 dominic 126         FileUnpacker unpacker = zipFilePlugin.newInstance(net.sf.basedb.plugins.ZipFileUnpacker.class, null, dc.getSessionControl(), null, null);
391 14 Aug 07 dominic 127         numUnpackedFiles=unpacker.unpack(dc, unzippedFilesDirectory,file.getDownloadStream(0), false,null);
391 14 Aug 07 dominic 128       }
391 14 Aug 07 dominic 129       else // if space is not enough
391 14 Aug 07 dominic 130       {
478 16 Nov 07 dominic 131         throw new BaseException("User do not have the required Disk Space. Please contact your BASE administrator or remove some files");
391 14 Aug 07 dominic 132       }
391 14 Aug 07 dominic 133       dc.commit(); 
391 14 Aug 07 dominic 134       inStream.close();
391 14 Aug 07 dominic 135     }
391 14 Aug 07 dominic 136     catch (Throwable exc)
391 14 Aug 07 dominic 137     {
391 14 Aug 07 dominic 138       dc.close();
391 14 Aug 07 dominic 139       log.info("File cannot be unpacked", exc);
478 16 Nov 07 dominic 140       new BaseException(exc.getMessage());
391 14 Aug 07 dominic 141     }
391 14 Aug 07 dominic 142     finally
391 14 Aug 07 dominic 143     {
391 14 Aug 07 dominic 144       if (dc!=null)
391 14 Aug 07 dominic 145         dc.close();
391 14 Aug 07 dominic 146     }
391 14 Aug 07 dominic 147   }
478 16 Nov 07 dominic 148
391 14 Aug 07 dominic 149   /**
391 14 Aug 07 dominic 150      checks user quota
391 14 Aug 07 dominic 151       @param inStream
391 14 Aug 07 dominic 152       @param dc
421 12 Sep 07 dominic 153       @return true, if user has sufficient quqota and false otherwise
391 14 Aug 07 dominic 154    */
391 14 Aug 07 dominic 155   private boolean checkUserQuota(InputStream inStream, DbControl dc)
391 14 Aug 07 dominic 156   {
391 14 Aug 07 dominic 157     boolean hasDiskSpace= false;  
391 14 Aug 07 dominic 158     zipFileSize = getZipfileEntriesSize(inStream);
391 14 Aug 07 dominic 159     //get the user's current disk usage and quota
391 14 Aug 07 dominic 160     Quota quota = user.getQuota();
391 14 Aug 07 dominic 161     QuotaType totalQuotaType = QuotaType.getById(dc, SystemItems.getId(QuotaType.TOTAL));
421 12 Sep 07 dominic 162     //unlimited storage (e.g. for user root) will return -1
391 14 Aug 07 dominic 163     long quotaValue = quota.getQuotaValue(totalQuotaType, Location.PRIMARY);    
441 30 Oct 07 dominic 164     log.info("the quota value of the user: " + user.getName()+ " is: "+quotaValue );
391 14 Aug 07 dominic 165     long currentDiskUsage = user.getDiskUsage(totalQuotaType, Location.PRIMARY);
421 12 Sep 07 dominic 166       //check whether remaining disk space and zip file size are compatible
391 14 Aug 07 dominic 167     long remainingSpace = quotaValue - currentDiskUsage;
441 30 Oct 07 dominic 168     log.info("the remaining space for user: " + user.getName()+ " is: "+remainingSpace );
391 14 Aug 07 dominic 169     if(remainingSpace < zipFileSize && quotaValue!=-1)
391 14 Aug 07 dominic 170     {
391 14 Aug 07 dominic 171       log.error("[disk space: "+remainingSpace+ " ] insufficient for unzipping of file size [" +zipFileSize + "] -- please contact your BASE administrator or remove some files");
478 16 Nov 07 dominic 172       throw new BaseException("[disk space: "+remainingSpace+ " ] insufficient for unzipping of file size [" +zipFileSize + "] -- please contact your BASE administrator or remove some files");
391 14 Aug 07 dominic 173     }
391 14 Aug 07 dominic 174     else if ( remainingSpace > zipFileSize || quotaValue==-1 )
391 14 Aug 07 dominic 175     {
391 14 Aug 07 dominic 176       hasDiskSpace=true;
391 14 Aug 07 dominic 177     }
391 14 Aug 07 dominic 178     return hasDiskSpace;
391 14 Aug 07 dominic 179   }
391 14 Aug 07 dominic 180   
391 14 Aug 07 dominic 181   /**
391 14 Aug 07 dominic 182       Checks the total size of a given zip file (uncompressed)
391 14 Aug 07 dominic 183       @param InputStream fileInputStream -- an input stream from the zip file
391 14 Aug 07 dominic 184       @return long - the total size of the zip file uncompressed, in bytes
391 14 Aug 07 dominic 185    
391 14 Aug 07 dominic 186    */
391 14 Aug 07 dominic 187   public static long getZipfileEntriesSize(InputStream fileInputStream)
391 14 Aug 07 dominic 188   {
391 14 Aug 07 dominic 189     long totalSize =0;
391 14 Aug 07 dominic 190       try
391 14 Aug 07 dominic 191       {
391 14 Aug 07 dominic 192         ZipInputStream zipStream = new ZipInputStream(fileInputStream);     
391 14 Aug 07 dominic 193         ZipEntry entry = zipStream.getNextEntry();
391 14 Aug 07 dominic 194         while(entry!=null)
391 14 Aug 07 dominic 195         {
391 14 Aug 07 dominic 196           long size = entry.getSize();
391 14 Aug 07 dominic 197           totalSize += size;
391 14 Aug 07 dominic 198           entry = zipStream.getNextEntry();
391 14 Aug 07 dominic 199         }
391 14 Aug 07 dominic 200       }
391 14 Aug 07 dominic 201       catch (IOException ioe)
391 14 Aug 07 dominic 202       {
478 16 Nov 07 dominic 203         throw new BaseException("zip file size could not be obtained " + ioe.getMessage());
391 14 Aug 07 dominic 204       }
391 14 Aug 07 dominic 205       return totalSize;
391 14 Aug 07 dominic 206     }
391 14 Aug 07 dominic 207   /**
391 14 Aug 07 dominic 208      create a sub-directory to contain the unzip files
391 14 Aug 07 dominic 209       @param zipFile, the zip file to unpack
391 14 Aug 07 dominic 210       @param user, currently logged-in user
478 16 Nov 07 dominic 211       @param
391 14 Aug 07 dominic 212     
391 14 Aug 07 dominic 213    */
478 16 Nov 07 dominic 214   public void createSubDirectory(File zipFile, User user, String dirName)
478 16 Nov 07 dominic 215   {
478 16 Nov 07 dominic 216     DbControl dc=null;
478 16 Nov 07 dominic 217     try
478 16 Nov 07 dominic 218     {
478 16 Nov 07 dominic 219       dc = sc.newDbControl();
478 16 Nov 07 dominic 220       //get the parent directory
478 16 Nov 07 dominic 221       Directory zipFileDir = zipFile.getDirectory();
478 16 Nov 07 dominic 222       log.info("zipFile is located in dir " + zipFile.getPath());
478 16 Nov 07 dominic 223       Directory d = Directory.getById(dc, zipFileDir.getId());
478 16 Nov 07 dominic 224       //String timeStamp = getTime("ddMMyy_HHmmss"); // can be added to the time directory name
478 16 Nov 07 dominic 225       Directory subDir = d.newSubDirectory();
478 16 Nov 07 dominic 226       subDir.setName(dirName);
478 16 Nov 07 dominic 227         subDir.setDescription("Unzippped directory created at "+new Date());
478 16 Nov 07 dominic 228       if (subDir.isInDatabase())
478 16 Nov 07 dominic 229       {
478 16 Nov 07 dominic 230         throw new ItemAlreadyExistsException("The Directory ["+ subDir.getPath().toString()+ "] already exists");
478 16 Nov 07 dominic 231       }
478 16 Nov 07 dominic 232       else if (!subDir.isInDatabase())
478 16 Nov 07 dominic 233       {
478 16 Nov 07 dominic 234         dc.saveItem(subDir);
478 16 Nov 07 dominic 235       }
478 16 Nov 07 dominic 236       dc.commit();
478 16 Nov 07 dominic 237         setUnzippedFilesDirectory(subDir);
478 16 Nov 07 dominic 238     }
478 16 Nov 07 dominic 239     catch (Throwable ex)
478 16 Nov 07 dominic 240     {
478 16 Nov 07 dominic 241       log.error("--Create subdirectory FAILED", ex);
478 16 Nov 07 dominic 242     }
478 16 Nov 07 dominic 243     finally
478 16 Nov 07 dominic 244     {
478 16 Nov 07 dominic 245       if (dc!=null) dc.close();
478 16 Nov 07 dominic 246     }
478 16 Nov 07 dominic 247             
478 16 Nov 07 dominic 248    }
478 16 Nov 07 dominic 249
478 16 Nov 07 dominic 250   /**
478 16 Nov 07 dominic 251      create a sub-directory to contain the unzip files
478 16 Nov 07 dominic 252       @param zipFile, the zip file to unpack
478 16 Nov 07 dominic 253       @param user, currently logged-in user
478 16 Nov 07 dominic 254       @param
478 16 Nov 07 dominic 255     
478 16 Nov 07 dominic 256    */
391 14 Aug 07 dominic 257   public void createSubDirectory(File zipFile, User user)
391 14 Aug 07 dominic 258   {
391 14 Aug 07 dominic 259     DbControl dc=null;
391 14 Aug 07 dominic 260     try
391 14 Aug 07 dominic 261     {
391 14 Aug 07 dominic 262       dc = sc.newDbControl();
391 14 Aug 07 dominic 263       //get the parent directory
391 14 Aug 07 dominic 264       Directory zipFileDir = zipFile.getDirectory();
441 30 Oct 07 dominic 265       log.info("zipFile is located in dir " + zipFile.getPath());
391 14 Aug 07 dominic 266       Directory d = Directory.getById(dc, zipFileDir.getId());
391 14 Aug 07 dominic 267       Directory subDir = d.newSubDirectory();
478 16 Nov 07 dominic 268       String fileName = zipFile.getName();
478 16 Nov 07 dominic 269         String fileNameNoExt = fileName.substring(0, fileName.indexOf("."));
478 16 Nov 07 dominic 270         subDir.setName(fileNameNoExt);
478 16 Nov 07 dominic 271         subDir.setDescription("Unzippped directory created at "+new Date());
441 30 Oct 07 dominic 272       if (subDir.isInDatabase())
441 30 Oct 07 dominic 273       {
478 16 Nov 07 dominic 274         throw new ItemAlreadyExistsException("The Directory ["+ subDir.getPath().toString()+ "] already exists");
441 30 Oct 07 dominic 275       }
441 30 Oct 07 dominic 276       else if (!subDir.isInDatabase())
441 30 Oct 07 dominic 277       {
478 16 Nov 07 dominic 278         dc.saveItem(subDir);
441 30 Oct 07 dominic 279       }
441 30 Oct 07 dominic 280       dc.commit();
391 14 Aug 07 dominic 281         setUnzippedFilesDirectory(subDir);
391 14 Aug 07 dominic 282     }
391 14 Aug 07 dominic 283     catch (Throwable ex)
391 14 Aug 07 dominic 284     {
441 30 Oct 07 dominic 285       log.error("--Create subdirectory FAILED", ex);
478 16 Nov 07 dominic 286       //throw new BaseException();
391 14 Aug 07 dominic 287     }
391 14 Aug 07 dominic 288     finally
391 14 Aug 07 dominic 289     {
391 14 Aug 07 dominic 290       if (dc!=null) dc.close();
391 14 Aug 07 dominic 291     }
391 14 Aug 07 dominic 292             
391 14 Aug 07 dominic 293    }
391 14 Aug 07 dominic 294
391 14 Aug 07 dominic 295   void setUnzippedFilesDirectory(Directory unzippedFilesDirectory) 
391 14 Aug 07 dominic 296   {
391 14 Aug 07 dominic 297     this.unzippedFilesDirectory = unzippedFilesDirectory;
391 14 Aug 07 dominic 298   }
391 14 Aug 07 dominic 299
391 14 Aug 07 dominic 300   public Directory getUnzippedFilesDirectory() 
391 14 Aug 07 dominic 301   {
391 14 Aug 07 dominic 302     return unzippedFilesDirectory;
391 14 Aug 07 dominic 303   }
478 16 Nov 07 dominic 304   
478 16 Nov 07 dominic 305   private String getTime(String pattern)
478 16 Nov 07 dominic 306   {
478 16 Nov 07 dominic 307     SimpleDateFormat formatter;
478 16 Nov 07 dominic 308     Locale currentLocale = Locale.getDefault();
478 16 Nov 07 dominic 309     formatter = new SimpleDateFormat(pattern, currentLocale);
478 16 Nov 07 dominic 310     String timeStamp = formatter.format(new Date());
478 16 Nov 07 dominic 311     return timeStamp;
478 16 Nov 07 dominic 312   }
391 14 Aug 07 dominic 313 }