001
014
015 package com.liferay.portlet.journal.util;
016
017 import com.liferay.portal.kernel.io.unsync.UnsyncStringWriter;
018 import com.liferay.portal.kernel.templateparser.BaseTemplateParser;
019 import com.liferay.portal.kernel.templateparser.TemplateContext;
020 import com.liferay.portal.kernel.templateparser.TemplateNode;
021 import com.liferay.portal.kernel.templateparser.TransformException;
022 import com.liferay.portal.kernel.util.StringBundler;
023 import com.liferay.portal.kernel.util.StringPool;
024 import com.liferay.portal.kernel.velocity.VelocityContext;
025 import com.liferay.portal.kernel.velocity.VelocityEngineUtil;
026 import com.liferay.portal.kernel.xml.Element;
027 import com.liferay.portal.util.PropsValues;
028 import com.liferay.portal.velocity.VelocityResourceListener;
029 import com.liferay.util.ContentUtil;
030 import com.liferay.util.PwdGenerator;
031
032 import java.util.ArrayList;
033 import java.util.HashMap;
034 import java.util.List;
035 import java.util.Map;
036
037 import org.apache.velocity.exception.ParseErrorException;
038 import org.apache.velocity.exception.VelocityException;
039
040
045 public class VelocityTemplateParser extends BaseTemplateParser {
046
047 protected String getErrorTemplateContent() {
048 return ContentUtil.get(PropsValues.JOURNAL_ERROR_TEMPLATE_VELOCITY);
049 }
050
051 protected String getErrorTemplateId() {
052 return PropsValues.JOURNAL_ERROR_TEMPLATE_VELOCITY;
053 }
054
055 protected String getJournalTemplatesPath() {
056 StringBundler sb = new StringBundler(5);
057
058 sb.append(VelocityResourceListener.JOURNAL_SEPARATOR);
059 sb.append(StringPool.SLASH);
060 sb.append(getCompanyId());
061 sb.append(StringPool.SLASH);
062 sb.append(getGroupId());
063
064 return sb.toString();
065 }
066
067 @Override
068 protected TemplateContext getTemplateContext() throws Exception {
069 return VelocityEngineUtil.getWrappedRestrictedToolsContext();
070 }
071
072 @Override
073 protected List<TemplateNode> getTemplateNodes(Element element)
074 throws Exception {
075
076 List<TemplateNode> templateNodes = new ArrayList<TemplateNode>();
077
078 Map<String, TemplateNode> prototypeTemplateNodes =
079 new HashMap<String, TemplateNode>();
080
081 List<Element> dynamicElementElements = element.elements(
082 "dynamic-element");
083
084 for (Element dynamicElementElement : dynamicElementElements) {
085 Element dynamicContentElement = dynamicElementElement.element(
086 "dynamic-content");
087
088 String data = StringPool.BLANK;
089
090 if (dynamicContentElement != null) {
091 data = dynamicContentElement.getText();
092 }
093
094 String name = dynamicElementElement.attributeValue("name", "");
095
096 if (name.length() == 0) {
097 throw new TransformException(
098 "Element missing \"name\" attribute");
099 }
100
101 String type = dynamicElementElement.attributeValue("type", "");
102
103 TemplateNode templateNode = new TemplateNode(
104 getThemeDisplay(), name, stripCDATA(data), type);
105
106 if (dynamicElementElement.element("dynamic-element") != null) {
107 templateNode.appendChildren(
108 getTemplateNodes(dynamicElementElement));
109 }
110 else if ((dynamicContentElement != null) &&
111 (dynamicContentElement.element("option") != null)) {
112
113 List<Element> optionElements = dynamicContentElement.elements(
114 "option");
115
116 for (Element optionElement : optionElements) {
117 templateNode.appendOption(
118 stripCDATA(optionElement.getText()));
119 }
120 }
121
122 TemplateNode prototypeTemplateNode = prototypeTemplateNodes.get(
123 name);
124
125 if (prototypeTemplateNode == null) {
126 prototypeTemplateNode = templateNode;
127
128 prototypeTemplateNodes.put(name, prototypeTemplateNode);
129
130 templateNodes.add(templateNode);
131 }
132
133 prototypeTemplateNode.appendSibling(templateNode);
134 }
135
136 return templateNodes;
137 }
138
139 @Override
140 protected boolean mergeTemplate(
141 TemplateContext templateContext,
142 UnsyncStringWriter unsyncStringWriter)
143 throws Exception {
144
145 VelocityContext velocityContext = (VelocityContext)templateContext;
146
147 try {
148 return VelocityEngineUtil.mergeTemplate(
149 getTemplateId(), getScript(), velocityContext,
150 unsyncStringWriter);
151 }
152 catch (VelocityException ve) {
153 String errorTemplateId = getErrorTemplateId();
154 String errorTemplateContent = getErrorTemplateContent();
155
156 velocityContext.put("exception", ve.getMessage());
157 velocityContext.put("script", getScript());
158
159 if (ve instanceof ParseErrorException) {
160 ParseErrorException pee = (ParseErrorException)ve;
161
162 velocityContext.put("column", pee.getColumnNumber());
163 velocityContext.put("line", pee.getLineNumber());
164 }
165
166 unsyncStringWriter.reset();
167
168 return VelocityEngineUtil.mergeTemplate(
169 errorTemplateId, errorTemplateContent, velocityContext,
170 unsyncStringWriter);
171 }
172 }
173
174 @Override
175 protected void populateTemplateContext(TemplateContext templateContext)
176 throws Exception {
177
178 super.populateTemplateContext(templateContext);
179
180 templateContext.put("journalTemplatesPath", getJournalTemplatesPath());
181
182 String randomNamespace =
183 PwdGenerator.getPassword(PwdGenerator.KEY3, 4) +
184 StringPool.UNDERLINE;
185
186 templateContext.put("randomNamespace", randomNamespace);
187 }
188
189 protected String stripCDATA(String s) {
190 if (s.startsWith(StringPool.CDATA_OPEN) &&
191 s.endsWith(StringPool.CDATA_CLOSE)) {
192
193 s = s.substring(
194 StringPool.CDATA_OPEN.length(),
195 s.length() - StringPool.CDATA_CLOSE.length());
196 }
197
198 return s;
199 }
200
201 }