src/core/net/sf/basedb/util/zip/TarUtil.java

Code
Comments
Other
Rev Date Author Line
4059 14 Dec 07 nicklas 1 /**
4059 14 Dec 07 nicklas 2   $Id$
4059 14 Dec 07 nicklas 3
4059 14 Dec 07 nicklas 4   Copyright (C) Authors contributing to this file.
4059 14 Dec 07 nicklas 5
4059 14 Dec 07 nicklas 6   This file is part of BASE - BioArray Software Environment.
4059 14 Dec 07 nicklas 7   Available at http://base.thep.lu.se/
4059 14 Dec 07 nicklas 8
4059 14 Dec 07 nicklas 9   BASE is free software; you can redistribute it and/or
4059 14 Dec 07 nicklas 10   modify it under the terms of the GNU General Public License
4479 05 Sep 08 jari 11   as published by the Free Software Foundation; either version 3
4059 14 Dec 07 nicklas 12   of the License, or (at your option) any later version.
4059 14 Dec 07 nicklas 13
4059 14 Dec 07 nicklas 14   BASE is distributed in the hope that it will be useful,
4059 14 Dec 07 nicklas 15   but WITHOUT ANY WARRANTY; without even the implied warranty of
4059 14 Dec 07 nicklas 16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
4059 14 Dec 07 nicklas 17   GNU General Public License for more details.
4059 14 Dec 07 nicklas 18
4059 14 Dec 07 nicklas 19   You should have received a copy of the GNU General Public License
4515 11 Sep 08 jari 20   along with BASE. If not, see <http://www.gnu.org/licenses/>.
4059 14 Dec 07 nicklas 21 */
4059 14 Dec 07 nicklas 22 package net.sf.basedb.util.zip;
4059 14 Dec 07 nicklas 23
4059 14 Dec 07 nicklas 24 import java.io.ByteArrayOutputStream;
4059 14 Dec 07 nicklas 25 import java.io.IOException;
4059 14 Dec 07 nicklas 26
4059 14 Dec 07 nicklas 27 import net.sf.basedb.util.FileUtil;
4059 14 Dec 07 nicklas 28
4059 14 Dec 07 nicklas 29 import com.ice.tar.TarEntry;
4059 14 Dec 07 nicklas 30 import com.ice.tar.TarInputStream;
4059 14 Dec 07 nicklas 31 import com.ice.tar.TarOutputStream;
4059 14 Dec 07 nicklas 32
4059 14 Dec 07 nicklas 33 /**
4059 14 Dec 07 nicklas 34   Contains utility functions for TAR archives. Most importantly functions
4059 14 Dec 07 nicklas 35   for handling entries with too long file names to fit in the header section.
4059 14 Dec 07 nicklas 36
4059 14 Dec 07 nicklas 37   @author nicklas
4059 14 Dec 07 nicklas 38   @version 2.5.1
4059 14 Dec 07 nicklas 39   @base.modified $Date$
4059 14 Dec 07 nicklas 40 */
4059 14 Dec 07 nicklas 41 public class TarUtil
4059 14 Dec 07 nicklas 42 {
4059 14 Dec 07 nicklas 43   /**
4059 14 Dec 07 nicklas 44     TAR has a limit of 100 characters in file names. Names that are longer
4059 14 Dec 07 nicklas 45     store the actual filename in an entry with this name just before
4059 14 Dec 07 nicklas 46     the real file (which usually has a truncated name entry).
4059 14 Dec 07 nicklas 47   */
4059 14 Dec 07 nicklas 48   public static final String LONG_LINK_NAME = "././@LongLink";
4059 14 Dec 07 nicklas 49   
4059 14 Dec 07 nicklas 50   /**
4059 14 Dec 07 nicklas 51     Maximum file name length.
4059 14 Dec 07 nicklas 52     @see #LONG_LINK_NAME
4059 14 Dec 07 nicklas 53   */
4059 14 Dec 07 nicklas 54   public static final int MAX_NAME_LENGTH = 100;
4059 14 Dec 07 nicklas 55
4059 14 Dec 07 nicklas 56   /**
4059 14 Dec 07 nicklas 57     The TAR header flag that must be set for @LongLink entries.
4059 14 Dec 07 nicklas 58   */
4059 14 Dec 07 nicklas 59   private static byte LONG_LINK_FLAG = (byte)'L';
4059 14 Dec 07 nicklas 60
4059 14 Dec 07 nicklas 61   /**
4059 14 Dec 07 nicklas 62     Get the next entry from a TAR input stream. This method has support for
4059 14 Dec 07 nicklas 63     long filenames. After calling this method the actual file data can be
4059 14 Dec 07 nicklas 64     read from the stream.
4059 14 Dec 07 nicklas 65     @param tarStream The TAR stream to read from
4059 14 Dec 07 nicklas 66     @return The next entry or null if the end of stream has been reached
4059 14 Dec 07 nicklas 67   */
4059 14 Dec 07 nicklas 68   public static final TarEntry getNextEntry(TarInputStream tarStream)
4059 14 Dec 07 nicklas 69     throws IOException
4059 14 Dec 07 nicklas 70   {
4059 14 Dec 07 nicklas 71     TarEntry entry = tarStream.getNextEntry();
4059 14 Dec 07 nicklas 72     if (entry != null)
4059 14 Dec 07 nicklas 73     {
4059 14 Dec 07 nicklas 74       if (LONG_LINK_NAME.equals(entry.getName()))
4059 14 Dec 07 nicklas 75       {
4059 14 Dec 07 nicklas 76         ByteArrayOutputStream out = new ByteArrayOutputStream((int)entry.getSize());
4059 14 Dec 07 nicklas 77         FileUtil.copy(tarStream, out);
4059 14 Dec 07 nicklas 78         byte[] temp = out.toByteArray();
4059 14 Dec 07 nicklas 79         int usedBytes = temp[temp.length-1] == 0x00 ? temp.length-1 : temp.length;
4059 14 Dec 07 nicklas 80         String filename = new String(temp, 0, usedBytes);
4059 14 Dec 07 nicklas 81         entry = tarStream.getNextEntry();
4059 14 Dec 07 nicklas 82         entry.setName(filename);
4059 14 Dec 07 nicklas 83       }
4059 14 Dec 07 nicklas 84     }
4059 14 Dec 07 nicklas 85     return entry;
4059 14 Dec 07 nicklas 86   }
4059 14 Dec 07 nicklas 87   
4059 14 Dec 07 nicklas 88   /**
4059 14 Dec 07 nicklas 89     Put the next entry to a TAR stream. This method has support for 
4059 14 Dec 07 nicklas 90     long filenames and will automatically create all neccesary extra information
4059 14 Dec 07 nicklas 91     inside the TAR stream. After calling this method the actual file data
4059 14 Dec 07 nicklas 92     should be written to the stream.
4059 14 Dec 07 nicklas 93     
4059 14 Dec 07 nicklas 94     @param entry The next entry
4059 14 Dec 07 nicklas 95     @param tarStream The tar stream to write to
4059 14 Dec 07 nicklas 96   */
4059 14 Dec 07 nicklas 97   public static final void putNextEntry(TarEntry entry, TarOutputStream tarStream)
4059 14 Dec 07 nicklas 98     throws IOException
4059 14 Dec 07 nicklas 99   {
4059 14 Dec 07 nicklas 100     String name = entry.getName();
4059 14 Dec 07 nicklas 101     if (name.length() > MAX_NAME_LENGTH)
4059 14 Dec 07 nicklas 102     {
4059 14 Dec 07 nicklas 103       TarEntry longLink = new TarEntry(LONG_LINK_NAME);
4059 14 Dec 07 nicklas 104       if (entry.getModTime() != null) longLink.setModTime(entry.getModTime());
4059 14 Dec 07 nicklas 105       longLink.setSize(name.length()+1);
4059 14 Dec 07 nicklas 106       longLink.getHeader().linkFlag = LONG_LINK_FLAG;
4059 14 Dec 07 nicklas 107       tarStream.putNextEntry(longLink);
4059 14 Dec 07 nicklas 108       tarStream.write(name.getBytes());
4059 14 Dec 07 nicklas 109       tarStream.write(0);
4059 14 Dec 07 nicklas 110       tarStream.closeEntry();
4059 14 Dec 07 nicklas 111       entry.setName(name.substring(0, MAX_NAME_LENGTH));
4059 14 Dec 07 nicklas 112     }
4059 14 Dec 07 nicklas 113     tarStream.putNextEntry(entry);
4059 14 Dec 07 nicklas 114   }
4059 14 Dec 07 nicklas 115   
4059 14 Dec 07 nicklas 116 }