001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.journal.util;
016    
017    import com.liferay.portal.kernel.io.unsync.UnsyncStringWriter;
018    import com.liferay.portal.kernel.template.StringTemplateResource;
019    import com.liferay.portal.kernel.template.Template;
020    import com.liferay.portal.kernel.template.TemplateConstants;
021    import com.liferay.portal.kernel.template.TemplateContextType;
022    import com.liferay.portal.kernel.template.TemplateManagerUtil;
023    import com.liferay.portal.kernel.template.TemplateResource;
024    import com.liferay.portal.kernel.template.URLTemplateResource;
025    import com.liferay.portal.kernel.templateparser.BaseTemplateParser;
026    import com.liferay.portal.kernel.templateparser.TemplateContext;
027    import com.liferay.portal.kernel.templateparser.TemplateNode;
028    import com.liferay.portal.kernel.templateparser.TransformException;
029    import com.liferay.portal.kernel.util.StringBundler;
030    import com.liferay.portal.kernel.util.StringPool;
031    import com.liferay.portal.kernel.xml.Element;
032    import com.liferay.portal.util.PropsValues;
033    import com.liferay.portlet.portletdisplaytemplate.util.PortletDisplayTemplateConstants;
034    import com.liferay.taglib.util.VelocityTaglib;
035    import com.liferay.util.PwdGenerator;
036    
037    import java.net.URL;
038    
039    import java.util.ArrayList;
040    import java.util.HashMap;
041    import java.util.List;
042    import java.util.Map;
043    
044    /**
045     * @author Alexander Chow
046     * @author Brian Wing Shun Chan
047     * @author Raymond Augé
048     */
049    public class VelocityTemplateParser extends BaseTemplateParser {
050    
051            protected String getErrorTemplateId() {
052                    return PropsValues.JOURNAL_ERROR_TEMPLATE_VELOCITY;
053            }
054    
055            protected TemplateResource getErrorTemplateResource() {
056                    try {
057                            Class<?> clazz = getClass();
058    
059                            ClassLoader classLoader = clazz.getClassLoader();
060    
061                            URL url = classLoader.getResource(getErrorTemplateId());
062    
063                            return new URLTemplateResource(getErrorTemplateId(), url);
064                    }
065                    catch (Exception e) {
066                    }
067    
068                    return null;
069            }
070    
071            protected String getJournalTemplatesPath() {
072                    StringBundler sb = new StringBundler(5);
073    
074                    sb.append(TemplateConstants.JOURNAL_SEPARATOR);
075                    sb.append(StringPool.SLASH);
076                    sb.append(getCompanyId());
077                    sb.append(StringPool.SLASH);
078                    sb.append(getGroupId());
079    
080                    return sb.toString();
081            }
082    
083            @Override
084            protected TemplateContext getTemplateContext() throws Exception {
085                    TemplateResource templateResource = new StringTemplateResource(
086                            getTemplateId(), getScript());
087    
088                    return TemplateManagerUtil.getTemplate(
089                            TemplateConstants.LANG_TYPE_VM, templateResource,
090                            getErrorTemplateResource(), TemplateContextType.RESTRICTED);
091            }
092    
093            @Override
094            protected List<TemplateNode> getTemplateNodes(Element element)
095                    throws Exception {
096    
097                    List<TemplateNode> templateNodes = new ArrayList<TemplateNode>();
098    
099                    Map<String, TemplateNode> prototypeTemplateNodes =
100                            new HashMap<String, TemplateNode>();
101    
102                    List<Element> dynamicElementElements = element.elements(
103                            "dynamic-element");
104    
105                    for (Element dynamicElementElement : dynamicElementElements) {
106                            Element dynamicContentElement = dynamicElementElement.element(
107                                    "dynamic-content");
108    
109                            String data = StringPool.BLANK;
110    
111                            if (dynamicContentElement != null) {
112                                    data = dynamicContentElement.getText();
113                            }
114    
115                            String name = dynamicElementElement.attributeValue(
116                                    "name", StringPool.BLANK);
117    
118                            if (name.length() == 0) {
119                                    throw new TransformException(
120                                            "Element missing \"name\" attribute");
121                            }
122    
123                            String type = dynamicElementElement.attributeValue(
124                                    "type", StringPool.BLANK);
125    
126                            TemplateNode templateNode = new TemplateNode(
127                                    getThemeDisplay(), name, stripCDATA(data), type);
128    
129                            if (dynamicElementElement.element("dynamic-element") != null) {
130                                    templateNode.appendChildren(
131                                            getTemplateNodes(dynamicElementElement));
132                            }
133                            else if ((dynamicContentElement != null) &&
134                                             (dynamicContentElement.element("option") != null)) {
135    
136                                    List<Element> optionElements = dynamicContentElement.elements(
137                                            "option");
138    
139                                    for (Element optionElement : optionElements) {
140                                            templateNode.appendOption(
141                                                    stripCDATA(optionElement.getText()));
142                                    }
143                            }
144    
145                            TemplateNode prototypeTemplateNode = prototypeTemplateNodes.get(
146                                    name);
147    
148                            if (prototypeTemplateNode == null) {
149                                    prototypeTemplateNode = templateNode;
150    
151                                    prototypeTemplateNodes.put(name, prototypeTemplateNode);
152    
153                                    templateNodes.add(templateNode);
154                            }
155    
156                            prototypeTemplateNode.appendSibling(templateNode);
157                    }
158    
159                    return templateNodes;
160            }
161    
162            @Override
163            protected boolean mergeTemplate(
164                            TemplateContext templateContext,
165                            UnsyncStringWriter unsyncStringWriter)
166                    throws Exception {
167    
168                    Template template = (Template)templateContext;
169    
170                    VelocityTaglib velocityTaglib = (VelocityTaglib)template.get(
171                            PortletDisplayTemplateConstants.TAGLIB_LIFERAY);
172    
173                    if (velocityTaglib != null) {
174                            velocityTaglib.setTemplateContext(templateContext);
175                    }
176    
177                    return template.processTemplate(unsyncStringWriter);
178            }
179    
180            @Override
181            protected void populateTemplateContext(TemplateContext templateContext)
182                    throws Exception {
183    
184                    super.populateTemplateContext(templateContext);
185    
186                    templateContext.put("journalTemplatesPath", getJournalTemplatesPath());
187    
188                    String randomNamespace =
189                            PwdGenerator.getPassword(PwdGenerator.KEY3, 4) +
190                                    StringPool.UNDERLINE;
191    
192                    templateContext.put("randomNamespace", randomNamespace);
193            }
194    
195            protected String stripCDATA(String s) {
196                    if (s.startsWith(StringPool.CDATA_OPEN) &&
197                            s.endsWith(StringPool.CDATA_CLOSE)) {
198    
199                            s = s.substring(
200                                    StringPool.CDATA_OPEN.length(),
201                                    s.length() - StringPool.CDATA_CLOSE.length());
202                    }
203    
204                    return s;
205            }
206    
207    }