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.portlet.journal.util;
16  
17  import com.liferay.portal.freemarker.JournalTemplateLoader;
18  import com.liferay.portal.kernel.exception.SystemException;
19  import com.liferay.portal.kernel.freemarker.FreeMarkerContext;
20  import com.liferay.portal.kernel.freemarker.FreeMarkerEngineUtil;
21  import com.liferay.portal.kernel.io.unsync.UnsyncStringWriter;
22  import com.liferay.portal.kernel.util.GetterUtil;
23  import com.liferay.portal.kernel.util.LocaleUtil;
24  import com.liferay.portal.kernel.util.StringPool;
25  import com.liferay.portal.kernel.xml.Document;
26  import com.liferay.portal.kernel.xml.DocumentException;
27  import com.liferay.portal.kernel.xml.Element;
28  import com.liferay.portal.kernel.xml.SAXReaderUtil;
29  import com.liferay.portal.model.Company;
30  import com.liferay.portal.security.permission.PermissionThreadLocal;
31  import com.liferay.portal.service.CompanyLocalServiceUtil;
32  import com.liferay.portal.util.ContentUtil;
33  import com.liferay.portal.util.PropsValues;
34  import com.liferay.portlet.journal.TransformException;
35  import com.liferay.util.PwdGenerator;
36  
37  import freemarker.core.ParseException;
38  
39  import freemarker.template.TemplateException;
40  
41  import java.io.IOException;
42  
43  import java.util.List;
44  import java.util.Map;
45  
46  /**
47   * <a href="FreeMarkerTemplateParser.java.html"><b><i>View Source</i></b></a>
48   *
49   * @author Mika Koivisto
50   */
51  public class FreeMarkerTemplateParser extends VelocityTemplateParser {
52  
53      public String doTransform(
54              Map<String, String> tokens, String viewMode, String languageId,
55              String xml, String script)
56          throws Exception {
57  
58          UnsyncStringWriter unsyncStringWriter = new UnsyncStringWriter(true);
59  
60          boolean load = false;
61  
62          try {
63              FreeMarkerContext freeMarkerContext =
64                  FreeMarkerEngineUtil.getWrappedRestrictedToolsContext();
65  
66              Document doc = SAXReaderUtil.read(xml);
67  
68              Element root = doc.getRootElement();
69  
70              List<TemplateNode> nodes = extractDynamicContents(root);
71  
72              for (TemplateNode node : nodes) {
73                  freeMarkerContext.put(node.getName(), node);
74              }
75  
76              freeMarkerContext.put(
77                  "xmlRequest", root.element("request").asXML());
78              freeMarkerContext.put(
79                  "request", insertRequestVariables(root.element("request")));
80  
81              long companyId = GetterUtil.getLong(tokens.get("company_id"));
82              Company company = CompanyLocalServiceUtil.getCompanyById(companyId);
83              long groupId = GetterUtil.getLong(tokens.get("group_id"));
84              String templateId = tokens.get("template_id");
85              String journalTemplatesPath =
86                  JournalTemplateLoader.JOURNAL_SEPARATOR + StringPool.SLASH +
87                      companyId + StringPool.SLASH + groupId;
88              String randomNamespace =
89                  PwdGenerator.getPassword(PwdGenerator.KEY3, 4) +
90                      StringPool.UNDERLINE;
91  
92              freeMarkerContext.put("company", company);
93              freeMarkerContext.put("companyId", String.valueOf(companyId));
94              freeMarkerContext.put("groupId", String.valueOf(groupId));
95              freeMarkerContext.put("journalTemplatesPath", journalTemplatesPath);
96              freeMarkerContext.put("viewMode", viewMode);
97              freeMarkerContext.put(
98                  "locale", LocaleUtil.fromLanguageId(languageId));
99              freeMarkerContext.put(
100                 "permissionChecker",
101                 PermissionThreadLocal.getPermissionChecker());
102             freeMarkerContext.put("randomNamespace", randomNamespace);
103 
104             script = injectEditInPlace(xml, script);
105 
106             try {
107                 String freeMarkerTemplateId = companyId + groupId + templateId;
108 
109                 load = FreeMarkerEngineUtil.mergeTemplate(
110                     freeMarkerTemplateId, script, freeMarkerContext,
111                     unsyncStringWriter);
112             }
113             catch (SystemException se) {
114                 if (se.getCause() instanceof TemplateException) {
115                     TemplateException te = (TemplateException)se.getCause();
116 
117                     freeMarkerContext.put("exception", te.getMessage());
118                     freeMarkerContext.put("script", script);
119 
120                     String freeMarkerTemplateId =
121                         PropsValues.JOURNAL_ERROR_TEMPLATE_FREEMARKER;
122                     String freemarkerTemplateContent =
123                         ContentUtil.get(
124                             PropsValues.JOURNAL_ERROR_TEMPLATE_FREEMARKER);
125 
126                     unsyncStringWriter = new UnsyncStringWriter(true);
127 
128                     load = FreeMarkerEngineUtil.mergeTemplate(
129                         freeMarkerTemplateId, freemarkerTemplateContent,
130                         freeMarkerContext, unsyncStringWriter);
131                 }
132                 else {
133                     throw se;
134                 }
135             }
136             catch (ParseException pe) {
137                 freeMarkerContext.put("exception", pe.getMessage());
138                 freeMarkerContext.put("script", script);
139 
140                 freeMarkerContext.put("column", new Integer(
141                     pe.getColumnNumber()));
142                 freeMarkerContext.put("line", new Integer(
143                     pe.getLineNumber()));
144 
145                 String freeMarkerTemplateId =
146                     PropsValues.JOURNAL_ERROR_TEMPLATE_FREEMARKER;
147                 String freemarkerTemplateContent =
148                     ContentUtil.get(
149                         PropsValues.JOURNAL_ERROR_TEMPLATE_FREEMARKER);
150 
151                 unsyncStringWriter = new UnsyncStringWriter(true);
152 
153                 load = FreeMarkerEngineUtil.mergeTemplate(
154                     freeMarkerTemplateId, freemarkerTemplateContent,
155                     freeMarkerContext, unsyncStringWriter);
156             }
157         }
158         catch (Exception e) {
159             if (e instanceof DocumentException) {
160                 throw new TransformException("Unable to read XML document", e);
161             }
162             else if (e instanceof IOException) {
163                 throw new TransformException(
164                     "Error reading freemarker template", e);
165             }
166             else if (e instanceof TransformException) {
167                 throw (TransformException) e;
168             }
169             else {
170                 throw new TransformException("Unhandled exception", e);
171             }
172         }
173 
174         if (!load) {
175             throw new TransformException(
176                 "Unable to dynamically load freemarker transform script");
177         }
178 
179         return unsyncStringWriter.toString();
180     }
181 
182 }