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