001    /**
002     * Copyright (c) 2000-2013 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.portal.webserver;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.exception.SystemException;
019    import com.liferay.portal.kernel.image.ImageBag;
020    import com.liferay.portal.kernel.image.ImageToolUtil;
021    import com.liferay.portal.kernel.log.Log;
022    import com.liferay.portal.kernel.log.LogFactoryUtil;
023    import com.liferay.portal.kernel.repository.RepositoryException;
024    import com.liferay.portal.kernel.repository.model.FileEntry;
025    import com.liferay.portal.kernel.repository.model.FileVersion;
026    import com.liferay.portal.kernel.repository.model.Folder;
027    import com.liferay.portal.kernel.servlet.HttpHeaders;
028    import com.liferay.portal.kernel.servlet.PortalSessionThreadLocal;
029    import com.liferay.portal.kernel.servlet.Range;
030    import com.liferay.portal.kernel.servlet.ServletResponseUtil;
031    import com.liferay.portal.kernel.template.Template;
032    import com.liferay.portal.kernel.template.TemplateConstants;
033    import com.liferay.portal.kernel.template.TemplateManagerUtil;
034    import com.liferay.portal.kernel.template.TemplateResource;
035    import com.liferay.portal.kernel.template.URLTemplateResource;
036    import com.liferay.portal.kernel.util.CharPool;
037    import com.liferay.portal.kernel.util.ContentTypes;
038    import com.liferay.portal.kernel.util.FastDateFormatFactoryUtil;
039    import com.liferay.portal.kernel.util.FileUtil;
040    import com.liferay.portal.kernel.util.GetterUtil;
041    import com.liferay.portal.kernel.util.HtmlUtil;
042    import com.liferay.portal.kernel.util.HttpUtil;
043    import com.liferay.portal.kernel.util.MimeTypesUtil;
044    import com.liferay.portal.kernel.util.ParamUtil;
045    import com.liferay.portal.kernel.util.ReleaseInfo;
046    import com.liferay.portal.kernel.util.SetUtil;
047    import com.liferay.portal.kernel.util.StringPool;
048    import com.liferay.portal.kernel.util.StringUtil;
049    import com.liferay.portal.kernel.util.UnicodeProperties;
050    import com.liferay.portal.kernel.util.Validator;
051    import com.liferay.portal.kernel.util.Validator_IW;
052    import com.liferay.portal.kernel.webdav.WebDAVUtil;
053    import com.liferay.portal.kernel.workflow.WorkflowConstants;
054    import com.liferay.portal.model.Company;
055    import com.liferay.portal.model.Group;
056    import com.liferay.portal.model.Image;
057    import com.liferay.portal.model.ImageConstants;
058    import com.liferay.portal.model.User;
059    import com.liferay.portal.model.impl.ImageImpl;
060    import com.liferay.portal.portletfilerepository.PortletFileRepositoryUtil;
061    import com.liferay.portal.repository.liferayrepository.model.LiferayFileEntry;
062    import com.liferay.portal.repository.liferayrepository.model.LiferayFileVersion;
063    import com.liferay.portal.security.auth.PrincipalException;
064    import com.liferay.portal.security.auth.PrincipalThreadLocal;
065    import com.liferay.portal.security.permission.PermissionChecker;
066    import com.liferay.portal.security.permission.PermissionCheckerFactoryUtil;
067    import com.liferay.portal.security.permission.PermissionThreadLocal;
068    import com.liferay.portal.service.CompanyLocalServiceUtil;
069    import com.liferay.portal.service.GroupLocalServiceUtil;
070    import com.liferay.portal.service.ImageLocalServiceUtil;
071    import com.liferay.portal.service.ImageServiceUtil;
072    import com.liferay.portal.service.UserLocalServiceUtil;
073    import com.liferay.portal.service.permission.PortletPermissionUtil;
074    import com.liferay.portal.theme.ThemeDisplay;
075    import com.liferay.portal.util.Portal;
076    import com.liferay.portal.util.PortalUtil;
077    import com.liferay.portal.util.PortletKeys;
078    import com.liferay.portal.util.PropsValues;
079    import com.liferay.portal.util.WebKeys;
080    import com.liferay.portlet.documentlibrary.NoSuchFileEntryException;
081    import com.liferay.portlet.documentlibrary.NoSuchFolderException;
082    import com.liferay.portlet.documentlibrary.model.DLFileEntry;
083    import com.liferay.portlet.documentlibrary.model.DLFileShortcut;
084    import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
085    import com.liferay.portlet.documentlibrary.service.DLAppLocalServiceUtil;
086    import com.liferay.portlet.documentlibrary.service.DLAppServiceUtil;
087    import com.liferay.portlet.documentlibrary.service.DLFileEntryServiceUtil;
088    import com.liferay.portlet.documentlibrary.util.AudioProcessorUtil;
089    import com.liferay.portlet.documentlibrary.util.DLUtil;
090    import com.liferay.portlet.documentlibrary.util.DocumentConversionUtil;
091    import com.liferay.portlet.documentlibrary.util.ImageProcessorUtil;
092    import com.liferay.portlet.documentlibrary.util.PDFProcessor;
093    import com.liferay.portlet.documentlibrary.util.PDFProcessorUtil;
094    import com.liferay.portlet.documentlibrary.util.VideoProcessor;
095    import com.liferay.portlet.documentlibrary.util.VideoProcessorUtil;
096    import com.liferay.portlet.trash.util.TrashUtil;
097    
098    import java.awt.image.RenderedImage;
099    
100    import java.io.File;
101    import java.io.FileInputStream;
102    import java.io.IOException;
103    import java.io.InputStream;
104    
105    import java.net.URL;
106    
107    import java.text.Format;
108    
109    import java.util.ArrayList;
110    import java.util.Date;
111    import java.util.List;
112    import java.util.Set;
113    
114    import javax.servlet.ServletConfig;
115    import javax.servlet.ServletException;
116    import javax.servlet.http.HttpServlet;
117    import javax.servlet.http.HttpServletRequest;
118    import javax.servlet.http.HttpServletResponse;
119    import javax.servlet.http.HttpSession;
120    
121    /**
122     * @author Alexander Chow
123     * @author Brian Wing Shun Chan
124     */
125    public class WebServerServlet extends HttpServlet {
126    
127            public static final String PATH_PORTLET_FILE_ENTRY = "portlet_file_entry";
128    
129            /**
130             * @see com.liferay.portal.servlet.filters.virtualhost.VirtualHostFilter
131             */
132            public static boolean hasFiles(HttpServletRequest request) {
133                    try {
134    
135                            // Do not use permission checking since this may be called from
136                            // other contexts that are also managing the principal
137    
138                            User user = _getUser(request);
139    
140                            String path = HttpUtil.fixPath(request.getPathInfo());
141    
142                            String[] pathArray = StringUtil.split(path, CharPool.SLASH);
143    
144                            if (pathArray.length == 0) {
145                                    return true;
146                            }
147                            else if (Validator.isNumber(pathArray[0])) {
148                                    _checkFileEntry(pathArray);
149                            }
150                            else if (PATH_PORTLET_FILE_ENTRY.equals(pathArray[0])) {
151                                    FileEntry fileEntry = getPortletFileEntry(request, pathArray);
152    
153                                    if (fileEntry != null) {
154                                            return true;
155                                    }
156                            }
157                            else {
158                                    long groupId = _getGroupId(user.getCompanyId(), pathArray[0]);
159                                    long folderId = DLFolderConstants.DEFAULT_PARENT_FOLDER_ID;
160    
161                                    for (int i = 1; i < pathArray.length; i++) {
162                                            try {
163                                                    Folder folder = DLAppLocalServiceUtil.getFolder(
164                                                            groupId, folderId, pathArray[i]);
165    
166                                                    folderId = folder.getFolderId();
167                                            }
168                                            catch (NoSuchFolderException nsfe) {
169                                                    if (i != (pathArray.length - 1)) {
170                                                            return false;
171                                                    }
172    
173                                                    pathArray = new String[] {
174                                                            String.valueOf(groupId), String.valueOf(folderId),
175                                                            pathArray[i]
176                                                    };
177    
178                                                    _checkFileEntry(pathArray);
179                                            }
180                                    }
181                            }
182                    }
183                    catch (Exception e) {
184                            return false;
185                    }
186    
187                    return true;
188            }
189    
190            @Override
191            public void init(ServletConfig servletConfig) throws ServletException {
192                    super.init(servletConfig);
193    
194                    _lastModified = GetterUtil.getBoolean(
195                            servletConfig.getInitParameter("last_modified"), true);
196    
197                    Class<?> clazz = getClass();
198    
199                    ClassLoader classLoader = clazz.getClassLoader();
200    
201                    String templateId =
202                            "com/liferay/portal/webserver/dependencies/template.ftl";
203    
204                    URL url = classLoader.getResource(templateId);
205    
206                    _templateResource = new URLTemplateResource(templateId, url);
207            }
208    
209            @Override
210            public void service(
211                            HttpServletRequest request, HttpServletResponse response)
212                    throws IOException, ServletException {
213    
214                    User user = null;
215    
216                    try {
217                            user = _getUser(request);
218    
219                            PrincipalThreadLocal.setName(user.getUserId());
220                            PrincipalThreadLocal.setPassword(
221                                    PortalUtil.getUserPassword(request));
222    
223                            PermissionChecker permissionChecker =
224                                    PermissionCheckerFactoryUtil.create(user);
225    
226                            PermissionThreadLocal.setPermissionChecker(permissionChecker);
227    
228                            if (_lastModified) {
229                                    long lastModified = getLastModified(request);
230    
231                                    if (lastModified > 0) {
232                                            long ifModifiedSince = request.getDateHeader(
233                                                    HttpHeaders.IF_MODIFIED_SINCE);
234    
235                                            if ((ifModifiedSince > 0) &&
236                                                    (ifModifiedSince == lastModified)) {
237    
238                                                    response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
239    
240                                                    return;
241                                            }
242                                    }
243    
244                                    if (lastModified > 0) {
245                                            response.setDateHeader(
246                                                    HttpHeaders.LAST_MODIFIED, lastModified);
247                                    }
248                            }
249    
250                            String path = HttpUtil.fixPath(request.getPathInfo());
251                            String[] pathArray = StringUtil.split(path, CharPool.SLASH);
252    
253                            if (pathArray.length == 0) {
254                                    sendGroups(
255                                            response, user,
256                                            request.getServletPath() + StringPool.SLASH + path);
257                            }
258                            else {
259                                    if (Validator.isNumber(pathArray[0])) {
260                                            sendFile(request, response, user, pathArray);
261                                    }
262                                    else if (PATH_PORTLET_FILE_ENTRY.equals(pathArray[0])) {
263                                            sendPortletFileEntry(request, response, pathArray);
264                                    }
265                                    else {
266                                            if (isLegacyImageGalleryImageId(request, response)) {
267                                                    return;
268                                            }
269    
270                                            Image image = getImage(request, true);
271    
272                                            if (image != null) {
273                                                    writeImage(image, request, response);
274                                            }
275                                            else {
276                                                    sendDocumentLibrary(
277                                                            request, response, user,
278                                                            request.getServletPath() + StringPool.SLASH + path,
279                                                            pathArray);
280                                            }
281                                    }
282                            }
283                    }
284                    catch (NoSuchFileEntryException nsfee) {
285                            PortalUtil.sendError(
286                                    HttpServletResponse.SC_NOT_FOUND, nsfee, request, response);
287                    }
288                    catch (NoSuchFolderException nsfe) {
289                            PortalUtil.sendError(
290                                    HttpServletResponse.SC_NOT_FOUND, nsfe, request, response);
291                    }
292                    catch (PrincipalException pe) {
293                            processPrincipalException(pe, user, request, response);
294                    }
295                    catch (Exception e) {
296                            PortalUtil.sendError(e, request, response);
297                    }
298            }
299    
300            protected static FileEntry getPortletFileEntry(
301                            HttpServletRequest request, String[] pathArray)
302                    throws Exception {
303    
304                    long groupId = GetterUtil.getLong(pathArray[1]);
305                    String uuid = pathArray[3];
306    
307                    FileEntry fileEntry = PortletFileRepositoryUtil.getPortletFileEntry(
308                            uuid, groupId);
309    
310                    DLFileEntry dlFileEntry = (DLFileEntry)fileEntry.getModel();
311    
312                    int status = ParamUtil.getInteger(
313                            request, "status", WorkflowConstants.STATUS_APPROVED);
314    
315                    if ((status != WorkflowConstants.STATUS_IN_TRASH) &&
316                            (dlFileEntry.isInTrash() || dlFileEntry.isInTrashContainer())) {
317    
318                            return null;
319                    }
320    
321                    return fileEntry;
322            }
323    
324            protected Image convertFileEntry(boolean smallImage, FileEntry fileEntry)
325                    throws PortalException, SystemException {
326    
327                    try {
328                            Image image = new ImageImpl();
329    
330                            image.setModifiedDate(fileEntry.getModifiedDate());
331    
332                            InputStream is = null;
333    
334                            if (smallImage) {
335                                    is = ImageProcessorUtil.getThumbnailAsStream(
336                                            fileEntry.getFileVersion(), 0);
337                            }
338                            else {
339                                    is = fileEntry.getContentStream();
340                            }
341    
342                            byte[] bytes = FileUtil.getBytes(is);
343    
344                            image.setTextObj(bytes);
345    
346                            image.setType(fileEntry.getExtension());
347    
348                            return image;
349                    }
350                    catch (PortalException pe) {
351                            throw pe;
352                    }
353                    catch (SystemException se) {
354                            throw se;
355                    }
356                    catch (Exception e) {
357                            throw new SystemException(e);
358                    }
359            }
360    
361            protected Image getDefaultImage(HttpServletRequest request, long imageId) {
362                    String path = GetterUtil.getString(request.getPathInfo());
363    
364                    if (path.startsWith("/company_logo") ||
365                            path.startsWith("/layout_set_logo") || path.startsWith("/logo")) {
366    
367                            return ImageToolUtil.getDefaultCompanyLogo();
368                    }
369                    else if (path.startsWith("/organization_logo")) {
370                            return ImageToolUtil.getDefaultOrganizationLogo();
371                    }
372                    else if (path.startsWith("/user_female_portrait")) {
373                            return ImageToolUtil.getDefaultUserFemalePortrait();
374                    }
375                    else if (path.startsWith("/user_male_portrait")) {
376                            return ImageToolUtil.getDefaultUserMalePortrait();
377                    }
378                    else if (path.startsWith("/user_portrait")) {
379                            return ImageToolUtil.getDefaultUserMalePortrait();
380                    }
381                    else {
382                            return null;
383                    }
384            }
385    
386            protected FileEntry getFileEntry(String[] pathArray) throws Exception {
387                    if (pathArray.length == 1) {
388                            long dlFileShortcutId = GetterUtil.getLong(pathArray[0]);
389    
390                            DLFileShortcut dlFileShortcut = DLAppServiceUtil.getFileShortcut(
391                                    dlFileShortcutId);
392    
393                            return DLAppServiceUtil.getFileEntry(
394                                    dlFileShortcut.getToFileEntryId());
395                    }
396                    else if (pathArray.length == 2) {
397                            long groupId = GetterUtil.getLong(pathArray[0]);
398    
399                            return DLAppServiceUtil.getFileEntryByUuidAndGroupId(
400                                    pathArray[1], groupId);
401                    }
402                    else if (pathArray.length == 3) {
403                            long groupId = GetterUtil.getLong(pathArray[0]);
404                            long folderId = GetterUtil.getLong(pathArray[1]);
405                            String fileName = HttpUtil.decodeURL(pathArray[2]);
406    
407                            if (fileName.contains(StringPool.QUESTION)) {
408                                    fileName = fileName.substring(
409                                            0, fileName.indexOf(StringPool.QUESTION));
410                            }
411    
412                            return DLAppServiceUtil.getFileEntry(groupId, folderId, fileName);
413                    }
414                    else {
415                            long groupId = GetterUtil.getLong(pathArray[0]);
416    
417                            String uuid = pathArray[3];
418    
419                            return DLAppServiceUtil.getFileEntryByUuidAndGroupId(uuid, groupId);
420                    }
421            }
422    
423            protected Image getImage(HttpServletRequest request, boolean getDefault)
424                    throws PortalException, SystemException {
425    
426                    Image image = null;
427    
428                    long imageId = getImageId(request);
429    
430                    if (imageId > 0) {
431                            image = ImageServiceUtil.getImage(imageId);
432    
433                            String path = GetterUtil.getString(request.getPathInfo());
434    
435                            if (path.startsWith("/user_female_portrait") ||
436                                    path.startsWith("/user_male_portrait") ||
437                                    path.startsWith("/user_portrait")) {
438    
439                                    image = getUserPortraitImageResized(image, imageId);
440                            }
441                    }
442                    else {
443                            String uuid = ParamUtil.getString(request, "uuid");
444                            long groupId = ParamUtil.getLong(request, "groupId");
445                            boolean igSmallImage = ParamUtil.getBoolean(
446                                    request, "igSmallImage");
447    
448                            if (Validator.isNotNull(uuid) && (groupId > 0)) {
449                                    try {
450                                            FileEntry fileEntry =
451                                                    DLAppServiceUtil.getFileEntryByUuidAndGroupId(
452                                                            uuid, groupId);
453    
454                                            image = convertFileEntry(igSmallImage, fileEntry);
455                                    }
456                                    catch (Exception e) {
457                                    }
458                            }
459                    }
460    
461                    if (getDefault) {
462                            if (image == null) {
463                                    if (_log.isWarnEnabled()) {
464                                            _log.warn("Get a default image for " + imageId);
465                                    }
466    
467                                    image = getDefaultImage(request, imageId);
468                            }
469                    }
470    
471                    return image;
472            }
473    
474            protected byte[] getImageBytes(HttpServletRequest request, Image image) {
475                    try {
476                            if (!PropsValues.IMAGE_AUTO_SCALE) {
477                                    return image.getTextObj();
478                            }
479    
480                            ImageBag imageBag = null;
481    
482                            if (image.getImageId() == 0) {
483                                    imageBag = ImageToolUtil.read(image.getTextObj());
484    
485                                    RenderedImage renderedImage = imageBag.getRenderedImage();
486    
487                                    image.setHeight(renderedImage.getHeight());
488                                    image.setWidth(renderedImage.getWidth());
489                            }
490    
491                            int height = ParamUtil.getInteger(
492                                    request, "height", image.getHeight());
493                            int width = ParamUtil.getInteger(
494                                    request, "width", image.getWidth());
495    
496                            if ((height >= image.getHeight()) && (width >= image.getWidth())) {
497                                    return image.getTextObj();
498                            }
499    
500                            if (image.getImageId() != 0) {
501                                    imageBag = ImageToolUtil.read(image.getTextObj());
502                            }
503    
504                            RenderedImage renderedImage = ImageToolUtil.scale(
505                                    imageBag.getRenderedImage(), height, width);
506    
507                            return ImageToolUtil.getBytes(renderedImage, imageBag.getType());
508                    }
509                    catch (Exception e) {
510                            if (_log.isWarnEnabled()) {
511                                    _log.warn("Error scaling image " + image.getImageId(), e);
512                            }
513                    }
514    
515                    return image.getTextObj();
516            }
517    
518            protected long getImageId(HttpServletRequest request) {
519    
520                    // The image id may be passed in as image_id, img_id, or i_id
521    
522                    long imageId = ParamUtil.getLong(request, "image_id");
523    
524                    if (imageId <= 0) {
525                            imageId = ParamUtil.getLong(request, "img_id");
526                    }
527    
528                    if (imageId <= 0) {
529                            imageId = ParamUtil.getLong(request, "i_id");
530                    }
531    
532                    if (imageId <= 0) {
533                            long companyId = ParamUtil.getLong(request, "companyId");
534                            String screenName = ParamUtil.getString(request, "screenName");
535    
536                            try {
537                                    if ((companyId > 0) && Validator.isNotNull(screenName)) {
538                                            User user = UserLocalServiceUtil.getUserByScreenName(
539                                                    companyId, screenName);
540    
541                                            imageId = user.getPortraitId();
542                                    }
543                            }
544                            catch (Exception e) {
545                            }
546                    }
547    
548                    return imageId;
549            }
550    
551            @Override
552            protected long getLastModified(HttpServletRequest request) {
553                    try {
554                            Date modifiedDate = null;
555    
556                            Image image = getImage(request, true);
557    
558                            if (image != null) {
559                                    modifiedDate = image.getModifiedDate();
560                            }
561                            else {
562                                    String path = HttpUtil.fixPath(request.getPathInfo());
563    
564                                    String[] pathArray = StringUtil.split(path, CharPool.SLASH);
565    
566                                    if (pathArray.length == 0) {
567                                            return -1;
568                                    }
569    
570                                    if (pathArray[0].equals("language")) {
571                                            return -1;
572                                    }
573    
574                                    FileEntry fileEntry = null;
575    
576                                    try {
577                                            fileEntry = getFileEntry(pathArray);
578                                    }
579                                    catch (Exception e) {
580                                    }
581    
582                                    if (fileEntry == null) {
583                                            return -1;
584                                    }
585    
586                                    String version = ParamUtil.getString(request, "version");
587    
588                                    if (Validator.isNotNull(version)) {
589                                            FileVersion fileVersion = fileEntry.getFileVersion(version);
590    
591                                            modifiedDate = fileVersion.getModifiedDate();
592                                    }
593                                    else {
594                                            modifiedDate = fileEntry.getModifiedDate();
595                                    }
596                            }
597    
598                            if (modifiedDate == null) {
599                                    modifiedDate = PortalUtil.getUptime();
600                            }
601    
602                            // Round down and remove milliseconds
603    
604                            return (modifiedDate.getTime() / 1000) * 1000;
605                    }
606                    catch (PrincipalException pe) {
607                            if (_log.isWarnEnabled()) {
608                                    _log.warn(pe, pe);
609                            }
610                    }
611                    catch (Exception e) {
612                            _log.error(e, e);
613                    }
614    
615                    return -1;
616            }
617    
618            protected Image getUserPortraitImageResized(Image image, long imageId)
619                    throws PortalException, SystemException {
620    
621                    if (image == null) {
622                            return null;
623                    }
624    
625                    if (((PropsValues.USERS_IMAGE_MAX_HEIGHT > 0) &&
626                             (image.getHeight() > PropsValues.USERS_IMAGE_MAX_HEIGHT)) ||
627                            ((PropsValues.USERS_IMAGE_MAX_WIDTH > 0) &&
628                             (image.getWidth() > PropsValues.USERS_IMAGE_MAX_WIDTH))) {
629    
630                            User user = UserLocalServiceUtil.getUserByPortraitId(imageId);
631    
632                            UserLocalServiceUtil.updatePortrait(
633                                    user.getUserId(), image.getTextObj());
634    
635                            return ImageLocalServiceUtil.getImage(imageId);
636                    }
637    
638                    return image;
639            }
640    
641            protected boolean isLegacyImageGalleryImageId(
642                    HttpServletRequest request, HttpServletResponse response) {
643    
644                    try {
645                            long imageId = getImageId(request);
646    
647                            if (imageId == 0) {
648                                    return false;
649                            }
650    
651                            DLFileEntry dlFileEntry =
652                                    DLFileEntryServiceUtil.fetchFileEntryByImageId(imageId);
653    
654                            if (dlFileEntry == null) {
655                                    return false;
656                            }
657    
658                            ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
659                                    WebKeys.THEME_DISPLAY);
660    
661                            String queryString = StringPool.BLANK;
662    
663                            if (imageId == dlFileEntry.getSmallImageId()) {
664                                    queryString = "&imageThumbnail=1";
665                            }
666                            else if (imageId == dlFileEntry.getCustom1ImageId()) {
667                                    queryString = "&imageThumbnail=2";
668                            }
669                            else if (imageId == dlFileEntry.getCustom2ImageId()) {
670                                    queryString = "&imageThumbnail=3";
671                            }
672    
673                            String url = DLUtil.getPreviewURL(
674                                    new LiferayFileEntry(dlFileEntry),
675                                    new LiferayFileVersion(dlFileEntry.getFileVersion()),
676                                    themeDisplay, queryString);
677    
678                            response.setHeader(HttpHeaders.LOCATION, url);
679                            response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
680    
681                            return true;
682                    }
683                    catch (Exception e) {
684                    }
685    
686                    return false;
687            }
688    
689            protected boolean isSupportsRangeHeader(String contentType) {
690                    return _acceptRangesMimeTypes.contains(contentType);
691            }
692    
693            protected void processPrincipalException(
694                            Throwable t, User user, HttpServletRequest request,
695                            HttpServletResponse response)
696                    throws IOException, ServletException {
697    
698                    if (!user.isDefaultUser()) {
699                            PortalUtil.sendError(
700                                    HttpServletResponse.SC_UNAUTHORIZED, (Exception)t, request,
701                                    response);
702    
703                            return;
704                    }
705    
706                    String redirect =
707                            request.getContextPath() + Portal.PATH_MAIN + "/portal/login";
708    
709                    String currentURL = PortalUtil.getCurrentURL(request);
710    
711                    redirect = HttpUtil.addParameter(redirect, "redirect", currentURL);
712    
713                    response.sendRedirect(redirect);
714            }
715    
716            protected void sendDocumentLibrary(
717                            HttpServletRequest request, HttpServletResponse response, User user,
718                            String path, String[] pathArray)
719                    throws Exception {
720    
721                    long groupId = _getGroupId(user.getCompanyId(), pathArray[0]);
722    
723                    Group group = GroupLocalServiceUtil.getGroup(groupId);
724    
725                    UnicodeProperties typeSettingsProperties =
726                            group.getTypeSettingsProperties();
727    
728                    boolean directoryIndexingEnabled = GetterUtil.getBoolean(
729                            typeSettingsProperties.getProperty("directoryIndexingEnabled"),
730                            PropsValues.WEB_SERVER_SERVLET_DIRECTORY_INDEXING_ENABLED);
731    
732                    if (!directoryIndexingEnabled) {
733                            throw new NoSuchFolderException();
734                    }
735    
736                    long folderId = DLFolderConstants.DEFAULT_PARENT_FOLDER_ID;
737    
738                    for (int i = 1; i < pathArray.length; i++) {
739                            String name = pathArray[i];
740    
741                            try {
742                                    Folder folder = DLAppServiceUtil.getFolder(
743                                            groupId, folderId, name);
744    
745                                    folderId = folder.getFolderId();
746                            }
747                            catch (NoSuchFolderException nsfe) {
748                                    if (i != (pathArray.length - 1)) {
749                                            throw nsfe;
750                                    }
751    
752                                    String title = name;
753    
754                                    sendFile(response, user, groupId, folderId, title);
755    
756                                    return;
757                            }
758                    }
759    
760                    try {
761                            sendFile(response, user, groupId, folderId, "index.html");
762    
763                            return;
764                    }
765                    catch (Exception e) {
766                            if ((e instanceof NoSuchFileEntryException) ||
767                                    (e instanceof PrincipalException)) {
768    
769                                    try {
770                                            sendFile(response, user, groupId, folderId, "index.htm");
771    
772                                            return;
773                                    }
774                                    catch (NoSuchFileEntryException nsfee) {
775                                    }
776                                    catch (PrincipalException pe) {
777                                    }
778                            }
779                            else {
780                                    throw e;
781                            }
782                    }
783    
784                    List<WebServerEntry> webServerEntries = new ArrayList<WebServerEntry>();
785    
786                    webServerEntries.add(new WebServerEntry(path, "../"));
787    
788                    List<Folder> folders = DLAppServiceUtil.getFolders(groupId, folderId);
789    
790                    for (Folder folder : folders) {
791                            WebServerEntry webServerEntry = new WebServerEntry(
792                                    path, folder.getName() + StringPool.SLASH,
793                                    folder.getCreateDate(), folder.getModifiedDate(),
794                                    folder.getDescription(), 0);
795    
796                            webServerEntries.add(webServerEntry);
797                    }
798    
799                    List<FileEntry> fileEntries = DLAppServiceUtil.getFileEntries(
800                            groupId, folderId);
801    
802                    for (FileEntry fileEntry : fileEntries) {
803                            WebServerEntry webServerEntry = new WebServerEntry(
804                                    path, fileEntry.getTitle(), fileEntry.getCreateDate(),
805                                    fileEntry.getModifiedDate(), fileEntry.getDescription(),
806                                    fileEntry.getSize());
807    
808                            webServerEntries.add(webServerEntry);
809                    }
810    
811                    sendHTML(response, path, webServerEntries);
812            }
813    
814            protected void sendFile(
815                            HttpServletRequest request, HttpServletResponse response, User user,
816                            String[] pathArray)
817                    throws Exception {
818    
819                    // Retrieve file details
820    
821                    FileEntry fileEntry = getFileEntry(pathArray);
822    
823                    if (fileEntry == null) {
824                            throw new NoSuchFileEntryException();
825                    }
826    
827                    String version = ParamUtil.getString(request, "version");
828    
829                    if (Validator.isNull(version)) {
830                            if (Validator.isNotNull(fileEntry.getVersion())) {
831                                    version = fileEntry.getVersion();
832                            }
833                    }
834    
835                    String tempFileId = DLUtil.getTempFileId(
836                            fileEntry.getFileEntryId(), version);
837    
838                    if (fileEntry.getModel() instanceof DLFileEntry) {
839                            LiferayFileEntry liferayFileEntry = (LiferayFileEntry)fileEntry;
840    
841                            if (liferayFileEntry.isInTrash() ||
842                                    liferayFileEntry.isInTrashContainer()) {
843    
844                                    int status = ParamUtil.getInteger(
845                                            request, "status", WorkflowConstants.STATUS_APPROVED);
846    
847                                    if (status != WorkflowConstants.STATUS_IN_TRASH) {
848                                            throw new NoSuchFileEntryException();
849                                    }
850    
851                                    PermissionChecker permissionChecker =
852                                            PermissionThreadLocal.getPermissionChecker();
853    
854                                    if (!PortletPermissionUtil.hasControlPanelAccessPermission(
855                                                    permissionChecker, fileEntry.getGroupId(),
856                                                    PortletKeys.TRASH)) {
857    
858                                            throw new PrincipalException();
859                                    }
860                            }
861                    }
862    
863                    FileVersion fileVersion = fileEntry.getFileVersion(version);
864    
865                    if ((ParamUtil.getInteger(request, "height") > 0) ||
866                            (ParamUtil.getInteger(request, "width") > 0)) {
867    
868                            InputStream inputStream = fileVersion.getContentStream(true);
869    
870                            Image image = ImageToolUtil.getImage(inputStream);
871    
872                            writeImage(image, request, response);
873    
874                            return;
875                    }
876    
877                    String fileName = fileVersion.getTitle();
878    
879                    String extension = fileVersion.getExtension();
880    
881                    if (Validator.isNotNull(extension) &&
882                            !fileName.endsWith(StringPool.PERIOD + extension)) {
883    
884                            fileName += StringPool.PERIOD + extension;
885                    }
886    
887                    // Handle requested conversion
888    
889                    boolean converted = false;
890    
891                    String targetExtension = ParamUtil.getString(
892                            request, "targetExtension");
893                    int imageThumbnail = ParamUtil.getInteger(request, "imageThumbnail");
894                    int documentThumbnail = ParamUtil.getInteger(
895                            request, "documentThumbnail");
896                    int previewFileIndex = ParamUtil.getInteger(
897                            request, "previewFileIndex");
898                    boolean audioPreview = ParamUtil.getBoolean(request, "audioPreview");
899                    boolean imagePreview = ParamUtil.getBoolean(request, "imagePreview");
900                    boolean videoPreview = ParamUtil.getBoolean(request, "videoPreview");
901                    int videoThumbnail = ParamUtil.getInteger(request, "videoThumbnail");
902    
903                    InputStream inputStream = null;
904                    long contentLength = 0;
905    
906                    if ((imageThumbnail > 0) && (imageThumbnail <= 3)) {
907                            fileName = FileUtil.stripExtension(fileName).concat(
908                                    StringPool.PERIOD).concat(
909                                            ImageProcessorUtil.getThumbnailType(fileVersion));
910    
911                            int thumbnailIndex = imageThumbnail - 1;
912    
913                            inputStream = ImageProcessorUtil.getThumbnailAsStream(
914                                    fileVersion, thumbnailIndex);
915                            contentLength = ImageProcessorUtil.getThumbnailFileSize(
916                                    fileVersion, thumbnailIndex);
917    
918                            converted = true;
919                    }
920                    else if ((documentThumbnail > 0) && (documentThumbnail <= 3)) {
921                            fileName = FileUtil.stripExtension(fileName).concat(
922                                    StringPool.PERIOD).concat(PDFProcessor.THUMBNAIL_TYPE);
923    
924                            int thumbnailIndex = documentThumbnail - 1;
925    
926                            inputStream = PDFProcessorUtil.getThumbnailAsStream(
927                                    fileVersion, thumbnailIndex);
928                            contentLength = PDFProcessorUtil.getThumbnailFileSize(
929                                    fileVersion, thumbnailIndex);
930    
931                            converted = true;
932                    }
933                    else if (previewFileIndex > 0) {
934                            fileName = FileUtil.stripExtension(fileName).concat(
935                                    StringPool.PERIOD).concat(PDFProcessor.PREVIEW_TYPE);
936                            inputStream = PDFProcessorUtil.getPreviewAsStream(
937                                    fileVersion, previewFileIndex);
938                            contentLength = PDFProcessorUtil.getPreviewFileSize(
939                                    fileVersion, previewFileIndex);
940    
941                            converted = true;
942                    }
943                    else if (audioPreview || videoPreview) {
944                            String type = ParamUtil.getString(request, "type");
945    
946                            fileName = FileUtil.stripExtension(fileName).concat(
947                                    StringPool.PERIOD).concat(type);
948    
949                            if (audioPreview) {
950                                    inputStream = AudioProcessorUtil.getPreviewAsStream(
951                                            fileVersion, type);
952                                    contentLength = AudioProcessorUtil.getPreviewFileSize(
953                                            fileVersion, type);
954                            }
955                            else {
956                                    inputStream = VideoProcessorUtil.getPreviewAsStream(
957                                            fileVersion, type);
958                                    contentLength = VideoProcessorUtil.getPreviewFileSize(
959                                            fileVersion, type);
960                            }
961    
962                            converted = true;
963                    }
964                    else if (imagePreview) {
965                            String type = ImageProcessorUtil.getPreviewType(fileVersion);
966    
967                            fileName = FileUtil.stripExtension(fileName).concat(
968                                    StringPool.PERIOD).concat(type);
969    
970                            inputStream = ImageProcessorUtil.getPreviewAsStream(fileVersion);
971    
972                            contentLength = ImageProcessorUtil.getPreviewFileSize(fileVersion);
973    
974                            converted = true;
975                    }
976                    else if ((videoThumbnail > 0) && (videoThumbnail <= 3)) {
977                            fileName = FileUtil.stripExtension(fileName).concat(
978                                    StringPool.PERIOD).concat(VideoProcessor.THUMBNAIL_TYPE);
979    
980                            int thumbnailIndex = videoThumbnail - 1;
981    
982                            inputStream = VideoProcessorUtil.getThumbnailAsStream(
983                                    fileVersion, thumbnailIndex);
984                            contentLength = VideoProcessorUtil.getThumbnailFileSize(
985                                    fileVersion, thumbnailIndex);
986    
987                            converted = true;
988                    }
989                    else {
990                            inputStream = fileVersion.getContentStream(true);
991                            contentLength = fileVersion.getSize();
992    
993                            if (Validator.isNotNull(targetExtension)) {
994                                    File convertedFile = DocumentConversionUtil.convert(
995                                            tempFileId, inputStream, extension, targetExtension);
996    
997                                    if (convertedFile != null) {
998                                            fileName = FileUtil.stripExtension(fileName).concat(
999                                                    StringPool.PERIOD).concat(targetExtension);
1000                                            inputStream = new FileInputStream(convertedFile);
1001                                            contentLength = convertedFile.length();
1002    
1003                                            converted = true;
1004                                    }
1005                            }
1006                    }
1007    
1008                    // Determine proper content type
1009    
1010                    String contentType = null;
1011    
1012                    if (converted) {
1013                            contentType = MimeTypesUtil.getContentType(fileName);
1014                    }
1015                    else {
1016                            contentType = fileVersion.getMimeType();
1017                    }
1018    
1019                    if (_log.isDebugEnabled()) {
1020                            _log.debug("Content type set to " + contentType);
1021                    }
1022    
1023                    // Send file
1024    
1025                    if (isSupportsRangeHeader(contentType)) {
1026                            sendFileWithRangeHeader(
1027                                    request, response, fileName, inputStream, contentLength,
1028                                    contentType);
1029                    }
1030                    else {
1031                            ServletResponseUtil.sendFile(
1032                                    request, response, fileName, inputStream, contentLength,
1033                                    contentType);
1034                    }
1035            }
1036    
1037            protected void sendFile(
1038                            HttpServletResponse response, User user, long groupId,
1039                            long folderId, String title)
1040                    throws Exception {
1041    
1042                    FileEntry fileEntry = DLAppServiceUtil.getFileEntry(
1043                            groupId, folderId, title);
1044    
1045                    String contentType = fileEntry.getMimeType();
1046    
1047                    response.setContentType(contentType);
1048    
1049                    InputStream inputStream = fileEntry.getContentStream();
1050    
1051                    ServletResponseUtil.write(response, inputStream, fileEntry.getSize());
1052            }
1053    
1054            protected void sendFileWithRangeHeader(
1055                            HttpServletRequest request, HttpServletResponse response,
1056                            String fileName, InputStream inputStream, long contentLength,
1057                            String contentType)
1058                    throws IOException {
1059    
1060                    if (_log.isDebugEnabled()) {
1061                            _log.debug("Accepting ranges for the file " + fileName);
1062                    }
1063    
1064                    response.setHeader(
1065                            HttpHeaders.ACCEPT_RANGES, HttpHeaders.ACCEPT_RANGES_BYTES_VALUE);
1066    
1067                    List<Range> ranges = null;
1068    
1069                    try {
1070                            ranges = ServletResponseUtil.getRanges(
1071                                    request, response, contentLength);
1072                    }
1073                    catch (IOException ioe) {
1074                            if (_log.isErrorEnabled()) {
1075                                    _log.error(ioe);
1076                            }
1077    
1078                            response.setHeader(
1079                                    HttpHeaders.CONTENT_RANGE, "bytes */" + contentLength);
1080    
1081                            response.sendError(
1082                                    HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
1083    
1084                            return;
1085                    }
1086    
1087                    if ((ranges == null) || ranges.isEmpty()) {
1088                            ServletResponseUtil.sendFile(
1089                                    request, response, fileName, inputStream, contentLength,
1090                                    contentType);
1091                    }
1092                    else {
1093                            if (_log.isDebugEnabled()) {
1094                                    _log.debug(
1095                                            "Request has range header " +
1096                                                    request.getHeader(HttpHeaders.RANGE));
1097                            }
1098    
1099                            ServletResponseUtil.write(
1100                                    request, response, fileName, ranges, inputStream, contentLength,
1101                                    contentType);
1102                    }
1103            }
1104    
1105            protected void sendGroups(
1106                            HttpServletResponse response, User user, String path)
1107                    throws Exception {
1108    
1109                    if (!PropsValues.WEB_SERVER_SERVLET_DIRECTORY_INDEXING_ENABLED) {
1110                            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
1111    
1112                            return;
1113                    }
1114    
1115                    List<WebServerEntry> webServerEntries = new ArrayList<WebServerEntry>();
1116    
1117                    List<Group> groups = WebDAVUtil.getGroups(user);
1118    
1119                    for (Group group : groups) {
1120                            String name = HttpUtil.fixPath(group.getFriendlyURL());
1121    
1122                            WebServerEntry webServerEntry = new WebServerEntry(
1123                                    path, name + StringPool.SLASH, null, null,
1124                                    group.getDescription(), 0);
1125    
1126                            webServerEntries.add(webServerEntry);
1127                    }
1128    
1129                    sendHTML(response, path, webServerEntries);
1130            }
1131    
1132            protected void sendHTML(
1133                            HttpServletResponse response, String path,
1134                            List<WebServerEntry> webServerEntries)
1135                    throws Exception {
1136    
1137                    Template template = TemplateManagerUtil.getTemplate(
1138                            TemplateConstants.LANG_TYPE_FTL, _templateResource, true);
1139    
1140                    template.put("dateFormat", _dateFormat);
1141                    template.put("entries", webServerEntries);
1142                    template.put("path", HttpUtil.encodePath(path));
1143    
1144                    if (_WEB_SERVER_SERVLET_VERSION_VERBOSITY_DEFAULT) {
1145                    }
1146                    else if (_WEB_SERVER_SERVLET_VERSION_VERBOSITY_PARTIAL) {
1147                            template.put("releaseInfo", ReleaseInfo.getName());
1148                    }
1149                    else {
1150                            template.put("releaseInfo", ReleaseInfo.getReleaseInfo());
1151                    }
1152    
1153                    template.put("validator", Validator_IW.getInstance());
1154    
1155                    response.setContentType(ContentTypes.TEXT_HTML_UTF8);
1156    
1157                    template.processTemplate(response.getWriter());
1158            }
1159    
1160            protected void sendPortletFileEntry(
1161                            HttpServletRequest request, HttpServletResponse response,
1162                            String[] pathArray)
1163                    throws Exception {
1164    
1165                    FileEntry fileEntry = getPortletFileEntry(request, pathArray);
1166    
1167                    if (fileEntry == null) {
1168                            return;
1169                    }
1170    
1171                    String fileName = HttpUtil.decodeURL(
1172                            HtmlUtil.escape(pathArray[2]), true);
1173    
1174                    if (fileEntry.isInTrash()) {
1175                            fileName = TrashUtil.getOriginalTitle(fileName);
1176                    }
1177    
1178                    ServletResponseUtil.sendFile(
1179                            request, response, fileName, fileEntry.getContentStream(),
1180                            fileEntry.getSize(), fileEntry.getMimeType());
1181            }
1182    
1183            protected void writeImage(
1184                    Image image, HttpServletRequest request, HttpServletResponse response) {
1185    
1186                    if (image == null) {
1187                            return;
1188                    }
1189    
1190                    String contentType = null;
1191    
1192                    String type = image.getType();
1193    
1194                    if (!type.equals(ImageConstants.TYPE_NOT_AVAILABLE)) {
1195                            contentType = MimeTypesUtil.getExtensionContentType(type);
1196    
1197                            response.setContentType(contentType);
1198                    }
1199    
1200                    String fileName = ParamUtil.getString(request, "fileName");
1201    
1202                    try {
1203                            byte[] bytes = getImageBytes(request, image);
1204    
1205                            if (Validator.isNotNull(fileName)) {
1206                                    ServletResponseUtil.sendFile(
1207                                            request, response, fileName, bytes, contentType);
1208                            }
1209                            else {
1210                                    ServletResponseUtil.write(response, bytes);
1211                            }
1212                    }
1213                    catch (Exception e) {
1214                            if (_log.isWarnEnabled()) {
1215                                    _log.warn(e, e);
1216                            }
1217                    }
1218            }
1219    
1220            private static void _checkFileEntry(String[] pathArray) throws Exception {
1221                    if (pathArray.length == 1) {
1222                            long dlFileShortcutId = GetterUtil.getLong(pathArray[0]);
1223    
1224                            DLFileShortcut dlFileShortcut =
1225                                    DLAppLocalServiceUtil.getFileShortcut(dlFileShortcutId);
1226    
1227                            DLAppLocalServiceUtil.getFileEntry(
1228                                    dlFileShortcut.getToFileEntryId());
1229                    }
1230                    else if (pathArray.length == 2) {
1231    
1232                            // Unable to check with UUID because of multiple repositories
1233    
1234                    }
1235                    else if (pathArray.length == 3) {
1236                            long groupId = GetterUtil.getLong(pathArray[0]);
1237                            long folderId = GetterUtil.getLong(pathArray[1]);
1238                            String fileName = HttpUtil.decodeURL(pathArray[2]);
1239    
1240                            try {
1241                                    DLAppLocalServiceUtil.getFileEntry(groupId, folderId, fileName);
1242                            }
1243                            catch (RepositoryException re) {
1244                            }
1245                    }
1246                    else {
1247                            long groupId = GetterUtil.getLong(pathArray[0]);
1248    
1249                            String uuid = pathArray[3];
1250    
1251                            try {
1252                                    DLAppLocalServiceUtil.getFileEntryByUuidAndGroupId(
1253                                            uuid, groupId);
1254                            }
1255                            catch (RepositoryException re) {
1256                            }
1257                    }
1258            }
1259    
1260            private static long _getGroupId(long companyId, String name)
1261                    throws Exception {
1262    
1263                    Group group = GroupLocalServiceUtil.fetchFriendlyURLGroup(
1264                            companyId, StringPool.SLASH + name);
1265    
1266                    if (group != null) {
1267                            return group.getGroupId();
1268                    }
1269    
1270                    User user = UserLocalServiceUtil.getUserByScreenName(companyId, name);
1271    
1272                    group = user.getGroup();
1273    
1274                    return group.getGroupId();
1275            }
1276    
1277            private static User _getUser(HttpServletRequest request) throws Exception {
1278                    HttpSession session = request.getSession();
1279    
1280                    if (PortalSessionThreadLocal.getHttpSession() == null) {
1281                            PortalSessionThreadLocal.setHttpSession(session);
1282                    }
1283    
1284                    User user = PortalUtil.getUser(request);
1285    
1286                    if (user != null) {
1287                            return user;
1288                    }
1289    
1290                    String userIdString = (String)session.getAttribute("j_username");
1291                    String password = (String)session.getAttribute("j_password");
1292    
1293                    if ((userIdString != null) && (password != null)) {
1294                            long userId = GetterUtil.getLong(userIdString);
1295    
1296                            user = UserLocalServiceUtil.getUser(userId);
1297                    }
1298                    else {
1299                            long companyId = PortalUtil.getCompanyId(request);
1300    
1301                            Company company = CompanyLocalServiceUtil.getCompany(companyId);
1302    
1303                            user = company.getDefaultUser();
1304                    }
1305    
1306                    return user;
1307            }
1308    
1309            private static final boolean _WEB_SERVER_SERVLET_VERSION_VERBOSITY_DEFAULT =
1310                    StringUtil.equalsIgnoreCase(
1311                            PropsValues.WEB_SERVER_SERVLET_VERSION_VERBOSITY,
1312                            ReleaseInfo.getName());
1313    
1314            private static final boolean _WEB_SERVER_SERVLET_VERSION_VERBOSITY_PARTIAL =
1315                    StringUtil.equalsIgnoreCase(
1316                            PropsValues.WEB_SERVER_SERVLET_VERSION_VERBOSITY, "partial");
1317    
1318            private static Log _log = LogFactoryUtil.getLog(WebServerServlet.class);
1319    
1320            private static Set<String> _acceptRangesMimeTypes = SetUtil.fromArray(
1321                    PropsValues.WEB_SERVER_SERVLET_ACCEPT_RANGES_MIME_TYPES);
1322            private static Format _dateFormat =
1323                    FastDateFormatFactoryUtil.getSimpleDateFormat("d MMM yyyy HH:mm z");
1324    
1325            private boolean _lastModified = true;
1326            private TemplateResource _templateResource;
1327    
1328    }