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

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