1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    *
5    *
6    *
7    * The contents of this file are subject to the terms of the Liferay Enterprise
8    * Subscription License ("License"). You may not use this file except in
9    * compliance with the License. You can obtain a copy of the License by
10   * contacting Liferay, Inc. See the License for the specific language governing
11   * permissions and limitations under the License, including but not limited to
12   * distribution rights of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portlet.layoutconfiguration.util;
24  
25  import com.liferay.portal.kernel.log.Log;
26  import com.liferay.portal.kernel.log.LogFactoryUtil;
27  import com.liferay.portal.kernel.servlet.StringServletResponse;
28  import com.liferay.portal.kernel.util.JavaConstants;
29  import com.liferay.portal.kernel.util.MethodInvoker;
30  import com.liferay.portal.kernel.util.MethodWrapper;
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.velocity.VelocityContext;
35  import com.liferay.portal.kernel.velocity.VelocityEngineUtil;
36  import com.liferay.portal.model.Portlet;
37  import com.liferay.portal.service.PortletLocalServiceUtil;
38  import com.liferay.portal.theme.PortletDisplay;
39  import com.liferay.portal.theme.PortletDisplayFactory;
40  import com.liferay.portal.theme.ThemeDisplay;
41  import com.liferay.portal.util.PortalUtil;
42  import com.liferay.portal.util.WebKeys;
43  import com.liferay.portal.velocity.VelocityVariables;
44  import com.liferay.portlet.layoutconfiguration.util.velocity.TemplateProcessor;
45  import com.liferay.portlet.layoutconfiguration.util.xml.RuntimeLogic;
46  
47  import java.io.StringWriter;
48  
49  import java.util.Iterator;
50  import java.util.Map;
51  
52  import javax.portlet.PortletConfig;
53  import javax.portlet.RenderRequest;
54  import javax.portlet.RenderResponse;
55  
56  import javax.servlet.ServletContext;
57  import javax.servlet.http.HttpServletRequest;
58  import javax.servlet.http.HttpServletResponse;
59  import javax.servlet.jsp.PageContext;
60  
61  /**
62   * <a href="RuntimePortletUtil.java.html"><b><i>View Source</i></b></a>
63   *
64   * @author Brian Wing Shun Chan
65   * @author Raymond Augé
66   */
67  public class RuntimePortletUtil {
68  
69      public static void processPortlet(
70              StringBuilder sb, ServletContext servletContext,
71              HttpServletRequest request, HttpServletResponse response,
72              RenderRequest renderRequest, RenderResponse renderResponse,
73              String portletId, String queryString)
74          throws Exception {
75  
76          processPortlet(
77              sb, servletContext, request, response, renderRequest,
78              renderResponse, portletId, queryString, null, null, null);
79      }
80  
81      public static void processPortlet(
82              StringBuilder sb, ServletContext servletContext,
83              HttpServletRequest request, HttpServletResponse response,
84              RenderRequest renderRequest, RenderResponse renderResponse,
85              String portletId, String queryString, String columnId,
86              Integer columnPos, Integer columnCount)
87          throws Exception {
88  
89          processPortlet(
90              sb, servletContext, request, response, renderRequest,
91              renderResponse, null, portletId, queryString, columnId, columnPos,
92              columnCount, null);
93      }
94  
95      public static void processPortlet(
96              StringBuilder sb, ServletContext servletContext,
97              HttpServletRequest request, HttpServletResponse response,
98              Portlet portlet, String queryString, String columnId,
99              Integer columnPos, Integer columnCount, String path)
100         throws Exception {
101 
102         processPortlet(
103             sb, servletContext, request, response, null, null, portlet,
104             portlet.getPortletId(), queryString, columnId, columnPos,
105             columnCount, path);
106     }
107 
108     public static void processPortlet(
109             StringBuilder sb, ServletContext servletContext,
110             HttpServletRequest request, HttpServletResponse response,
111             RenderRequest renderRequest, RenderResponse renderResponse,
112             Portlet portlet, String portletId, String queryString,
113             String columnId, Integer columnPos, Integer columnCount,
114             String path)
115         throws Exception {
116 
117         ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
118             WebKeys.THEME_DISPLAY);
119 
120         if (portlet == null) {
121             portlet = PortletLocalServiceUtil.getPortletById(
122                 themeDisplay.getCompanyId(), portletId);
123         }
124 
125         if ((portlet != null) && (portlet.isInstanceable()) &&
126             (!portlet.isAddDefaultResource())) {
127 
128             String instanceId = portlet.getInstanceId();
129 
130             if (Validator.isNotNull(instanceId) &&
131                 Validator.isPassword(instanceId) &&
132                 (instanceId.length() == 4)) {
133 
134                 /*portletId +=
135                     PortletConstants.INSTANCE_SEPARATOR + instanceId;
136 
137                 portlet = PortletLocalServiceUtil.getPortletById(
138                     themeDisplay.getCompanyId(), portletId);*/
139             }
140             else {
141                 if (_log.isDebugEnabled()) {
142                     _log.debug(
143                         "Portlet " + portlet.getPortletId() +
144                             " is instanceable but does not have a " +
145                                 "valid instance id");
146                 }
147 
148                 portlet = null;
149             }
150         }
151 
152         if (portlet == null) {
153             return;
154         }
155 
156         // Capture the current portlet's settings to reset them once the child
157         // portlet is rendered
158 
159         PortletDisplay portletDisplay = themeDisplay.getPortletDisplay();
160 
161         PortletDisplay portletDisplayClone = PortletDisplayFactory.create();
162 
163         portletDisplay.copyTo(portletDisplayClone);
164 
165         PortletConfig portletConfig = (PortletConfig)request.getAttribute(
166             JavaConstants.JAVAX_PORTLET_CONFIG);
167 
168         try {
169             PortalUtil.renderPortlet(
170                 sb, servletContext, request, response, portlet, queryString,
171                 columnId, columnPos, columnCount, path);
172         }
173         finally {
174             portletDisplay.copyFrom(portletDisplayClone);
175 
176             try {
177                 PortletDisplayFactory.recycle(portletDisplayClone);
178             }
179             catch (Exception e) {
180                 _log.error(e);
181             }
182 
183             _defineObjects(
184                 request, portletConfig, renderRequest, renderResponse);
185         }
186     }
187 
188     public static String processTemplate(
189             ServletContext servletContext, HttpServletRequest request,
190             HttpServletResponse response, PageContext pageContext,
191             String velocityTemplateId, String velocityTemplateContent)
192         throws Exception {
193 
194         return processTemplate(
195             servletContext, request, response, pageContext, null,
196             velocityTemplateId, velocityTemplateContent);
197     }
198 
199     public static String processTemplate(
200             ServletContext servletContext, HttpServletRequest request,
201             HttpServletResponse response, PageContext pageContext,
202             String portletId, String velocityTemplateId,
203             String velocityTemplateContent)
204         throws Exception {
205 
206         if (Validator.isNull(velocityTemplateContent)) {
207             return StringPool.BLANK;
208         }
209 
210         TemplateProcessor processor = new TemplateProcessor(
211             servletContext, request, response, portletId);
212 
213         VelocityContext velocityContext =
214             VelocityEngineUtil.getWrappedStandardToolsContext();
215 
216         velocityContext.put("processor", processor);
217 
218         // Velocity variables
219 
220         VelocityVariables.insertVariables(velocityContext, request);
221 
222         // liferay:include tag library
223 
224         StringServletResponse stringResponse = new StringServletResponse(
225             response);
226 
227         MethodWrapper methodWrapper = new MethodWrapper(
228             "com.liferay.taglib.util.VelocityTaglib", "init",
229             new Object[] {
230                 servletContext, request, stringResponse, pageContext
231             });
232 
233         Object velocityTaglib = MethodInvoker.invoke(methodWrapper);
234 
235         velocityContext.put("taglibLiferay", velocityTaglib);
236         velocityContext.put("theme", velocityTaglib);
237 
238         StringWriter stringWriter = new StringWriter();
239 
240         try {
241             VelocityEngineUtil.mergeTemplate(
242                 velocityTemplateId, velocityTemplateContent, velocityContext,
243                 stringWriter);
244         }
245         catch (Exception e) {
246             _log.error(e, e);
247 
248             throw e;
249         }
250 
251         String output = stringWriter.toString();
252 
253         Map<String, String> columnsMap = processor.getColumnsMap();
254 
255         Iterator<Map.Entry<String, String>> columnsMapItr =
256             columnsMap.entrySet().iterator();
257 
258         while (columnsMapItr.hasNext()) {
259             Map.Entry<String, String> entry = columnsMapItr.next();
260 
261             String key = entry.getKey();
262             String value = entry.getValue();
263 
264             output = StringUtil.replace(output, key, value);
265         }
266 
267         Map<Portlet, Object[]> portletsMap = processor.getPortletsMap();
268 
269         Iterator<Map.Entry<Portlet, Object[]>> portletsMapItr =
270             portletsMap.entrySet().iterator();
271 
272         while (portletsMapItr.hasNext()) {
273             Map.Entry<Portlet, Object[]> entry = portletsMapItr.next();
274 
275             Portlet portlet = entry.getKey();
276             Object[] value = entry.getValue();
277 
278             String queryString = (String)value[0];
279             String columnId = (String)value[1];
280             Integer columnPos = (Integer)value[2];
281             Integer columnCount = (Integer)value[3];
282 
283             StringBuilder sb = new StringBuilder();
284 
285             processPortlet(
286                 sb, servletContext, request, response, portlet, queryString,
287                 columnId, columnPos, columnCount, null);
288 
289             output = StringUtil.replace(
290                 output, "[$TEMPLATE_PORTLET_" + portlet.getPortletId() + "$]",
291                 sb.toString());
292         }
293 
294         return output;
295     }
296 
297     public static String processXML(
298             HttpServletRequest request, String content,
299             RuntimeLogic runtimeLogic)
300         throws Exception {
301 
302         if (Validator.isNull(content)) {
303             return StringPool.BLANK;
304         }
305 
306         try {
307             request.setAttribute(WebKeys.RENDER_PORTLET_RESOURCE, Boolean.TRUE);
308 
309             StringBuilder sb = new StringBuilder();
310 
311             int x = 0;
312             int y = content.indexOf(runtimeLogic.getOpenTag());
313 
314             while (y != -1) {
315                 sb.append(content.substring(x, y));
316 
317                 int close1 = content.indexOf(runtimeLogic.getClose1Tag(), y);
318                 int close2 = content.indexOf(runtimeLogic.getClose2Tag(), y);
319 
320                 if ((close2 == -1) || ((close1 != -1) && (close1 < close2))) {
321                     x = close1 + runtimeLogic.getClose1Tag().length();
322                 }
323                 else {
324                     x = close2 + runtimeLogic.getClose2Tag().length();
325                 }
326 
327                 runtimeLogic.processXML(sb, content.substring(y, x));
328 
329                 y = content.indexOf(runtimeLogic.getOpenTag(), x);
330             }
331 
332             if (y == -1) {
333                 sb.append(content.substring(x, content.length()));
334             }
335 
336             return sb.toString();
337         }
338         finally {
339             request.removeAttribute(WebKeys.RENDER_PORTLET_RESOURCE);
340         }
341     }
342 
343     private static void _defineObjects(
344         HttpServletRequest request, PortletConfig portletConfig,
345         RenderRequest renderRequest, RenderResponse renderResponse) {
346 
347         if (portletConfig != null) {
348             request.setAttribute(
349                 JavaConstants.JAVAX_PORTLET_CONFIG, portletConfig);
350         }
351 
352         if (renderRequest != null) {
353             request.setAttribute(
354                 JavaConstants.JAVAX_PORTLET_REQUEST, renderRequest);
355         }
356 
357         if (renderResponse != null) {
358             request.setAttribute(
359                 JavaConstants.JAVAX_PORTLET_RESPONSE, renderResponse);
360         }
361     }
362 
363     private static Log _log = LogFactoryUtil.getLog(RuntimePortletUtil.class);
364 
365 }