package org.jboss.seam.ui; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.ByteBuffer; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; import java.nio.channels.WritableByteChannel; import javax.faces.context.FacesContext; import org.jboss.seam.core.Manager; import org.jboss.seam.document.DocumentData; import org.jboss.seam.document.DocumentStore; import org.jboss.seam.document.DocumentData.DocumentType; import org.jboss.seam.navigation.Pages; import org.jboss.seam.ui.component.UIResource; public class DocumentStoreUtils { private static final int BUFFER_SIZE = 32768; public static String addResourceToDataStore(FacesContext ctx, UIResource resource) { String baseName = Pages.getCurrentBaseName(); String viewId = Pages.getViewId(ctx); DocumentStore store = DocumentStore.instance(); String id = store.newId(); DocumentType type = new DocumentType("", resource.getContentType()); DocumentData documentData = new DownloadableDocumentData(baseName, type, resource.getData()); documentData.setFilename(resource.getFileName()); documentData.setDisposition(resource.getDisposition()); String url = store.preferredUrlForContent(resource.getFileName(), type.getExtension(), id); url = Manager.instance().encodeConversationId(url, viewId); store.saveData(id, documentData); return url; } static class DownloadableDocumentData extends DocumentData { private Object data; public DownloadableDocumentData(String baseName, DocumentType type, Object data) { super(baseName, type); this.data = data; } @Override public void writeDataToStream(OutputStream os) throws IOException { if (data instanceof byte[]) { os.write((byte[]) data); } else if (data instanceof File) { writeStream(os, new FileInputStream((File) data)); } else if (data instanceof InputStream) { writeStream(os, (InputStream) data); } } private void writeStream(OutputStream os, InputStream is) throws IOException { ReadableByteChannel in = Channels.newChannel(is); WritableByteChannel out = Channels.newChannel(os); try { copyChannel(in, out); } finally { try { in.close(); } catch (IOException e) { // eat it } try { out.close(); } catch (IOException e) { // eat it } } } private void copyChannel(ReadableByteChannel in, WritableByteChannel out) throws IOException { ByteBuffer buffer = ByteBuffer.allocateDirect(BUFFER_SIZE); while (in.read(buffer) != -1 || buffer.position() > 0) { buffer.flip(); out.write(buffer); buffer.compact(); } } } }