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

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

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

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

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

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

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

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

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

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

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