I have what I expect would be a pretty common task, but I can't find any straight-forward answers anywhere, so any help here would be greatly appreciated.
Short version: How can I make an IResourceStream from an SmbFile's inputStream?
Long version: In my Wicket app, I have users fill out a questionnaire and then download a file once they've completed it properly. The file is on a Samba server, so I'm using SmbFile, which is working perfectly, so no issue with that. I'm using the AJAXDownload that was written by Sven Meier, Ernesto Barreiro, and Jordi Deu-Pons because I need my button to have Ajax functionality to check that the form was filled out properly, and then start the download. When I was starting out with the file on my computer, I could simply use
final AJAXDownload download = new AJAXDownload()
{
@Override
protected IResourceStream getResourceStream()
{
IResourceStream resStream = new FileResourceStream(file);
return resStream;
}
@Override
protected String getFileName() {
return fileName;
}
};
form.add(download);
But now that I'm using SmbFile through JCIFS, I can't just make a new FileResourceStream. I found that I can use java.io.File.createTempFile to make a tempfile from the smbFile's inputStream, and then use the temp file like this:
protected IResourceStream getResourceStream()
{
java.io.File tempFile = null;
try {
tempFile = File.createTempFile(smbFile.getName(), smbFile.getContentType());
} catch (IOException e1) {
e1.printStackTrace();
}
try {
Files.writeTo(tempFile, smbFile.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
IResourceStream resStream = new FileResourceStream(tempFile);
return resStream;
}
And this works fine for small files, but I will also have some rather large files and since it makes a temp copy of the file before sending it down, it takes a very long time and is just poor design. Any ideas of how I can get my smbFile downloaded in the wicket app?
Edit: Thanks to Joop Eggen, and the book 'Enjoying Web Development with Wicket' by Kent Ka lok Tong, I have the solution below in case anyone else ends up in a similar situation:
final AJAXDownload download = new AJAXDownload()
{
@Override
protected IResourceStream getResourceStream()
{
IResourceStream resStream = new AbstractResourceStream() {
InputStream inStream;
public InputStream getInputStream() throws ResourceStreamNotFoundException{
try {
inStream = smbFile.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
return inStream;
}
public void close() throws IOException {
inStream.close();
}
public String getContentType() {
return smbFile.getContentType();
}
};
return resStream;
}
@Override
protected String getFileName() {
return smbFileName;
}
};
form.add(download);
You should derive a SmbResourceStream that extends AbstractResourceStream, and implement providing an InputStream for reading by overriding getInputStream
and close
. You already have smbFile.getInputStream()
.