aoqi@0: /* aoqi@0: * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. Oracle designates this aoqi@0: * particular file as subject to the "Classpath" exception as provided aoqi@0: * by Oracle in the LICENSE file that accompanied this code. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: */ aoqi@0: aoqi@0: package com.sun.xml.internal.org.jvnet.staxex; aoqi@0: aoqi@0: import javax.activation.DataHandler; aoqi@0: import javax.activation.DataSource; aoqi@0: import java.io.BufferedInputStream; aoqi@0: import java.io.Closeable; aoqi@0: import java.io.File; aoqi@0: import java.io.IOException; aoqi@0: import java.io.InputStream; aoqi@0: import java.net.URL; aoqi@0: aoqi@0: /** aoqi@0: * {@link DataHandler} extended to offer better buffer management aoqi@0: * in a streaming environment. aoqi@0: * aoqi@0: *

aoqi@0: * {@link DataHandler} is used commonly as a data format across aoqi@0: * multiple systems (such as JAXB/WS.) Unfortunately, {@link DataHandler} aoqi@0: * has the semantics of "read as many times as you want", so this makes aoqi@0: * it difficult for involving parties to handle a BLOB in a streaming fashion. aoqi@0: * aoqi@0: *

aoqi@0: * {@link StreamingDataHandler} solves this problem by offering methods aoqi@0: * that enable faster bulk "consume once" read operation. aoqi@0: * aoqi@0: * @author Jitendra Kotamraju aoqi@0: */ aoqi@0: public abstract class StreamingDataHandler extends DataHandler implements Closeable { aoqi@0: aoqi@0: public StreamingDataHandler(Object o, String s) { aoqi@0: super(o, s); aoqi@0: } aoqi@0: aoqi@0: public StreamingDataHandler(URL url) { aoqi@0: super(url); aoqi@0: } aoqi@0: aoqi@0: public StreamingDataHandler(DataSource dataSource) { aoqi@0: super(dataSource); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Works like {@link #getInputStream()} except that this method aoqi@0: * can be invoked only once. aoqi@0: * aoqi@0: *

aoqi@0: * This is used as a signal from the caller that there will aoqi@0: * be no further {@link #getInputStream()} invocation nor aoqi@0: * {@link #readOnce()} invocation on this object (which would aoqi@0: * result in {@link IOException}.) aoqi@0: * aoqi@0: *

aoqi@0: * When {@link DataHandler} is backed by a streaming BLOB aoqi@0: * (such as an attachment in a web service read from the network), aoqi@0: * this allows the callee to avoid unnecessary buffering. aoqi@0: * aoqi@0: *

aoqi@0: * Note that it is legal to call {@link #getInputStream()} aoqi@0: * multiple times and then call {@link #readOnce()} afterward. aoqi@0: * Streams created such a way can be read in any order — aoqi@0: * there's no requirement that streams created earlier must be read aoqi@0: * first. aoqi@0: * aoqi@0: * @return aoqi@0: * always non-null. Represents the content of this BLOB. aoqi@0: * The returned stream is generally not buffered, so for aoqi@0: * better performance read in a big batch or wrap this into aoqi@0: * {@link BufferedInputStream}. aoqi@0: * @throws IOException aoqi@0: * if any i/o error aoqi@0: */ aoqi@0: public abstract InputStream readOnce() throws IOException; aoqi@0: aoqi@0: /** aoqi@0: * Obtains the BLOB into a specified file. aoqi@0: * aoqi@0: *

aoqi@0: * Semantically, this method is roughly equivalent to the following aoqi@0: * code, except that the actual implementation is likely to be a lot faster. aoqi@0: * aoqi@0: *

aoqi@0:      * InputStream i = getInputStream();
aoqi@0:      * OutputStream o = new FileOutputStream(dst);
aoqi@0:      * int ch;
aoqi@0:      * while((ch=i.read())!=-1)  o.write(ch);
aoqi@0:      * i.close();
aoqi@0:      * o.close();
aoqi@0:      * 
aoqi@0: * aoqi@0: *

aoqi@0: * The main motivation behind this method is that often aoqi@0: * {@link DataHandler} that reads data from a streaming source aoqi@0: * will use a temporary file as a data store to hold data aoqi@0: * (think of commons-fileupload.) In such case this method aoqi@0: * can be as fast as calling {@link File#renameTo(File)}. aoqi@0: * aoqi@0: *

aoqi@0: * This method shouldn't be called when there are any aoqi@0: * open streams. aoqi@0: * aoqi@0: *

aoqi@0: * After this method is invoked, {@link #readOnce()} and aoqi@0: * {@link #getInputStream()} will simply open the destination aoqi@0: * file you've specified as an argument. So if you further aoqi@0: * move the file or delete this file, those methods will aoqi@0: * behave in undefined fashion. For a simliar reason, aoqi@0: * calling this method multiple times will cause aoqi@0: * undefined behavior. aoqi@0: */ aoqi@0: public abstract void moveTo(File dst) throws IOException; aoqi@0: aoqi@0: /** aoqi@0: * Releases any resources associated with this DataHandler. aoqi@0: * (such as an attachment in a web service read from a temp aoqi@0: * file will be deleted.) After calling this method, it is aoqi@0: * illegal to call any other methods. aoqi@0: */ aoqi@0: public abstract void close() throws IOException; aoqi@0: aoqi@0: }