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