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.servlet;
16  
17  import com.liferay.portal.kernel.cache.key.CacheKeyGeneratorUtil;
18  import com.liferay.portal.kernel.servlet.ServletContextUtil;
19  import com.liferay.portal.kernel.util.ContentTypes;
20  import com.liferay.portal.kernel.util.FileUtil;
21  import com.liferay.portal.kernel.util.StringBundler;
22  import com.liferay.portal.kernel.util.StringPool;
23  import com.liferay.portal.kernel.util.StringUtil;
24  import com.liferay.portal.kernel.util.Validator;
25  import com.liferay.util.SystemProperties;
26  import com.liferay.util.servlet.ServletResponseUtil;
27  
28  import java.io.File;
29  import java.io.IOException;
30  
31  import java.util.Enumeration;
32  import java.util.Map;
33  
34  import javax.servlet.ServletContext;
35  import javax.servlet.http.HttpServlet;
36  import javax.servlet.http.HttpServletRequest;
37  import javax.servlet.http.HttpServletResponse;
38  
39  /**
40   * <a href="ComboServlet.java.html"><b><i>View Source</i></b></a>
41   *
42   * @author Eduardo Lundgren
43   */
44  public class ComboServlet extends HttpServlet {
45  
46      public void service(
47              HttpServletRequest request, HttpServletResponse response)
48          throws IOException {
49  
50          Map<String, String[]> parameterMap = request.getParameterMap();
51  
52          if (parameterMap.size() == 0) {
53              response.sendError(HttpServletResponse.SC_BAD_REQUEST);
54  
55              return;
56          }
57  
58          byte[] bytes = null;
59  
60          File cacheFile = getCacheFile(request);
61  
62          if (cacheFile.exists()) {
63              bytes = FileUtil.getBytes(cacheFile);
64          }
65          else {
66              StringBundler sb = new StringBundler(parameterMap.size());
67  
68              for (String modulePath : parameterMap.keySet()) {
69                  File file = getFile(modulePath);
70  
71                  if (file != null) {
72                      String moduleContent = FileUtil.read(file);
73  
74                      sb.append(moduleContent);
75                  }
76              }
77  
78              String content = sb.toString();
79  
80              if (Validator.isNotNull(content)) {
81                  bytes = content.getBytes();
82  
83                  FileUtil.write(cacheFile, bytes);
84              }
85              else {
86                  bytes = new byte[0];
87              }
88          }
89  
90          String contentType = ContentTypes.TEXT_JAVASCRIPT;
91  
92          String firstModulePath =
93              (String)request.getParameterNames().nextElement();
94  
95          String extension = FileUtil.getExtension(firstModulePath);
96  
97          if (extension.equalsIgnoreCase(_CSS_EXTENSION)) {
98              contentType = ContentTypes.TEXT_CSS;
99          }
100 
101         response.setContentType(contentType);
102 
103         ServletResponseUtil.write(response, bytes);
104     }
105 
106     protected File getCacheFile(HttpServletRequest request) throws IOException {
107         StringBundler sb = new StringBundler(5);
108 
109         sb.append(request.getRequestURI());
110 
111         String queryString = request.getQueryString();
112 
113         if (queryString != null) {
114             sb.append(StringPool.QUESTION);
115             sb.append(queryString);
116         }
117 
118         long lastModified = 0;
119 
120         Enumeration<String> enu = request.getParameterNames();
121 
122         while (enu.hasMoreElements()) {
123             String modulePath = enu.nextElement();
124 
125             File file = getFile(modulePath);
126 
127             if (file != null) {
128                 lastModified += file.lastModified();
129             }
130         }
131 
132         if (lastModified > 0) {
133             sb.append(StringPool.AMPERSAND);
134             sb.append(lastModified);
135         }
136 
137         String cacheFileName = _TEMP_DIR.concat(
138             CacheKeyGeneratorUtil.getCacheKey(
139                 ComboServlet.class.getName(), sb.toString()));
140 
141         return new File(cacheFileName);
142     }
143 
144     protected File getFile(String path) throws IOException {
145         ServletContext servletContext = getServletContext();
146 
147         String basePath = ServletContextUtil.getRealPath(
148             servletContext, _JAVASCRIPT_DIR);
149 
150         if (basePath == null) {
151             return null;
152         }
153 
154         basePath = StringUtil.replace(
155             basePath, StringPool.BACK_SLASH, StringPool.SLASH);
156 
157         File baseDir = new File(basePath);
158 
159         if (!baseDir.exists()) {
160             return null;
161         }
162 
163         String filePath = ServletContextUtil.getRealPath(servletContext, path);
164 
165         if (filePath == null) {
166             return null;
167         }
168 
169         filePath = StringUtil.replace(
170             filePath, StringPool.BACK_SLASH, StringPool.SLASH);
171 
172         File file = new File(filePath);
173 
174         if (!file.exists()) {
175             return null;
176         }
177 
178         String baseCanonicalPath = baseDir.getCanonicalPath();
179         String fileCanonicalPath = file.getCanonicalPath();
180 
181         if (fileCanonicalPath.indexOf(baseCanonicalPath) == 0) {
182             return file;
183         }
184 
185         return null;
186     }
187 
188     private static final String _CSS_EXTENSION = "css";
189 
190     private static final String _JAVASCRIPT_DIR = "html/js";
191 
192     private static final String _TEMP_DIR =
193         SystemProperties.get(SystemProperties.TMP_DIR) + "/liferay/combo/";
194 
195 }