001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.util.servlet;
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.StringPool;
028    import com.liferay.portal.kernel.util.StringUtil;
029    import com.liferay.portal.kernel.util.Validator;
030    import com.liferay.portal.util.PortalUtil;
031    
032    import java.io.IOException;
033    import java.io.InputStream;
034    import java.io.OutputStream;
035    
036    import javax.portlet.MimeResponse;
037    import javax.portlet.PortletRequest;
038    import javax.portlet.ResourceResponse;
039    
040    import javax.servlet.http.HttpServletRequest;
041    
042    /**
043     * @author Brian Wing Shun Chan
044     */
045    public class PortletResponseUtil {
046    
047            /**
048             * @deprecated
049             */
050            public static void sendFile(
051                            MimeResponse mimeResponse, String fileName, byte[] bytes)
052                    throws IOException {
053    
054                    sendFile(null, mimeResponse, fileName, bytes);
055            }
056    
057            /**
058             * @deprecated
059             */
060            public static void sendFile(
061                            MimeResponse mimeResponse, String fileName, byte[] bytes,
062                            String contentType)
063                    throws IOException {
064    
065                    sendFile(null, mimeResponse, fileName, bytes, contentType);
066            }
067    
068            /**
069             * @deprecated
070             */
071            public static void sendFile(
072                            MimeResponse mimeResponse, String fileName, InputStream is)
073                    throws IOException {
074    
075                    sendFile(null, mimeResponse, fileName, is);
076            }
077    
078            /**
079             * @deprecated
080             */
081            public static void sendFile(
082                            MimeResponse mimeResponse, String fileName, InputStream is,
083                            int contentLength, String contentType)
084                    throws IOException {
085    
086                    sendFile(null, mimeResponse, fileName, is, contentLength, contentType);
087            }
088    
089            /**
090             * @deprecated
091             */
092            public static void sendFile(
093                            MimeResponse mimeResponse, String fileName, InputStream is,
094                            String contentType)
095                    throws IOException {
096    
097                    sendFile(null, mimeResponse, fileName, is, contentType);
098            }
099    
100            public static void sendFile(
101                            PortletRequest portletRequest, MimeResponse mimeResponse,
102                            String fileName, byte[] bytes)
103                    throws IOException {
104    
105                    sendFile(portletRequest, mimeResponse, fileName, bytes, null);
106            }
107    
108            public static void sendFile(
109                            PortletRequest portletRequest, MimeResponse mimeResponse,
110                            String fileName, byte[] bytes, String contentType)
111                    throws IOException {
112    
113                    setHeaders(portletRequest, mimeResponse, fileName, contentType);
114    
115                    write(mimeResponse, bytes);
116            }
117    
118            public static void sendFile(
119                            PortletRequest portletRequest, MimeResponse mimeResponse,
120                            String fileName, InputStream is)
121                    throws IOException {
122    
123                    sendFile(portletRequest, mimeResponse, fileName, is, null);
124            }
125    
126            public static void sendFile(
127                            PortletRequest portletRequest, MimeResponse mimeResponse,
128                            String fileName, InputStream is, int contentLength,
129                            String contentType)
130                    throws IOException {
131    
132                    setHeaders(portletRequest, mimeResponse, fileName, contentType);
133    
134                    write(mimeResponse, is, contentLength);
135            }
136    
137            public static void sendFile(
138                            PortletRequest portletRequest, MimeResponse mimeResponse,
139                            String fileName, InputStream is, String contentType)
140                    throws IOException {
141    
142                    sendFile(portletRequest, mimeResponse, fileName, is, 0, contentType);
143            }
144    
145            public static void write(MimeResponse mimeResponse, byte[] bytes)
146                    throws IOException {
147    
148                    write(mimeResponse, bytes, 0);
149            }
150    
151            public static void write(
152                            MimeResponse mimeResponse, byte[] bytes, int contentLength)
153                    throws IOException {
154    
155                    // LEP-3122
156    
157                    if (!mimeResponse.isCommitted()) {
158    
159                            // LEP-536
160    
161                            if (contentLength == 0) {
162                                    contentLength = bytes.length;
163                            }
164    
165                            if (mimeResponse instanceof ResourceResponse) {
166                                    ResourceResponse resourceResponse =
167                                            (ResourceResponse)mimeResponse;
168    
169                                    resourceResponse.setContentLength(contentLength);
170                            }
171    
172                            OutputStream outputStream = mimeResponse.getPortletOutputStream();
173    
174                            outputStream.write(bytes, 0, contentLength);
175                    }
176            }
177    
178            public static void write(MimeResponse mimeResponse, byte[][] bytesArray)
179                    throws IOException {
180    
181                    // LEP-3122
182    
183                    if (!mimeResponse.isCommitted()) {
184    
185                            // LEP-536
186    
187                            int contentLength = 0;
188    
189                            for (byte[] bytes : bytesArray) {
190                                    contentLength += bytes.length;
191                            }
192    
193                            if (mimeResponse instanceof ResourceResponse) {
194                                    ResourceResponse resourceResponse =
195                                            (ResourceResponse)mimeResponse;
196    
197                                    resourceResponse.setContentLength(contentLength);
198                            }
199    
200                            OutputStream outputStream = mimeResponse.getPortletOutputStream();
201    
202                            for (byte[] bytes : bytesArray) {
203                                    outputStream.write(bytes);
204                            }
205                    }
206            }
207    
208            public static void write(MimeResponse mimeResponse, InputStream is)
209                    throws IOException {
210    
211                    write(mimeResponse, is, 0);
212            }
213    
214            public static void write(
215                            MimeResponse mimeResponse, InputStream is, int contentLength)
216                    throws IOException {
217    
218                    if (mimeResponse.isCommitted()) {
219                            return;
220                    }
221    
222                    if (contentLength > 0) {
223                            if (mimeResponse instanceof ResourceResponse) {
224                                    ResourceResponse resourceResponse =
225                                            (ResourceResponse)mimeResponse;
226    
227                                    resourceResponse.setContentLength(contentLength);
228                            }
229                    }
230    
231                    StreamUtil.transfer(is, mimeResponse.getPortletOutputStream());
232            }
233    
234            public static void write(MimeResponse mimeResponse, String s)
235                    throws IOException {
236    
237                    write(mimeResponse, s.getBytes(StringPool.UTF8));
238            }
239    
240            protected static void setHeaders(
241                    PortletRequest portletRequest, MimeResponse mimeResponse,
242                    String fileName, String contentType) {
243    
244                    if (_log.isDebugEnabled()) {
245                            _log.debug("Sending file of type " + contentType);
246                    }
247    
248                    // LEP-2201
249    
250                    if (Validator.isNotNull(contentType)) {
251                            mimeResponse.setContentType(contentType);
252                    }
253    
254                    mimeResponse.setProperty(
255                            HttpHeaders.CACHE_CONTROL, HttpHeaders.CACHE_CONTROL_PUBLIC_VALUE);
256                    mimeResponse.setProperty(
257                            HttpHeaders.PRAGMA, HttpHeaders.PRAGMA_PUBLIC_VALUE);
258    
259                    if (Validator.isNotNull(fileName)) {
260                            String contentDisposition =
261                                    "attachment; filename=\"" + fileName + "\"";
262    
263                            // If necessary for non-ASCII characters, encode based on RFC 2184.
264                            // However, not all browsers support RFC 2184. See LEP-3127.
265    
266                            boolean ascii = true;
267    
268                            for (int i = 0; i < fileName.length(); i++) {
269                                    if (!Validator.isAscii(fileName.charAt(i))) {
270                                            ascii = false;
271    
272                                            break;
273                                    }
274                            }
275    
276                            try {
277                                    if (!ascii) {
278                                            String encodedFileName = HttpUtil.encodeURL(fileName, true);
279    
280                                            HttpServletRequest request =
281                                                    PortalUtil.getHttpServletRequest(portletRequest);
282    
283                                            if (BrowserSnifferUtil.isIe(request)) {
284                                                    contentDisposition =
285                                                            "attachment; filename=\"" + encodedFileName + "\"";
286                                            }
287                                            else {
288                                                    contentDisposition =
289                                                            "attachment; filename*=UTF-8''" + encodedFileName;
290                                            }
291                                    }
292                            }
293                            catch (Exception e) {
294                                    if (_log.isWarnEnabled()) {
295                                            _log.warn(e);
296                                    }
297                            }
298    
299                            String extension = GetterUtil.getString(
300                                    FileUtil.getExtension(fileName)).toLowerCase();
301    
302                            String[] mimeTypesContentDispositionInline = null;
303    
304                            try {
305                                    mimeTypesContentDispositionInline = PropsUtil.getArray(
306                                            "mime.types.content.disposition.inline");
307                            }
308                            catch (Exception e) {
309                                    mimeTypesContentDispositionInline = new String[0];
310                            }
311    
312                            if (ArrayUtil.contains(
313                                            mimeTypesContentDispositionInline, extension)) {
314    
315                                    contentDisposition = StringUtil.replace(
316                                            contentDisposition, "attachment; ", "inline; ");
317                            }
318    
319                            mimeResponse.setProperty(
320                                    HttpHeaders.CONTENT_DISPOSITION, contentDisposition);
321                    }
322            }
323    
324            private static Log _log = LogFactoryUtil.getLog(PortletResponseUtil.class);
325    
326    }