/** * * Copyright * 2009-2015 Jayway Products AB * 2016-2017 Föreningen Sambruk * * Licensed under AGPL, Version 3.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.gnu.org/licenses/agpl.txt * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package se.streamsource.streamflow.web.infrastructure.attachment; import java.io.BufferedOutputStream; import java.io.IOException; import java.io.OutputStream; import java.nio.ByteBuffer; import org.qi4j.api.io.Input; import org.qi4j.api.io.Output; import org.qi4j.api.io.Receiver; import org.qi4j.api.io.Sender; import se.streamsource.streamflow.util.Visitor; /** * An Input that allows a Visitor to write to an OutputStream. The stream is a BufferedOutputStream, so when enough * data has been gathered it will send this in chunks of the given size to the Output it is transferred to. The Visitor does not have to call * close() on the OutputStream, but should ensure that any wrapper streams or writers are flushed so that all data is sent. * <p/> * TODO Replace this with Inputs.output() in Qi4j v2.0 later. * */ public class OutputstreamInput implements Input<ByteBuffer, IOException> { public OutputstreamInput(Visitor<OutputStream, IOException> outputVisitor, int bufferSize) { this.outputVisitor = outputVisitor; this.bufferSize = bufferSize; } private Visitor<OutputStream, IOException> outputVisitor; private int bufferSize; public <ReceiverThrowableType extends Throwable> void transferTo(Output<? super ByteBuffer, ReceiverThrowableType> output) throws IOException, ReceiverThrowableType { output.receiveFrom(new Sender<ByteBuffer, IOException>() { public <ReceiverThrowableType extends Throwable> void sendTo(final Receiver<? super ByteBuffer, ReceiverThrowableType> receiver) throws ReceiverThrowableType, IOException { OutputStream out = new BufferedOutputStream(new OutputStream() { @Override public void write(int b) throws IOException { // Ignore } @Override public void write(byte[] b, int off, int len) throws IOException { try { ByteBuffer byteBuffer = ByteBuffer.wrap(b, 0, len); receiver.receive(byteBuffer); } catch (Throwable ex) { throw new IOException(ex); } } }, bufferSize); try { outputVisitor.visit(out); } catch (IOException ex) { throw (ReceiverThrowableType) ex.getCause(); } finally { out.close(); } } }); } }