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