001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.webserver;
016    
017    import com.liferay.portal.NoSuchGroupException;
018    import com.liferay.portal.freemarker.FreeMarkerUtil;
019    import com.liferay.portal.kernel.freemarker.FreeMarkerContext;
020    import com.liferay.portal.kernel.freemarker.FreeMarkerEngineUtil;
021    import com.liferay.portal.kernel.util.ContentTypes;
022    import com.liferay.portal.kernel.util.FastDateFormatFactoryUtil;
023    import com.liferay.portal.kernel.util.FileUtil;
024    import com.liferay.portal.kernel.util.GetterUtil;
025    import com.liferay.portal.kernel.util.HttpUtil;
026    import com.liferay.portal.kernel.util.MimeTypesUtil;
027    import com.liferay.portal.kernel.util.ParamUtil;
028    import com.liferay.portal.kernel.util.ReleaseInfo;
029    import com.liferay.portal.kernel.util.StringPool;
030    import com.liferay.portal.kernel.util.StringUtil;
031    import com.liferay.portal.kernel.util.Validator;
032    import com.liferay.portal.kernel.util.Validator_IW;
033    import com.liferay.portal.kernel.webdav.WebDAVUtil;
034    import com.liferay.portal.model.Company;
035    import com.liferay.portal.model.Group;
036    import com.liferay.portal.model.User;
037    import com.liferay.portal.security.auth.PrincipalException;
038    import com.liferay.portal.security.auth.PrincipalThreadLocal;
039    import com.liferay.portal.security.permission.PermissionChecker;
040    import com.liferay.portal.security.permission.PermissionCheckerFactoryUtil;
041    import com.liferay.portal.security.permission.PermissionThreadLocal;
042    import com.liferay.portal.service.CompanyLocalServiceUtil;
043    import com.liferay.portal.service.GroupLocalServiceUtil;
044    import com.liferay.portal.service.UserLocalServiceUtil;
045    import com.liferay.portal.util.PortalUtil;
046    import com.liferay.portlet.documentlibrary.NoSuchFileEntryException;
047    import com.liferay.portlet.documentlibrary.NoSuchFolderException;
048    import com.liferay.portlet.documentlibrary.model.DLFileEntry;
049    import com.liferay.portlet.documentlibrary.model.DLFileShortcut;
050    import com.liferay.portlet.documentlibrary.model.DLFileVersion;
051    import com.liferay.portlet.documentlibrary.model.DLFolder;
052    import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
053    import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
054    import com.liferay.portlet.documentlibrary.service.DLFileEntryServiceUtil;
055    import com.liferay.portlet.documentlibrary.service.DLFileShortcutServiceUtil;
056    import com.liferay.portlet.documentlibrary.service.DLFileVersionLocalServiceUtil;
057    import com.liferay.portlet.documentlibrary.service.DLFolderServiceUtil;
058    import com.liferay.portlet.documentlibrary.util.DLUtil;
059    import com.liferay.portlet.documentlibrary.util.DocumentConversionUtil;
060    import com.liferay.util.servlet.ServletResponseUtil;
061    
062    import java.io.IOException;
063    import java.io.InputStream;
064    
065    import java.text.Format;
066    
067    import java.util.ArrayList;
068    import java.util.List;
069    
070    import javax.servlet.ServletException;
071    import javax.servlet.http.HttpServlet;
072    import javax.servlet.http.HttpServletRequest;
073    import javax.servlet.http.HttpServletResponse;
074    
075    /**
076     * @author Alexander Chow
077     * @author Brian Wing Shun Chan
078     */
079    public class WebServerServlet extends HttpServlet {
080    
081            public void service(
082                            HttpServletRequest request, HttpServletResponse response)
083                    throws IOException, ServletException {
084    
085                    try {
086                            long companyId = PortalUtil.getCompanyId(request);
087    
088                            User user = PortalUtil.getUser(request);
089    
090                            if (user == null) {
091                                    Company company = CompanyLocalServiceUtil.getCompany(companyId);
092    
093                                    user = company.getDefaultUser();
094                            }
095    
096                            PrincipalThreadLocal.setName(user.getUserId());
097    
098                            PermissionChecker permissionChecker =
099                                    PermissionCheckerFactoryUtil.create(user, true);
100    
101                            PermissionThreadLocal.setPermissionChecker(permissionChecker);
102    
103                            String path = HttpUtil.fixPath(request.getPathInfo());
104                            String[] pathArray = StringUtil.split(path, StringPool.SLASH);
105    
106                            if (pathArray.length == 0) {
107                                    sendGroups(
108                                            response, user,
109                                            request.getServletPath() + StringPool.SLASH + path);
110                            }
111                            else {
112                                    if (Validator.isNumber(pathArray[0])) {
113                                            sendFile(request, response, user, pathArray);
114                                    }
115                                    else {
116                                            sendDocumentLibrary(
117                                                    request, response, user,
118                                                    request.getServletPath() + StringPool.SLASH + path,
119                                                    pathArray);
120                                    }
121                            }
122                    }
123                    catch (NoSuchFileEntryException nsfee) {
124                            PortalUtil.sendError(
125                                    HttpServletResponse.SC_NOT_FOUND, nsfee, request, response);
126                    }
127                    catch (Exception e) {
128                            PortalUtil.sendError(e, request, response);
129                    }
130            }
131    
132            protected long getGroupId(long companyId, String name) throws Exception {
133                    try {
134                            Group group = GroupLocalServiceUtil.getFriendlyURLGroup(
135                                    companyId, StringPool.SLASH + name);
136    
137                            return group.getGroupId();
138                    }
139                    catch (NoSuchGroupException nsge) {
140                    }
141    
142                    User user = UserLocalServiceUtil.getUserByScreenName(companyId, name);
143    
144                    Group group = user.getGroup();
145    
146                    return group.getGroupId();
147            }
148    
149            protected void sendDocumentLibrary(
150                            HttpServletRequest request, HttpServletResponse response, User user,
151                            String path, String[] pathArray)
152                    throws Exception {
153    
154                    long groupId = getGroupId(user.getCompanyId(), pathArray[0]);
155                    long dlFolderId = DLFolderConstants.DEFAULT_PARENT_FOLDER_ID;
156    
157                    for (int i = 1; i < pathArray.length; i++) {
158                            String name = pathArray[i];
159    
160                            try {
161                                    DLFolder folder = DLFolderServiceUtil.getFolder(
162                                            groupId, dlFolderId, name);
163    
164                                    dlFolderId = folder.getFolderId();
165                            }
166                            catch (NoSuchFolderException nsfe) {
167                                    if (i != pathArray.length - 1) {
168                                            throw nsfe;
169                                    }
170    
171                                    String title = name;
172    
173                                    sendFile(response, user, groupId, dlFolderId, title);
174    
175                                    return;
176                            }
177                    }
178    
179                    try {
180                            sendFile(response, user, groupId, dlFolderId, "index.html");
181    
182                            return;
183                    }
184                    catch (Exception e) {
185                            if ((e instanceof NoSuchFileEntryException) ||
186                                    (e instanceof PrincipalException)) {
187    
188                                    try {
189                                            sendFile(response, user, groupId, dlFolderId, "index.htm");
190    
191                                            return;
192                                    }
193                                    catch (NoSuchFileEntryException nsfee) {
194                                    }
195                                    catch (PrincipalException pe) {
196                                    }
197                            }
198                            else {
199                                    throw e;
200                            }
201                    }
202    
203                    List<WebServerEntry> webServerEntries = new ArrayList<WebServerEntry>();
204    
205                    webServerEntries.add(new WebServerEntry(path, "../"));
206    
207                    List<DLFolder> dlFolders = DLFolderServiceUtil.getFolders(
208                            groupId, dlFolderId);
209    
210                    for (DLFolder dlFolder : dlFolders) {
211                            webServerEntries.add(
212                                    new WebServerEntry(
213                                            path, dlFolder.getName() + StringPool.SLASH,
214                                            dlFolder.getCreateDate(), dlFolder.getModifiedDate(),
215                                            dlFolder.getDescription(), 0));
216                    }
217    
218                    List<DLFileEntry> dlFileEntries = DLFileEntryServiceUtil.getFileEntries(
219                            groupId, dlFolderId);
220    
221                    for (DLFileEntry dlFileEntry : dlFileEntries) {
222                            webServerEntries.add(
223                                    new WebServerEntry(
224                                            path, dlFileEntry.getTitle(),
225                                            dlFileEntry.getCreateDate(), dlFileEntry.getModifiedDate(),
226                                            dlFileEntry.getDescription(), dlFileEntry.getSize()));
227                    }
228    
229                    sendHTML(response, path, webServerEntries);
230            }
231    
232            protected void sendFile(
233                            HttpServletRequest request, HttpServletResponse response,
234                            User user, String[] pathArray)
235                    throws Exception {
236    
237                    long groupId = 0;
238                    long folderId = 0;
239                    String name = null;
240                    String fileName = null;
241    
242                    DLFileEntry dlFileEntry = null;
243    
244                    if (pathArray.length == 1) {
245                            long fileShortcutId = GetterUtil.getLong(pathArray[0]);
246    
247                            DLFileShortcut fileShortcut =
248                                    DLFileShortcutServiceUtil.getFileShortcut(fileShortcutId);
249    
250                            groupId = fileShortcut.getGroupId();
251                            folderId = fileShortcut.getToFolderId();
252                            name = fileShortcut.getToName();
253    
254                            dlFileEntry = DLFileEntryServiceUtil.getFileEntry(
255                                    groupId, folderId, name);
256    
257                            fileName = dlFileEntry.getTitle();
258                    }
259                    else if (pathArray.length == 2) {
260                            groupId = GetterUtil.getLong(pathArray[0]);
261    
262                            dlFileEntry = DLFileEntryServiceUtil.getFileEntryByUuidAndGroupId(
263                                    pathArray[1], groupId);
264    
265                            folderId = dlFileEntry.getFolderId();
266                            fileName = dlFileEntry.getTitle();
267                            name = dlFileEntry.getName();
268                    }
269                    else {
270                            groupId = GetterUtil.getLong(pathArray[0]);
271                            folderId = GetterUtil.getLong(pathArray[1]);
272                            fileName = HttpUtil.decodeURL(pathArray[2], true);
273    
274                            dlFileEntry = DLFileEntryServiceUtil.getFileEntryByTitle(
275                                    groupId, folderId, fileName);
276    
277                            name = dlFileEntry.getName();
278                    }
279    
280                    if (dlFileEntry == null) {
281                            throw new NoSuchFileEntryException();
282                    }
283    
284                    String version = ParamUtil.getString(request, "version");
285    
286                    String targetExtension = ParamUtil.getString(
287                            request, "targetExtension");
288    
289                    if (Validator.isNull(version)) {
290                            if (Validator.isNotNull(dlFileEntry.getVersion())) {
291                                    version = dlFileEntry.getVersion();
292                            }
293                            else {
294                                    throw new NoSuchFileEntryException();
295                            }
296                    }
297    
298                    DLFileVersion fileVersion =
299                            DLFileVersionLocalServiceUtil.getFileVersion(
300                                    groupId, folderId, name, version);
301    
302                    fileName = fileVersion.getTitle();
303    
304                    String extension = GetterUtil.getString(
305                            FileUtil.getExtension(fileName));
306    
307                    if (Validator.isNull(extension) ||
308                            !extension.equals(fileVersion.getExtension())) {
309    
310                            fileName += StringPool.PERIOD + fileVersion.getExtension();
311                    }
312    
313                    InputStream is = DLFileEntryLocalServiceUtil.getFileAsStream(
314                            user.getCompanyId(), user.getUserId(), groupId, folderId, name,
315                            version);
316    
317                    boolean converted = false;
318    
319                    if (Validator.isNotNull(targetExtension)) {
320                            String id = DocumentConversionUtil.getTempFileId(
321                                    dlFileEntry.getFileEntryId(), version);
322    
323                            String sourceExtension = FileUtil.getExtension(fileName);
324    
325                            InputStream convertedIS = DocumentConversionUtil.convert(
326                                    id, is, sourceExtension, targetExtension);
327    
328                            if ((convertedIS != null) && (convertedIS != is)) {
329                                    fileName = FileUtil.stripExtension(fileName).concat(
330                                            StringPool.PERIOD).concat(targetExtension);
331    
332                                    is = convertedIS;
333    
334                                    converted = true;
335                            }
336                    }
337    
338                    int contentLength = 0;
339    
340                    if (!converted) {
341                            if (DLUtil.compareVersions(version, dlFileEntry.getVersion()) >=
342                                            0) {
343    
344                                    contentLength = (int)dlFileEntry.getSize();
345                            }
346                            else {
347                                    contentLength = (int)fileVersion.getSize();
348                            }
349                    }
350    
351                    String contentType = MimeTypesUtil.getContentType(fileName);
352    
353                    ServletResponseUtil.sendFile(
354                            request, response, fileName, is, contentLength, contentType);
355            }
356    
357            protected void sendFile(
358                            HttpServletResponse response, User user, long groupId,
359                            long folderId, String title)
360                    throws Exception {
361    
362                    DLFileEntry dlFileEntry = DLFileEntryServiceUtil.getFileEntryByTitle(
363                            groupId, folderId, title);
364    
365                    String contentType = MimeTypesUtil.getContentType(
366                            dlFileEntry.getTitle());
367    
368                    InputStream inputStream = DLFileEntryLocalServiceUtil.getFileAsStream(
369                            user.getCompanyId(), user.getUserId(), groupId, folderId,
370                            dlFileEntry.getName());
371    
372                    response.setContentType(contentType);
373    
374                    ServletResponseUtil.write(response, inputStream);
375            }
376    
377            protected void sendGroups(
378                            HttpServletResponse response, User user, String path)
379                    throws Exception {
380    
381                    List<WebServerEntry> webServerEntries = new ArrayList<WebServerEntry>();
382    
383                    List<Group> groups = WebDAVUtil.getGroups(user);
384    
385                    for (Group group : groups) {
386                            String name = HttpUtil.fixPath(group.getFriendlyURL());
387    
388                            webServerEntries.add(
389                                    new WebServerEntry(
390                                            path, name + StringPool.SLASH, null, null,
391                                            group.getDescription(), 0));
392                    }
393    
394                    sendHTML(response, path, webServerEntries);
395            }
396    
397            protected void sendHTML(
398                            HttpServletResponse response, String path,
399                            List<WebServerEntry> webServerEntries)
400                    throws Exception {
401    
402                    FreeMarkerContext freeMarkerContext =
403                            FreeMarkerEngineUtil.getWrappedRestrictedToolsContext();
404    
405                    freeMarkerContext.put("dateFormat", _dateFormat);
406                    freeMarkerContext.put("entries", webServerEntries);
407                    freeMarkerContext.put("path", HttpUtil.encodePath(path));
408                    freeMarkerContext.put("serverInfo", ReleaseInfo.getServerInfo());
409                    freeMarkerContext.put("validator", Validator_IW.getInstance());
410    
411                    String html = FreeMarkerUtil.process(_TPL_TEMPLATE, freeMarkerContext);
412    
413                    response.setContentType(ContentTypes.TEXT_HTML_UTF8);
414    
415                    ServletResponseUtil.write(response, html);
416            }
417    
418            private static final String _DATE_FORMAT_PATTERN = "d MMM yyyy HH:mm z";
419    
420            private static final String _TPL_TEMPLATE =
421                    "com/liferay/portal/webserver/dependencies/template.ftl";
422    
423            private static Format _dateFormat =
424                    FastDateFormatFactoryUtil.getSimpleDateFormat(_DATE_FORMAT_PATTERN);
425    
426    }