001
014
015 package com.liferay.portal.kernel.portlet;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.kernel.servlet.BrowserSnifferUtil;
020 import com.liferay.portal.kernel.servlet.HttpHeaders;
021 import com.liferay.portal.kernel.util.ArrayUtil;
022 import com.liferay.portal.kernel.util.FileUtil;
023 import com.liferay.portal.kernel.util.GetterUtil;
024 import com.liferay.portal.kernel.util.HttpUtil;
025 import com.liferay.portal.kernel.util.PropsUtil;
026 import com.liferay.portal.kernel.util.StreamUtil;
027 import com.liferay.portal.kernel.util.StringBundler;
028 import com.liferay.portal.kernel.util.StringPool;
029 import com.liferay.portal.kernel.util.StringUtil;
030 import com.liferay.portal.kernel.util.Validator;
031 import com.liferay.portal.util.PortalUtil;
032
033 import java.io.File;
034 import java.io.FileInputStream;
035 import java.io.IOException;
036 import java.io.InputStream;
037 import java.io.OutputStream;
038
039 import java.nio.channels.Channels;
040 import java.nio.channels.FileChannel;
041
042 import javax.portlet.MimeResponse;
043 import javax.portlet.PortletRequest;
044 import javax.portlet.ResourceResponse;
045
046 import javax.servlet.http.HttpServletRequest;
047
048
051 public class PortletResponseUtil {
052
053
056 public static void sendFile(
057 MimeResponse mimeResponse, String fileName, byte[] bytes)
058 throws IOException {
059
060 sendFile(null, mimeResponse, fileName, bytes);
061 }
062
063
066 public static void sendFile(
067 MimeResponse mimeResponse, String fileName, byte[] bytes,
068 String contentType)
069 throws IOException {
070
071 sendFile(null, mimeResponse, fileName, bytes, contentType);
072 }
073
074
077 public static void sendFile(
078 MimeResponse mimeResponse, String fileName, InputStream is)
079 throws IOException {
080
081 sendFile(null, mimeResponse, fileName, is);
082 }
083
084
087 public static void sendFile(
088 MimeResponse mimeResponse, String fileName, InputStream is,
089 int contentLength, String contentType)
090 throws IOException {
091
092 sendFile(null, mimeResponse, fileName, is, contentLength, contentType);
093 }
094
095
098 public static void sendFile(
099 MimeResponse mimeResponse, String fileName, InputStream is,
100 String contentType)
101 throws IOException {
102
103 sendFile(null, mimeResponse, fileName, is, contentType);
104 }
105
106 public static void sendFile(
107 PortletRequest portletRequest, MimeResponse mimeResponse,
108 String fileName, byte[] bytes)
109 throws IOException {
110
111 sendFile(portletRequest, mimeResponse, fileName, bytes, null);
112 }
113
114 public static void sendFile(
115 PortletRequest portletRequest, MimeResponse mimeResponse,
116 String fileName, byte[] bytes, String contentType)
117 throws IOException {
118
119 sendFile(
120 portletRequest, mimeResponse, fileName, bytes, contentType, null);
121 }
122
123 public static void sendFile(
124 PortletRequest portletRequest, MimeResponse mimeResponse,
125 String fileName, byte[] bytes, String contentType,
126 String contentDispositionType)
127 throws IOException {
128
129 setHeaders(
130 portletRequest, mimeResponse, fileName, contentType,
131 contentDispositionType);
132
133 write(mimeResponse, bytes);
134 }
135
136 public static void sendFile(
137 PortletRequest portletRequest, MimeResponse mimeResponse,
138 String fileName, InputStream is)
139 throws IOException {
140
141 sendFile(portletRequest, mimeResponse, fileName, is, null);
142 }
143
144 public static void sendFile(
145 PortletRequest portletRequest, MimeResponse mimeResponse,
146 String fileName, InputStream is, int contentLength,
147 String contentType)
148 throws IOException {
149
150 sendFile(
151 portletRequest, mimeResponse, fileName, is, 0, contentType, null);
152 }
153
154 public static void sendFile(
155 PortletRequest portletRequest, MimeResponse mimeResponse,
156 String fileName, InputStream is, int contentLength,
157 String contentType, String contentDispositionType)
158 throws IOException {
159
160 setHeaders(
161 portletRequest, mimeResponse, fileName, contentType,
162 contentDispositionType);
163
164 write(mimeResponse, is, contentLength);
165 }
166
167 public static void sendFile(
168 PortletRequest portletRequest, MimeResponse mimeResponse,
169 String fileName, InputStream is, String contentType)
170 throws IOException {
171
172 sendFile(portletRequest, mimeResponse, fileName, is, 0, contentType);
173 }
174
175 public static void write(MimeResponse mimeResponse, byte[] bytes)
176 throws IOException {
177
178 write(mimeResponse, bytes, 0, 0);
179 }
180
181 public static void write(
182 MimeResponse mimeResponse, byte[] bytes, int offset,
183 int contentLength)
184 throws IOException {
185
186
187
188 if (!mimeResponse.isCommitted()) {
189
190
191
192 if (contentLength == 0) {
193 contentLength = bytes.length;
194 }
195
196 if (mimeResponse instanceof ResourceResponse) {
197 ResourceResponse resourceResponse =
198 (ResourceResponse)mimeResponse;
199
200 resourceResponse.setContentLength(contentLength);
201 }
202
203 OutputStream outputStream = mimeResponse.getPortletOutputStream();
204
205 outputStream.write(bytes, offset, contentLength);
206 }
207 }
208
209 public static void write(MimeResponse mimeResponse, byte[][] bytesArray)
210 throws IOException {
211
212
213
214 if (mimeResponse.isCommitted()) {
215 return;
216 }
217
218
219
220 int contentLength = 0;
221
222 for (byte[] bytes : bytesArray) {
223 contentLength += bytes.length;
224 }
225
226 if (mimeResponse instanceof ResourceResponse) {
227 ResourceResponse resourceResponse = (ResourceResponse)mimeResponse;
228
229 resourceResponse.setContentLength(contentLength);
230 }
231
232 OutputStream outputStream = mimeResponse.getPortletOutputStream();
233
234 for (byte[] bytes : bytesArray) {
235 outputStream.write(bytes);
236 }
237 }
238
239 public static void write(MimeResponse mimeResponse, File file)
240 throws IOException {
241
242 FileInputStream fileInputStream = new FileInputStream(file);
243
244 FileChannel fileChannel = fileInputStream.getChannel();
245
246 try {
247 int contentLength = (int)fileChannel.size();
248
249 if (mimeResponse instanceof ResourceResponse) {
250 ResourceResponse resourceResponse =
251 (ResourceResponse)mimeResponse;
252
253 resourceResponse.setContentLength(contentLength);
254 }
255
256 fileChannel.transferTo(
257 0, contentLength,
258 Channels.newChannel(mimeResponse.getPortletOutputStream()));
259 }
260 finally {
261 fileChannel.close();
262 }
263 }
264
265 public static void write(MimeResponse mimeResponse, InputStream is)
266 throws IOException {
267
268 write(mimeResponse, is, 0);
269 }
270
271 public static void write(
272 MimeResponse mimeResponse, InputStream is, int contentLength)
273 throws IOException {
274
275 if (mimeResponse.isCommitted()) {
276 return;
277 }
278
279 if (contentLength > 0) {
280 if (mimeResponse instanceof ResourceResponse) {
281 ResourceResponse resourceResponse =
282 (ResourceResponse)mimeResponse;
283
284 resourceResponse.setContentLength(contentLength);
285 }
286 }
287
288 StreamUtil.transfer(is, mimeResponse.getPortletOutputStream());
289 }
290
291 public static void write(MimeResponse mimeResponse, String s)
292 throws IOException {
293
294 write(mimeResponse, s.getBytes(StringPool.UTF8));
295 }
296
297 protected static void setHeaders(
298 PortletRequest portletRequest, MimeResponse mimeResponse,
299 String fileName, String contentType, String contentDispositionType) {
300
301 if (_log.isDebugEnabled()) {
302 _log.debug("Sending file of type " + contentType);
303 }
304
305
306
307 if (Validator.isNotNull(contentType)) {
308 mimeResponse.setContentType(contentType);
309 }
310
311 mimeResponse.setProperty(
312 HttpHeaders.CACHE_CONTROL, HttpHeaders.CACHE_CONTROL_PRIVATE_VALUE);
313
314 if (Validator.isNull(fileName)) {
315 return;
316 }
317
318 String contentDispositionFileName = "filename=\"" + fileName + "\"";
319
320
321
322
323 boolean ascii = true;
324
325 for (int i = 0; i < fileName.length(); i++) {
326 if (!Validator.isAscii(fileName.charAt(i))) {
327 ascii = false;
328
329 break;
330 }
331 }
332
333 try {
334 if (!ascii) {
335 String encodedFileName = HttpUtil.encodeURL(fileName, true);
336
337 HttpServletRequest request = PortalUtil.getHttpServletRequest(
338 portletRequest);
339
340 if (BrowserSnifferUtil.isIe(request)) {
341 contentDispositionFileName =
342 "filename=\"" + encodedFileName + "\"";
343 }
344 else {
345 contentDispositionFileName =
346 "filename*=UTF-8''" + encodedFileName;
347 }
348 }
349 }
350 catch (Exception e) {
351 if (_log.isWarnEnabled()) {
352 _log.warn(e);
353 }
354 }
355
356 if (Validator.isNull(contentDispositionType)) {
357 String extension = GetterUtil.getString(
358 FileUtil.getExtension(fileName));
359
360 extension = StringUtil.toLowerCase(extension);
361
362 String[] mimeTypesContentDispositionInline = null;
363
364 try {
365 mimeTypesContentDispositionInline = PropsUtil.getArray(
366 "mime.types.content.disposition.inline");
367 }
368 catch (Exception e) {
369 mimeTypesContentDispositionInline = new String[0];
370 }
371
372 if (ArrayUtil.contains(
373 mimeTypesContentDispositionInline, extension)) {
374
375 contentDispositionType = HttpHeaders.CONTENT_DISPOSITION_INLINE;
376 }
377 else {
378 contentDispositionType =
379 HttpHeaders.CONTENT_DISPOSITION_ATTACHMENT;
380 }
381 }
382
383 StringBundler sb = new StringBundler(4);
384
385 sb.append(contentDispositionType);
386 sb.append(StringPool.SEMICOLON);
387 sb.append(StringPool.SPACE);
388 sb.append(contentDispositionFileName);
389
390 mimeResponse.setProperty(
391 HttpHeaders.CONTENT_DISPOSITION, sb.toString());
392 }
393
394 private static Log _log = LogFactoryUtil.getLog(PortletResponseUtil.class);
395
396 }