1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   *
13   */
14  
15  package com.liferay.portal.upload;
16  
17  import com.liferay.portal.kernel.log.Log;
18  import com.liferay.portal.kernel.log.LogFactoryUtil;
19  
20  import java.io.IOException;
21  import java.io.InputStream;
22  import java.io.OutputStream;
23  
24  import javax.portlet.ActionRequest;
25  import javax.portlet.PortletSession;
26  
27  /**
28   * <a href="ProgressInputStream.java.html"><b><i>View Source</i></b></a>
29   *
30   * @author Jorge Ferrer
31   */
32  public class ProgressInputStream extends InputStream {
33  
34      public ProgressInputStream(
35          ActionRequest actionRequest, InputStream is, long totalSize,
36          String progressId) {
37  
38          _portletSession = actionRequest.getPortletSession();
39          _is = is;
40          _totalSize = totalSize;
41          _progressId = progressId;
42  
43          initProgress();
44      }
45  
46      public int available() throws IOException {
47          return _is.available();
48      }
49  
50      public void clearProgress() {
51          _portletSession.removeAttribute(_getPercentAttributeName());
52      }
53  
54      public void close() throws IOException {
55          _is.close();
56      }
57  
58      public long getTotalRead() {
59          return _totalRead;
60      }
61  
62      public void initProgress() {
63          _portletSession.setAttribute(
64              _getPercentAttributeName(), new Integer(0),
65              PortletSession.APPLICATION_SCOPE);
66      }
67  
68      public void mark(int readlimit) {
69          _is.mark(readlimit);
70      }
71  
72      public boolean markSupported() {
73          return _is.markSupported();
74      }
75  
76      public int read() throws IOException {
77          return _is.read();
78      }
79  
80      public int read(byte[] b) throws IOException {
81          return read(b, 0, b.length);
82      }
83  
84      public int read(byte[] b, int off, int len) throws IOException {
85          int bytesRead = super.read(b, off, len);
86  
87          _updateProgress(bytesRead);
88  
89          return bytesRead;
90      }
91  
92      public void readAll(OutputStream os) throws IOException {
93          byte[] buffer = new byte[_DEFAULT_INITIAL_BUFFER_SIZE];
94  
95          int len = 0;
96  
97          while ((len = read(buffer)) > 0) {
98              os.write(buffer, 0, len);
99          }
100 
101         os.close();
102     }
103 
104     public void reset() throws IOException {
105         _is.reset();
106     }
107 
108     public long skip(long n) throws IOException {
109         long result = _is.skip(n);
110 
111         _updateProgress(result);
112 
113         return result;
114     }
115 
116     private String _getPercentAttributeName() {
117         return LiferayFileUpload.PERCENT + _progressId;
118     }
119 
120     private void _updateProgress(long bytesRead) {
121         if (bytesRead > 0) {
122             _totalRead += bytesRead;
123         }
124         else {
125             _totalRead = _totalSize;
126         }
127 
128         int percent = (int) ((_totalRead * 100) / _totalSize);
129 
130         if (_log.isDebugEnabled()) {
131             _log.debug(bytesRead + "/" + _totalRead + "=" + percent);
132         }
133 
134         Integer curPercent = (Integer)_portletSession.getAttribute(
135             _getPercentAttributeName(), PortletSession.APPLICATION_SCOPE);
136 
137         if ((curPercent == null) || (percent - curPercent.intValue() >= 1)) {
138             _portletSession.setAttribute(
139                 _getPercentAttributeName(), new Integer(percent),
140                 PortletSession.APPLICATION_SCOPE);
141         }
142     }
143 
144     private static final int _DEFAULT_INITIAL_BUFFER_SIZE = 4 * 1024;
145 
146     private static Log _log = LogFactoryUtil.getLog(ProgressInputStream.class);
147 
148     private PortletSession _portletSession;
149     private InputStream _is;
150     private long _totalRead;
151     private long _totalSize;
152     private String _progressId;
153 
154 }