1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portal.webserver;
16  
17  import com.liferay.portal.NoSuchGroupException;
18  import com.liferay.portal.freemarker.FreeMarkerUtil;
19  import com.liferay.portal.kernel.dao.orm.QueryUtil;
20  import com.liferay.portal.kernel.freemarker.FreeMarkerContext;
21  import com.liferay.portal.kernel.freemarker.FreeMarkerEngineUtil;
22  import com.liferay.portal.kernel.util.ContentTypes;
23  import com.liferay.portal.kernel.util.FastDateFormatFactoryUtil;
24  import com.liferay.portal.kernel.util.FileUtil;
25  import com.liferay.portal.kernel.util.GetterUtil;
26  import com.liferay.portal.kernel.util.HttpUtil;
27  import com.liferay.portal.kernel.util.MimeTypesUtil;
28  import com.liferay.portal.kernel.util.OrderByComparator;
29  import com.liferay.portal.kernel.util.ParamUtil;
30  import com.liferay.portal.kernel.util.ReleaseInfo;
31  import com.liferay.portal.kernel.util.StringPool;
32  import com.liferay.portal.kernel.util.StringUtil;
33  import com.liferay.portal.kernel.util.Validator;
34  import com.liferay.portal.kernel.util.Validator_IW;
35  import com.liferay.portal.model.Company;
36  import com.liferay.portal.model.Group;
37  import com.liferay.portal.model.GroupConstants;
38  import com.liferay.portal.model.User;
39  import com.liferay.portal.security.auth.PrincipalException;
40  import com.liferay.portal.security.auth.PrincipalThreadLocal;
41  import com.liferay.portal.security.permission.PermissionChecker;
42  import com.liferay.portal.security.permission.PermissionCheckerFactoryUtil;
43  import com.liferay.portal.security.permission.PermissionThreadLocal;
44  import com.liferay.portal.service.CompanyLocalServiceUtil;
45  import com.liferay.portal.service.GroupLocalServiceUtil;
46  import com.liferay.portal.service.UserLocalServiceUtil;
47  import com.liferay.portal.util.PortalUtil;
48  import com.liferay.portal.util.comparator.GroupFriendlyURLComparator;
49  import com.liferay.portlet.documentlibrary.NoSuchFileEntryException;
50  import com.liferay.portlet.documentlibrary.NoSuchFolderException;
51  import com.liferay.portlet.documentlibrary.model.DLFileEntry;
52  import com.liferay.portlet.documentlibrary.model.DLFileShortcut;
53  import com.liferay.portlet.documentlibrary.model.DLFileVersion;
54  import com.liferay.portlet.documentlibrary.model.DLFolder;
55  import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
56  import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
57  import com.liferay.portlet.documentlibrary.service.DLFileEntryServiceUtil;
58  import com.liferay.portlet.documentlibrary.service.DLFileShortcutServiceUtil;
59  import com.liferay.portlet.documentlibrary.service.DLFileVersionLocalServiceUtil;
60  import com.liferay.portlet.documentlibrary.service.DLFolderServiceUtil;
61  import com.liferay.portlet.documentlibrary.util.DLUtil;
62  import com.liferay.portlet.documentlibrary.util.DocumentConversionUtil;
63  import com.liferay.util.servlet.ServletResponseUtil;
64  
65  import java.io.IOException;
66  import java.io.InputStream;
67  
68  import java.text.Format;
69  
70  import java.util.ArrayList;
71  import java.util.Collections;
72  import java.util.LinkedHashMap;
73  import java.util.List;
74  
75  import javax.servlet.ServletException;
76  import javax.servlet.http.HttpServlet;
77  import javax.servlet.http.HttpServletRequest;
78  import javax.servlet.http.HttpServletResponse;
79  
80  /**
81   * <a href="WebServerServlet.java.html"><b><i>View Source</i></b></a>
82   *
83   * @author Alexander Chow
84   * @author Brian Wing Shun Chan
85   */
86  public class WebServerServlet extends HttpServlet {
87  
88      public void service(
89              HttpServletRequest request, HttpServletResponse response)
90          throws IOException, ServletException {
91  
92          try {
93              long companyId = PortalUtil.getCompanyId(request);
94  
95              User user = PortalUtil.getUser(request);
96  
97              if (user == null) {
98                  Company company = CompanyLocalServiceUtil.getCompany(companyId);
99  
100                 user = company.getDefaultUser();
101             }
102 
103             PrincipalThreadLocal.setName(user.getUserId());
104 
105             PermissionChecker permissionChecker =
106                 PermissionCheckerFactoryUtil.create(user, true);
107 
108             PermissionThreadLocal.setPermissionChecker(permissionChecker);
109 
110             String path = HttpUtil.fixPath(request.getPathInfo());
111             String[] pathArray = StringUtil.split(path, StringPool.SLASH);
112 
113             if (pathArray.length == 0) {
114                 sendGroups(
115                     response, user,
116                     request.getServletPath() + StringPool.SLASH + path);
117             }
118             else {
119                 if (Validator.isNumber(pathArray[0])) {
120                     sendFile(request, response, user, pathArray);
121                 }
122                 else {
123                     sendDocumentLibrary(
124                         request, response, user,
125                         request.getServletPath() + StringPool.SLASH + path,
126                         pathArray);
127                 }
128             }
129         }
130         catch (NoSuchFileEntryException nsfee) {
131             PortalUtil.sendError(
132                 HttpServletResponse.SC_NOT_FOUND, nsfee, request, response);
133         }
134         catch (Exception e) {
135             PortalUtil.sendError(e, request, response);
136         }
137     }
138 
139     protected long getGroupId(long companyId, String name) throws Exception {
140         try {
141             Group group = GroupLocalServiceUtil.getFriendlyURLGroup(
142                 companyId, StringPool.SLASH + name);
143 
144             return group.getGroupId();
145         }
146         catch (NoSuchGroupException nsge) {
147         }
148 
149         User user = UserLocalServiceUtil.getUserByScreenName(companyId, name);
150 
151         Group group = user.getGroup();
152 
153         return group.getGroupId();
154     }
155 
156     protected List<Group> getGroups(User user) throws Exception {
157 
158         // Guest
159 
160         if (user.isDefaultUser()) {
161             List<Group> groups = new ArrayList<Group>();
162 
163             Group group = GroupLocalServiceUtil.getGroup(
164                 user.getCompanyId(), GroupConstants.GUEST);
165 
166             groups.add(group);
167 
168             return groups;
169         }
170 
171         // Communities
172 
173         LinkedHashMap<String, Object> params =
174             new LinkedHashMap<String, Object>();
175 
176         params.put("usersGroups", user.getUserId());
177 
178         OrderByComparator orderByComparator = new GroupFriendlyURLComparator(
179             true);
180 
181         List<Group> groups = GroupLocalServiceUtil.search(
182             user.getCompanyId(), null, null, params, QueryUtil.ALL_POS,
183             QueryUtil.ALL_POS, orderByComparator);
184 
185         // Organizations
186 
187         groups.addAll(
188             GroupLocalServiceUtil.getUserOrganizationsGroups(
189                 user.getUserId(), QueryUtil.ALL_POS, QueryUtil.ALL_POS));
190 
191         // User
192 
193         if (!user.isDefaultUser()) {
194             groups.add(user.getGroup());
195         }
196 
197         Collections.sort(groups, orderByComparator);
198 
199         return groups;
200     }
201 
202     protected void sendDocumentLibrary(
203             HttpServletRequest request, HttpServletResponse response, User user,
204             String path, String[] pathArray)
205         throws Exception {
206 
207         long groupId = getGroupId(user.getCompanyId(), pathArray[0]);
208         long dlFolderId = DLFolderConstants.DEFAULT_PARENT_FOLDER_ID;
209 
210         for (int i = 1; i < pathArray.length; i++) {
211             String name = pathArray[i];
212 
213             try {
214                 DLFolder folder = DLFolderServiceUtil.getFolder(
215                     groupId, dlFolderId, name);
216 
217                 dlFolderId = folder.getFolderId();
218             }
219             catch (NoSuchFolderException nsfe) {
220                 if (i != pathArray.length - 1) {
221                     throw nsfe;
222                 }
223 
224                 String title = name;
225 
226                 sendFile(response, user, groupId, dlFolderId, title);
227 
228                 return;
229             }
230         }
231 
232         try {
233             sendFile(response, user, groupId, dlFolderId, "index.html");
234 
235             return;
236         }
237         catch (Exception e) {
238             if ((e instanceof NoSuchFileEntryException) ||
239                 (e instanceof PrincipalException)) {
240 
241                 try {
242                     sendFile(response, user, groupId, dlFolderId, "index.htm");
243 
244                     return;
245                 }
246                 catch (NoSuchFileEntryException nsfee) {
247                 }
248                 catch (PrincipalException pe) {
249                 }
250             }
251             else {
252                 throw e;
253             }
254         }
255 
256         List<WebServerEntry> webServerEntries = new ArrayList<WebServerEntry>();
257 
258         webServerEntries.add(new WebServerEntry(path, "../"));
259 
260         List<DLFolder> dlFolders = DLFolderServiceUtil.getFolders(
261             groupId, dlFolderId);
262 
263         for (DLFolder dlFolder : dlFolders) {
264             webServerEntries.add(
265                 new WebServerEntry(
266                     path, dlFolder.getName() + StringPool.SLASH,
267                     dlFolder.getCreateDate(), dlFolder.getModifiedDate(),
268                     dlFolder.getDescription(), 0));
269         }
270 
271         List<DLFileEntry> dlFileEntries = DLFileEntryServiceUtil.getFileEntries(
272             groupId, dlFolderId);
273 
274         for (DLFileEntry dlFileEntry : dlFileEntries) {
275             webServerEntries.add(
276                 new WebServerEntry(
277                     path, dlFileEntry.getTitle(),
278                     dlFileEntry.getCreateDate(), dlFileEntry.getModifiedDate(),
279                     dlFileEntry.getDescription(), dlFileEntry.getSize()));
280         }
281 
282         sendHTML(response, path, webServerEntries);
283     }
284 
285     protected void sendFile(
286             HttpServletRequest request, HttpServletResponse response,
287             User user, String[] pathArray)
288         throws Exception {
289 
290         long groupId = 0;
291         long folderId = 0;
292         String name = null;
293         String fileName = null;
294 
295         DLFileEntry dlFileEntry = null;
296 
297         if (pathArray.length == 1) {
298             long fileShortcutId = GetterUtil.getLong(pathArray[0]);
299 
300             DLFileShortcut fileShortcut =
301                 DLFileShortcutServiceUtil.getFileShortcut(fileShortcutId);
302 
303             groupId = fileShortcut.getGroupId();
304             folderId = fileShortcut.getToFolderId();
305             name = fileShortcut.getToName();
306 
307             dlFileEntry = DLFileEntryLocalServiceUtil.getFileEntry(
308                 groupId, folderId, name);
309 
310             fileName = dlFileEntry.getTitle();
311         }
312         else if (pathArray.length == 2) {
313             groupId = GetterUtil.getLong(pathArray[0]);
314 
315             dlFileEntry = DLFileEntryServiceUtil.getFileEntryByUuidAndGroupId(
316                 pathArray[1], groupId);
317 
318             folderId = dlFileEntry.getFolderId();
319             fileName = dlFileEntry.getTitle();
320             name = dlFileEntry.getName();
321         }
322         else {
323             groupId = GetterUtil.getLong(pathArray[0]);
324             folderId = GetterUtil.getLong(pathArray[1]);
325             fileName = HttpUtil.decodeURL(pathArray[2], true);
326 
327             dlFileEntry = DLFileEntryServiceUtil.getFileEntryByTitle(
328                 groupId, folderId, fileName);
329 
330             name = dlFileEntry.getName();
331         }
332 
333         if (dlFileEntry == null) {
334             throw new NoSuchFileEntryException();
335         }
336 
337         String version = ParamUtil.getString(request, "version");
338 
339         String targetExtension = ParamUtil.getString(
340             request, "targetExtension");
341 
342         if (Validator.isNull(version)) {
343             if (Validator.isNotNull(dlFileEntry.getVersion())) {
344                 version = dlFileEntry.getVersion();
345             }
346             else {
347                 throw new NoSuchFileEntryException();
348             }
349         }
350 
351         InputStream is = DLFileEntryLocalServiceUtil.getFileAsStream(
352             user.getCompanyId(), user.getUserId(), groupId, folderId, name,
353             version);
354 
355         boolean converted = false;
356 
357         if (Validator.isNotNull(targetExtension)) {
358             String id = DocumentConversionUtil.getTempFileId(
359                 dlFileEntry.getFileEntryId(), version);
360 
361             String sourceExtension = FileUtil.getExtension(fileName);
362 
363             InputStream convertedIS = DocumentConversionUtil.convert(
364                 id, is, sourceExtension, targetExtension);
365 
366             if ((convertedIS != null) && (convertedIS != is)) {
367                 fileName = FileUtil.stripExtension(fileName).concat(
368                     StringPool.PERIOD).concat(targetExtension);
369 
370                 is = convertedIS;
371 
372                 converted = true;
373             }
374         }
375 
376         int contentLength = 0;
377 
378         if (!converted) {
379             if (DLUtil.compareVersions(version, dlFileEntry.getVersion()) >=
380                     0) {
381 
382                 contentLength = (int)dlFileEntry.getSize();
383             }
384             else {
385                 DLFileVersion fileVersion =
386                     DLFileVersionLocalServiceUtil.getFileVersion(
387                         groupId, folderId, name, version);
388 
389                 contentLength = (int)fileVersion.getSize();
390             }
391         }
392 
393         String contentType = MimeTypesUtil.getContentType(fileName);
394 
395         ServletResponseUtil.sendFile(
396             request, response, fileName, is, contentLength, contentType);
397     }
398 
399     protected void sendFile(
400             HttpServletResponse response, User user, long groupId,
401             long folderId, String title)
402         throws Exception {
403 
404         DLFileEntry dlFileEntry = DLFileEntryServiceUtil.getFileEntryByTitle(
405             groupId, folderId, title);
406 
407         String contentType = MimeTypesUtil.getContentType(
408             dlFileEntry.getTitle());
409 
410         InputStream inputStream = DLFileEntryLocalServiceUtil.getFileAsStream(
411             user.getCompanyId(), user.getUserId(), groupId, folderId,
412             dlFileEntry.getName());
413 
414         response.setContentType(contentType);
415 
416         ServletResponseUtil.write(response, inputStream);
417     }
418 
419     protected void sendGroups(
420             HttpServletResponse response, User user, String path)
421         throws Exception {
422 
423         List<WebServerEntry> webServerEntries = new ArrayList<WebServerEntry>();
424 
425         List<Group> groups = getGroups(user);
426 
427         for (Group group : groups) {
428             String name = HttpUtil.fixPath(group.getFriendlyURL());
429 
430             webServerEntries.add(
431                 new WebServerEntry(
432                     path, name + StringPool.SLASH, null, null,
433                     group.getDescription(), 0));
434         }
435 
436         sendHTML(response, path, webServerEntries);
437     }
438 
439     protected void sendHTML(
440             HttpServletResponse response, String path,
441             List<WebServerEntry> webServerEntries)
442         throws Exception {
443 
444         FreeMarkerContext freeMarkerContext =
445             FreeMarkerEngineUtil.getWrappedRestrictedToolsContext();
446 
447         freeMarkerContext.put("dateFormat", _dateFormat);
448         freeMarkerContext.put("entries", webServerEntries);
449         freeMarkerContext.put("path", HttpUtil.encodePath(path));
450         freeMarkerContext.put("serverInfo", ReleaseInfo.getServerInfo());
451         freeMarkerContext.put("validator", Validator_IW.getInstance());
452 
453         String html = FreeMarkerUtil.process(_TPL_TEMPLATE, freeMarkerContext);
454 
455         response.setContentType(ContentTypes.TEXT_HTML_UTF8);
456 
457         ServletResponseUtil.write(response, html);
458     }
459 
460     private static final String _DATE_FORMAT_PATTERN = "d MMM yyyy HH:mm z";
461 
462     private static final String _TPL_TEMPLATE =
463         "com/liferay/portal/webserver/dependencies/template.ftl";
464 
465     private static Format _dateFormat =
466         FastDateFormatFactoryUtil.getSimpleDateFormat(_DATE_FORMAT_PATTERN);
467 
468 }