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

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