Thu, 31 Aug 2017 15:18:52 +0800
merge
1 /*
2 * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package com.sun.xml.internal.org.jvnet.staxex;
28 import javax.activation.DataHandler;
29 import javax.activation.DataSource;
30 import java.io.BufferedInputStream;
31 import java.io.Closeable;
32 import java.io.File;
33 import java.io.IOException;
34 import java.io.InputStream;
35 import java.net.URL;
37 /**
38 * {@link DataHandler} extended to offer better buffer management
39 * in a streaming environment.
40 *
41 * <p>
42 * {@link DataHandler} is used commonly as a data format across
43 * multiple systems (such as JAXB/WS.) Unfortunately, {@link DataHandler}
44 * has the semantics of "read as many times as you want", so this makes
45 * it difficult for involving parties to handle a BLOB in a streaming fashion.
46 *
47 * <p>
48 * {@link StreamingDataHandler} solves this problem by offering methods
49 * that enable faster bulk "consume once" read operation.
50 *
51 * @author Jitendra Kotamraju
52 */
53 public abstract class StreamingDataHandler extends DataHandler implements Closeable {
55 public StreamingDataHandler(Object o, String s) {
56 super(o, s);
57 }
59 public StreamingDataHandler(URL url) {
60 super(url);
61 }
63 public StreamingDataHandler(DataSource dataSource) {
64 super(dataSource);
65 }
67 /**
68 * Works like {@link #getInputStream()} except that this method
69 * can be invoked only once.
70 *
71 * <p>
72 * This is used as a signal from the caller that there will
73 * be no further {@link #getInputStream()} invocation nor
74 * {@link #readOnce()} invocation on this object (which would
75 * result in {@link IOException}.)
76 *
77 * <p>
78 * When {@link DataHandler} is backed by a streaming BLOB
79 * (such as an attachment in a web service read from the network),
80 * this allows the callee to avoid unnecessary buffering.
81 *
82 * <p>
83 * Note that it is legal to call {@link #getInputStream()}
84 * multiple times and then call {@link #readOnce()} afterward.
85 * Streams created such a way can be read in any order —
86 * there's no requirement that streams created earlier must be read
87 * first.
88 *
89 * @return
90 * always non-null. Represents the content of this BLOB.
91 * The returned stream is generally not buffered, so for
92 * better performance read in a big batch or wrap this into
93 * {@link BufferedInputStream}.
94 * @throws IOException
95 * if any i/o error
96 */
97 public abstract InputStream readOnce() throws IOException;
99 /**
100 * Obtains the BLOB into a specified file.
101 *
102 * <p>
103 * Semantically, this method is roughly equivalent to the following
104 * code, except that the actual implementation is likely to be a lot faster.
105 *
106 * <pre>
107 * InputStream i = getInputStream();
108 * OutputStream o = new FileOutputStream(dst);
109 * int ch;
110 * while((ch=i.read())!=-1) o.write(ch);
111 * i.close();
112 * o.close();
113 * </pre>
114 *
115 * <p>
116 * The main motivation behind this method is that often
117 * {@link DataHandler} that reads data from a streaming source
118 * will use a temporary file as a data store to hold data
119 * (think of commons-fileupload.) In such case this method
120 * can be as fast as calling {@link File#renameTo(File)}.
121 *
122 * <p>
123 * This method shouldn't be called when there are any
124 * open streams.
125 *
126 * <p>
127 * After this method is invoked, {@link #readOnce()} and
128 * {@link #getInputStream()} will simply open the destination
129 * file you've specified as an argument. So if you further
130 * move the file or delete this file, those methods will
131 * behave in undefined fashion. For a simliar reason,
132 * calling this method multiple times will cause
133 * undefined behavior.
134 */
135 public abstract void moveTo(File dst) throws IOException;
137 /**
138 * Releases any resources associated with this DataHandler.
139 * (such as an attachment in a web service read from a temp
140 * file will be deleted.) After calling this method, it is
141 * illegal to call any other methods.
142 */
143 public abstract void close() throws IOException;
145 }