StreamPumper.java

biz/hammurapi/util/StreamPumper.java

Violations

Inspector Message Severity Location
Java Inspector 048 Copyrights information should be present in each file. 1
Java Inspector 049 Use a Collection instead of arrays Object[] 2 82:32
Java Inspector 089 Undocumented parameter sink 2 54:5
Java Inspector 089 Undocumented parameter closeStreams 2 54:5
Java Inspector 089 Undocumented method 2 63:5
Java Inspector 089 Undocumented method 2 69:5
Java Inspector 016 Sun coding standards - class modifiers should be in order (public protected private abstract static final strictfp) 3 40:5
Java Inspector 051 It is good practice to call in any case super() in a constructor. 3 54:5
Java Inspector 054 Discourage usage of instance variables like a, j by enforcing minimal variable name length (3). 3 41:5
Java Inspector 054 Discourage usage of instance variables like a, j by enforcing minimal variable name length (3). 3 42:5

Source code

1/*
2 * hgcommons 9
3 * Hammurapi Group Common Library
4 * Copyright (C) 2003 Hammurapi Group
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 * URL: http://www.hammurapi.biz/hammurapi-biz/ef/xmenu/hammurapi-group/products/products/hgcommons/index.html
21 * e-Mail: support@hammurapi.biz
22 */
23
24package biz.hammurapi.util;
25
26import java.io.IOException;
27import java.io.InputStream;
28import java.io.OutputStream;
29import java.util.ArrayList;
30import java.util.List;
31
32/**
33 *
34 * Copies all data from an input stream to an output stream.
35 * @author Pavel Vlasov
36 * @version $Revision: 1.3 $
37 */
38public class StreamPumper implements Runnable {
39
40 private final static int SIZE = 1024;
41 private InputStream is;
42 private OutputStream os;
43
44 private ExceptionSink sink;
45
46 private boolean closeStreams=false;
47
48 /**
49 * Create a new stream pumper.
50 *
51 * @param is input stream to read data from
52 * @param os output stream to write data to.
53 */
54 public StreamPumper(InputStream is, OutputStream os, ExceptionSink sink, boolean closeStreams) {
55 this.is = is;
56 this.os = os;
57 this.closeStreams=closeStreams;
58 this.sink=sink;
59 }
60
61 private List listeners=new ArrayList();
62
63 public void addListener(StreamPumpListener listener, int tickSize) {
64 synchronized (listeners) {
65 listeners.add(new StreamPumpListenerEntry(listener, tickSize));
66 }
67 }
68
69 public void removeListener(StreamPumpListener listener) {
70 synchronized (listeners) {
71 listeners.remove(listener);
72 }
73 }
74
75 /**
76 * Copies data from the input stream to the output stream.
77 * Creates a copy of listeners collection before pumping.
78 * addListener() and removeListener() have no effect once pumping has started.
79 * Terminates as soon as the input stream is closed or an error occurs.
80 */
81 public void run() {
82 StreamPumpListenerEntry[] listenersArray;
83 synchronized (listeners) {
84 listenersArray= (StreamPumpListenerEntry[]) listeners.toArray(new StreamPumpListenerEntry[listeners.size()]);
85 }
86
87 for (int i=0; i<listenersArray.length; i++) {
88 listenersArray[i].listener.pumpStarted(this);
89 }
90
91 long counter=0;
92 try {
93 final byte[] buf = new byte[SIZE];
94 int length;
95 while ((length = is.read(buf)) != -1) {
96 os.write(buf, 0, length);
97 counter+=length;
98 for (int i=0; i<listenersArray.length; i++) {
99 listenersArray[i].counter+=length;
100 if (listenersArray[i].counter>=listenersArray[i].tickSize) {
101 listenersArray[i].counter=0;
102 listenersArray[i].listener.tick(this, counter);
103 }
104 }
105 }
106 } catch(IOException e) {
107 handleException(e, listenersArray);
108 } finally {
109 for (int i=0; i<listenersArray.length; i++) {
110 listenersArray[i].listener.pumpFinished(this);
111 }
112 if (closeStreams) {
113 try {
114 is.close();
115 } catch (IOException ie) {
116 handleException(ie, listenersArray);
117 }
118
119 try {
120 os.close();
121 } catch (IOException ie) {
122 handleException(ie, listenersArray);
123 }
124 }
125 }
126 }
127
128 /**
129 * @param e
130 * @param listenersArray
131 */
132 private void handleException(Exception e, StreamPumpListenerEntry[] listenersArray) {
133 for (int i=0; i<listenersArray.length; i++) {
134 listenersArray[i].listener.pumpingError(this, e);
135 }
136
137 if (sink==null) {
138 e.printStackTrace();
139 } else {
140 sink.consume(this, e);
141 }
142 }
143}
144