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             portletDisplayClone.recycle();
177 
178             _defineObjects(
179                 request, portletConfig, renderRequest, renderResponse);
180         }
181     }
182 
183     public static String processTemplate(
184             ServletContext servletContext, HttpServletRequest request,
185             HttpServletResponse response, PageContext pageContext,
186             String velocityTemplateId, String velocityTemplateContent)
187         throws Exception {
188 
189         return processTemplate(
190             servletContext, request, response, pageContext, null,
191             velocityTemplateId, velocityTemplateContent);
192     }
193 
194     public static String processTemplate(
195             ServletContext servletContext, HttpServletRequest request,
196             HttpServletResponse response, PageContext pageContext,
197             String portletId, String velocityTemplateId,
198             String velocityTemplateContent)
199         throws Exception {
200 
201         if (Validator.isNull(velocityTemplateContent)) {
202             return StringPool.BLANK;
203         }
204 
205         TemplateProcessor processor = new TemplateProcessor(
206             servletContext, request, response, portletId);
207 
208         VelocityContext velocityContext =
209             VelocityEngineUtil.getWrappedStandardToolsContext();
210 
211         velocityContext.put("processor", processor);
212 
213         // Velocity variables
214 
215         VelocityVariables.insertVariables(velocityContext, request);
216 
217         // liferay:include tag library
218 
219         StringServletResponse stringResponse = new StringServletResponse(
220             response);
221 
222         MethodWrapper methodWrapper = new MethodWrapper(
223             "com.liferay.taglib.util.VelocityTaglib", "init",
224             new Object[] {
225                 servletContext, request, stringResponse, pageContext
226             });
227 
228         Object velocityTaglib = MethodInvoker.invoke(methodWrapper);
229 
230         velocityContext.put("taglibLiferay", velocityTaglib);
231         velocityContext.put("theme", velocityTaglib);
232 
233         StringWriter stringWriter = new StringWriter();
234 
235         try {
236             VelocityEngineUtil.mergeTemplate(
237                 velocityTemplateId, velocityTemplateContent, velocityContext,
238                 stringWriter);
239         }
240         catch (Exception e) {
241             _log.error(e, e);
242 
243             throw e;
244         }
245 
246         String output = stringWriter.toString();
247 
248         Map<String, String> columnsMap = processor.getColumnsMap();
249 
250         Iterator<Map.Entry<String, String>> columnsMapItr =
251             columnsMap.entrySet().iterator();
252 
253         while (columnsMapItr.hasNext()) {
254             Map.Entry<String, String> entry = columnsMapItr.next();
255 
256             String key = entry.getKey();
257             String value = entry.getValue();
258 
259             output = StringUtil.replace(output, key, value);
260         }
261 
262         Map<Portlet, Object[]> portletsMap = processor.getPortletsMap();
263 
264         Iterator<Map.Entry<Portlet, Object[]>> portletsMapItr =
265             portletsMap.entrySet().iterator();
266 
267         while (portletsMapItr.hasNext()) {
268             Map.Entry<Portlet, Object[]> entry = portletsMapItr.next();
269 
270             Portlet portlet = entry.getKey();
271             Object[] value = entry.getValue();
272 
273             String queryString = (String)value[0];
274             String columnId = (String)value[1];
275             Integer columnPos = (Integer)value[2];
276             Integer columnCount = (Integer)value[3];
277 
278             StringBuilder sb = new StringBuilder();
279 
280             processPortlet(
281                 sb, servletContext, request, response, portlet, queryString,
282                 columnId, columnPos, columnCount, null);
283 
284             output = StringUtil.replace(
285                 output, "[$TEMPLATE_PORTLET_" + portlet.getPortletId() + "$]",
286                 sb.toString());
287         }
288 
289         return output;
290     }
291 
292     public static String processXML(
293             HttpServletRequest request, String content,
294             RuntimeLogic runtimeLogic)
295         throws Exception {
296 
297         if (Validator.isNull(content)) {
298             return StringPool.BLANK;
299         }
300 
301         try {
302             request.setAttribute(WebKeys.RENDER_PORTLET_RESOURCE, Boolean.TRUE);
303 
304             StringBuilder sb = new StringBuilder();
305 
306             int x = 0;
307             int y = content.indexOf(runtimeLogic.getOpenTag());
308 
309             while (y != -1) {
310                 sb.append(content.substring(x, y));
311 
312                 int close1 = content.indexOf(runtimeLogic.getClose1Tag(), y);
313                 int close2 = content.indexOf(runtimeLogic.getClose2Tag(), y);
314 
315                 if ((close2 == -1) || ((close1 != -1) && (close1 < close2))) {
316                     x = close1 + runtimeLogic.getClose1Tag().length();
317                 }
318                 else {
319                     x = close2 + runtimeLogic.getClose2Tag().length();
320                 }
321 
322                 runtimeLogic.processXML(sb, content.substring(y, x));
323 
324                 y = content.indexOf(runtimeLogic.getOpenTag(), x);
325             }
326 
327             if (y == -1) {
328                 sb.append(content.substring(x, content.length()));
329             }
330 
331             return sb.toString();
332         }
333         finally {
334             request.removeAttribute(WebKeys.RENDER_PORTLET_RESOURCE);
335         }
336     }
337 
338     private static void _defineObjects(
339         HttpServletRequest request, PortletConfig portletConfig,
340         RenderRequest renderRequest, RenderResponse renderResponse) {
341 
342         if (portletConfig != null) {
343             request.setAttribute(
344                 JavaConstants.JAVAX_PORTLET_CONFIG, portletConfig);
345         }
346 
347         if (renderRequest != null) {
348             request.setAttribute(
349                 JavaConstants.JAVAX_PORTLET_REQUEST, renderRequest);
350         }
351 
352         if (renderResponse != null) {
353             request.setAttribute(
354                 JavaConstants.JAVAX_PORTLET_RESPONSE, renderResponse);
355         }
356     }
357 
358     private static Log _log = LogFactoryUtil.getLog(RuntimePortletUtil.class);
359 
360 }