supported downloading workspace and artifacts as a single zip file.

git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@2383 71c3de6d-444a-0410-be80-ed276b4c234a
This commit is contained in:
kohsuke committed 2007-03-09 06:57:24 +00:00
1 parent dd79c8857c
commit 9da772fa98
3 files changed
+60 -3

No files matched your search

+42 -3
View File
@@ -27,6 +27,8 @@ import java.io.Serializable;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipOutputStream;
import java.util.zip.ZipEntry;
import java.net.URI;
/**
@@ -144,6 +146,39 @@ public final class FilePath implements Serializable {
return remote;
}
/**
* Creates a zip file from this directory or a file and sends that to the given output stream.
*/
public void createZipArchive(OutputStream os) throws IOException, InterruptedException {
final OutputStream out = (channel!=null)?new RemoteOutputStream(os):os;
act(new FileCallable<Void>() {
private transient byte[] buf;
public Void invoke(File f, VirtualChannel channel) throws IOException {
buf = new byte[8192];
ZipOutputStream zip = new ZipOutputStream(out);
scan(f,zip,"");
zip.close();
return null;
}
private void scan(File f, ZipOutputStream zip, String path) throws IOException {
if(f.isDirectory()) {
for( File child : f.listFiles() )
scan(child,zip,path+f.getName()+'/');
} else {
zip.putNextEntry(new ZipEntry(path+f.getName()));
FileInputStream in = new FileInputStream(f);
int len;
while((len=in.read(buf))>0)
zip.write(buf,0,len);
in.close();
zip.closeEntry();
}
}
});
}
/**
* Code that gets executed on the machine where the {@link FilePath} is local.
* Used to act on {@link FilePath}.
@@ -260,15 +295,19 @@ public final class FilePath implements Serializable {
* This method assumes that the file name is the same between local and remote.
*/
public String getName() {
int len = remote.length()-1;
String r = remote;
if(r.endsWith("\\") || r.endsWith("/"))
r = r.substring(0,r.length()-1);
int len = r.length()-1;
while(len>=0) {
char ch = remote.charAt(len);
char ch = r.charAt(len);
if(ch=='\\' || ch=='/')
break;
len--;
}
return remote.substring(len+1);
return r.substring(len+1);
}
/**
@@ -75,6 +75,13 @@ public final class DirectoryBrowserSupport {
f = f.getParent();
isFingerprint = true;
}
if(f.getParent().getName().equals("*zip*")) {
// the expected syntax is foo/bar/*zip*/bar.zip
// the last 'bar.zip' portion is to causes browses to set a good default file name
rsp.setContentType("application/zip");
f.getParent().getParent().createZipArchive(rsp.getOutputStream());
return;
}
if(f.isDirectory()) {
if(!req.getRequestURL().toString().endsWith("/")) {
@@ -91,6 +98,7 @@ public final class DirectoryBrowserSupport {
req.setAttribute("files", f.act(new ChildPathBuilder()));
req.setAttribute("icon",icon);
req.setAttribute("path",path);
req.setAttribute("dir",f);
req.getView(this,"dir.jelly").forward(req,rsp);
return;
} else {
@@ -39,6 +39,16 @@
</j:if>
</tr>
</j:forEach>
<tr>
<td style="text-align:right;" colspan="3">
<div style="margin-top: 1em;">
<a href="*zip*/${dir.name}.zip">
<img src="${rootURL}/images/16x16/package.gif"/>
(all files in zip)
</a>
</div>
</td>
</tr>
</table>
</div>
</l:main-panel>