package gnu.java.net.protocol.jar;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.net.JarURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Locale;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public final class Connection extends JarURLConnection
{
private static Hashtable file_cache = new Hashtable();
private static SimpleDateFormat dateFormat
= new SimpleDateFormat("EEE, dd MMM yyyy hh:mm:ss 'GMT'",
new Locale ("En", "Us", "Unix"));
private JarFile jar_file;
static HashMap connectionCache = new HashMap();
protected Connection(URL url)
throws MalformedURLException
{
super(url);
}
public synchronized void connect() throws IOException
{
if (connected)
return;
if (getUseCaches())
{
jarFileURLConnection =
(URLConnection) connectionCache.get(getJarFileURL());
if (jarFileURLConnection == null)
{
jarFileURLConnection = getJarFileURL().openConnection();
jarFileURLConnection.setUseCaches(true);
jarFileURLConnection.connect();
connectionCache.put(getJarFileURL(), jarFileURLConnection);
}
}
else
{
jarFileURLConnection = getJarFileURL().openConnection();
jarFileURLConnection.connect();
}
connected = true;
}
public InputStream getInputStream() throws IOException
{
if (!connected)
connect();
if (! doInput)
throw new ProtocolException("Can't open InputStream if doInput is false");
if (getEntryName() == null)
{
InputStream in = new BufferedInputStream
(jarFileURLConnection.getInputStream());
return new JarInputStream(in);
}
JarFile jarfile = null;
try
{
jarfile = getJarFile ();
}
catch (IOException x)
{
}
if (jarfile != null)
{
ZipEntry entry = jarfile.getEntry(getEntryName());
if (entry != null)
return jarfile.getInputStream (entry);
}
else
{
JarInputStream zis = new JarInputStream(
jarFileURLConnection.getInputStream ());
for (ZipEntry entry = zis.getNextEntry();
entry != null;
entry = zis.getNextEntry())
{
if (getEntryName().equals(entry.getName()))
{
int size = (int) entry.getSize();
byte[] data = new byte[size];
zis.read (data, 0, size);
return new ByteArrayInputStream (data);
}
}
}
throw new FileNotFoundException("No entry for \"" + getEntryName()
+ "\" in \""
+ getJarFileURL()
+ "\"");
}
public synchronized JarFile getJarFile() throws IOException
{
if (!connected)
connect();
if (! doInput)
throw new ProtocolException("Can't open JarFile if doInput is false");
if (jar_file != null)
return jar_file;
URL jarFileURL = getJarFileURL();
if (jarFileURL.getProtocol().equals ("file")
&& jarFileURL.getHost().equals (""))
{
if (getUseCaches())
{
jar_file = (JarFile) file_cache.get (jarFileURL);
if (jar_file == null)
{
jar_file = new JarFile (jarFileURL.getFile());
file_cache.put (jarFileURL, jar_file);
}
}
else
jar_file = new JarFile (jarFileURL.getFile());
}
else
{
URLConnection urlconn = jarFileURL.openConnection();
InputStream is = urlconn.getInputStream();
byte[] buf = new byte[4*1024];
File f = File.createTempFile("cache", "jar");
FileOutputStream fos = new FileOutputStream(f);
int len = 0;
while ((len = is.read(buf)) != -1)
fos.write(buf, 0, len);
fos.close();
jar_file = new JarFile (f, true,
ZipFile.OPEN_READ | ZipFile.OPEN_DELETE);
}
return jar_file;
}
public String getHeaderField(String field)
{
try
{
if (!connected)
connect();
if (field.equals("content-type"))
return guessContentTypeFromName(getJarEntry().getName());
else if (field.equals("content-length"))
return Long.toString(getJarEntry().getSize());
else if (field.equals("last-modified"))
{
synchronized (dateFormat)
{
return dateFormat.format(new Date(getJarEntry().getTime()));
}
}
}
catch (IOException e)
{
}
return null;
}
public int getContentLength()
{
if (!connected)
return -1;
try
{
return (int) getJarEntry().getSize();
}
catch (IOException e)
{
return -1;
}
}
public long getLastModified()
{
if (!connected)
return -1;
try
{
return getJarEntry().getTime();
}
catch (IOException e)
{
return -1;
}
}
}