blob: 8d5e69bd62a3568c903dbc60e8a3efedab78e0ae [file] [log] [blame]
//
// ========================================================================
// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.osgi.boot.warurl.internal;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.security.Permission;
import java.util.List;
import java.util.Map;
import java.util.jar.JarFile;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.resource.Resource;
/**
* Facade for a URLConnection that will read a jar and substitute its
* manifest by the manifest provided here.
* <p>
* Use Piped streams to avoid having to create temporary files.
* </p>
*/
public class WarURLConnection extends URLConnection
{
/**
* Use PipedOuputStream and PipedInputStream to do the transformation without making
* a new temporary file ust to replace the manifest.
* @param newmanifest The new manifest
* @param rawIn The file input stream or equivalent. not the jar input stream.
*/
public static InputStream substitueManifest(final Manifest newmanifest,
final InputStream rawIn) throws IOException
{
final PipedOutputStream pOut = new PipedOutputStream();
PipedInputStream pIn = new PipedInputStream(pOut);
Runnable run = new Runnable()
{
public void run()
{
JarInputStream jin = null;
JarOutputStream dest = null;
try
{
jin = new JarInputStream(rawIn, false);
dest = new JarOutputStream(pOut, newmanifest);
ZipEntry next = jin.getNextEntry();
while (next != null)
{
if (next.getName().equalsIgnoreCase(JarFile.MANIFEST_NAME))
{
continue;
}
dest.putNextEntry(next);
if (next.getSize() > 0)
{
IO.copy(jin,dest,next.getSize());
}
next = jin.getNextJarEntry();
}
}
catch (IOException ioe) {
ioe.printStackTrace();
}
finally
{
if (dest != null) IO.close(dest);
if (jin != null) IO.close(jin);
IO.close(pOut);
}
}
};
Thread th = new Thread(run);
th.start();
return pIn;
}
private Manifest _mf;
private URLConnection _conn;
/**
* @param url The file url (for example)
* @param mf The manifest to use as a replacement to the jar file inside
* the file url.
*/
public WarURLConnection(URL url, Manifest mf) throws IOException
{
super(url);
_conn = url.openConnection();
_conn.setDefaultUseCaches(Resource.getDefaultUseCaches());
_mf = mf;
}
@Override
public void connect() throws IOException
{
_conn.connect();
}
public InputStream getInputStream() throws IOException
{
return substitueManifest(_mf, _conn.getInputStream());
}
public void addRequestProperty(String key, String value)
{
_conn.addRequestProperty(key,value);
}
public boolean equals(Object obj)
{
return _conn.equals(obj);
}
public boolean getAllowUserInteraction()
{
return _conn.getAllowUserInteraction();
}
public int getConnectTimeout()
{
return _conn.getConnectTimeout();
}
public Object getContent() throws IOException
{
return _conn.getContent();
}
public Object getContent(Class[] classes) throws IOException
{
return _conn.getContent(classes);
}
public String getContentEncoding()
{
return _conn.getContentEncoding();
}
public int getContentLength()
{
return _conn.getContentLength();
}
public String getContentType()
{
return _conn.getContentType();
}
public long getDate()
{
return _conn.getDate();
}
public boolean getDefaultUseCaches()
{
return _conn.getDefaultUseCaches();
}
public boolean getDoInput()
{
return _conn.getDoInput();
}
public boolean getDoOutput()
{
return _conn.getDoOutput();
}
public long getExpiration()
{
return _conn.getExpiration();
}
public String getHeaderField(int n)
{
return _conn.getHeaderField(n);
}
public String getHeaderField(String name)
{
return _conn.getHeaderField(name);
}
public long getHeaderFieldDate(String name, long Default)
{
return _conn.getHeaderFieldDate(name,Default);
}
public int getHeaderFieldInt(String name, int Default)
{
return _conn.getHeaderFieldInt(name,Default);
}
public String getHeaderFieldKey(int n)
{
return _conn.getHeaderFieldKey(n);
}
public Map<String, List<String>> getHeaderFields()
{
return _conn.getHeaderFields();
}
public long getIfModifiedSince()
{
return _conn.getIfModifiedSince();
}
public long getLastModified()
{
return _conn.getLastModified();
}
public OutputStream getOutputStream() throws IOException
{
return _conn.getOutputStream();
}
public Permission getPermission() throws IOException
{
return _conn.getPermission();
}
public int getReadTimeout()
{
return _conn.getReadTimeout();
}
public Map<String, List<String>> getRequestProperties()
{
return _conn.getRequestProperties();
}
public String getRequestProperty(String key)
{
return _conn.getRequestProperty(key);
}
public URL getURL()
{
return _conn.getURL();
}
public boolean getUseCaches()
{
return _conn.getUseCaches();
}
public void setAllowUserInteraction(boolean allowuserinteraction)
{
_conn.setAllowUserInteraction(allowuserinteraction);
}
public void setConnectTimeout(int timeout)
{
_conn.setConnectTimeout(timeout);
}
public void setDefaultUseCaches(boolean defaultusecaches)
{
_conn.setDefaultUseCaches(defaultusecaches);
}
public void setDoInput(boolean doinput)
{
_conn.setDoInput(doinput);
}
public void setDoOutput(boolean dooutput)
{
_conn.setDoOutput(dooutput);
}
public void setIfModifiedSince(long ifmodifiedsince)
{
_conn.setIfModifiedSince(ifmodifiedsince);
}
public void setReadTimeout(int timeout)
{
_conn.setReadTimeout(timeout);
}
public void setRequestProperty(String key, String value)
{
_conn.setRequestProperty(key,value);
}
public void setUseCaches(boolean usecaches)
{
_conn.setUseCaches(usecaches);
}
}