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