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.portal.velocity;
016    
017    import com.liferay.portal.kernel.template.Template;
018    import com.liferay.portal.kernel.template.TemplateConstants;
019    import com.liferay.portal.kernel.template.TemplateContextType;
020    import com.liferay.portal.kernel.template.TemplateException;
021    import com.liferay.portal.kernel.template.TemplateManager;
022    import com.liferay.portal.kernel.template.TemplateResource;
023    import com.liferay.portal.kernel.util.PropsKeys;
024    import com.liferay.portal.kernel.util.StringUtil;
025    import com.liferay.portal.template.PACLTemplateWrapper;
026    import com.liferay.portal.template.RestrictedTemplate;
027    import com.liferay.portal.template.TemplateContextHelper;
028    import com.liferay.portal.util.PropsUtil;
029    import com.liferay.portal.util.PropsValues;
030    
031    import java.util.Map;
032    
033    import org.apache.commons.collections.ExtendedProperties;
034    import org.apache.velocity.VelocityContext;
035    import org.apache.velocity.app.VelocityEngine;
036    import org.apache.velocity.runtime.RuntimeConstants;
037    import org.apache.velocity.util.introspection.SecureUberspector;
038    
039    /**
040     * @author Raymond Augé
041     */
042    public class VelocityManager implements TemplateManager {
043    
044            public void destroy() {
045                    if (_velocityEngine == null) {
046                            return;
047                    }
048    
049                    _velocityEngine = null;
050    
051                    _templateContextHelper.removeAllHelperUtilities();
052    
053                    _templateContextHelper = null;
054            }
055    
056            public void destroy(ClassLoader classLoader) {
057                    _templateContextHelper.removeHelperUtilities(classLoader);
058            }
059    
060            public String getName() {
061                    return TemplateConstants.LANG_TYPE_VM;
062            }
063    
064            public Template getTemplate(
065                    TemplateResource templateResource,
066                    TemplateContextType templateContextType) {
067    
068                    return getTemplate(templateResource, null, templateContextType);
069            }
070    
071            public Template getTemplate(
072                    TemplateResource templateResource,
073                    TemplateResource errorTemplateResource,
074                    TemplateContextType templateContextType) {
075    
076                    Template template = null;
077    
078                    VelocityContext velocityContext = getVelocityContext(
079                            templateContextType);
080    
081                    if (templateContextType.equals(TemplateContextType.EMPTY)) {
082                            template = new VelocityTemplate(
083                                    templateResource, errorTemplateResource, null, _velocityEngine,
084                                    _templateContextHelper);
085                    }
086                    else if (templateContextType.equals(TemplateContextType.RESTRICTED)) {
087                            template = new RestrictedTemplate(
088                                    new VelocityTemplate(
089                                            templateResource, errorTemplateResource, velocityContext,
090                                            _velocityEngine, _templateContextHelper),
091                                    _templateContextHelper.getRestrictedVariables());
092                    }
093                    else if (templateContextType.equals(TemplateContextType.STANDARD)) {
094                            template = new VelocityTemplate(
095                                    templateResource, errorTemplateResource, velocityContext,
096                                    _velocityEngine, _templateContextHelper);
097                    }
098    
099                    return PACLTemplateWrapper.getTemplate(template);
100            }
101    
102            public void init() throws TemplateException {
103                    if (_velocityEngine != null) {
104                            return;
105                    }
106    
107                    _velocityEngine = new VelocityEngine();
108    
109                    ExtendedProperties extendedProperties = new FastExtendedProperties();
110    
111                    extendedProperties.setProperty(
112                            VelocityEngine.EVENTHANDLER_METHODEXCEPTION,
113                            LiferayMethodExceptionEventHandler.class.getName());
114    
115                    extendedProperties.setProperty(
116                            RuntimeConstants.INTROSPECTOR_RESTRICT_CLASSES,
117                            StringUtil.merge(PropsValues.VELOCITY_ENGINE_RESTRICTED_CLASSES));
118    
119                    extendedProperties.setProperty(
120                            RuntimeConstants.INTROSPECTOR_RESTRICT_PACKAGES,
121                            StringUtil.merge(PropsValues.VELOCITY_ENGINE_RESTRICTED_PACKAGES));
122    
123                    extendedProperties.setProperty(
124                            VelocityEngine.RESOURCE_LOADER, "liferay");
125    
126                    boolean cacheEnabled = false;
127    
128                    if (PropsValues.VELOCITY_ENGINE_RESOURCE_MODIFICATION_CHECK_INTERVAL !=
129                                    0) {
130    
131                            cacheEnabled = true;
132                    }
133    
134                    extendedProperties.setProperty(
135                            "liferay." + VelocityEngine.RESOURCE_LOADER + ".cache",
136                            String.valueOf(cacheEnabled));
137    
138                    extendedProperties.setProperty(
139                            "liferay." + VelocityEngine.RESOURCE_LOADER + ".class",
140                            LiferayResourceLoader.class.getName());
141    
142                    extendedProperties.setProperty(
143                            VelocityEngine.RESOURCE_MANAGER_CLASS,
144                            LiferayResourceManager.class.getName());
145    
146                    extendedProperties.setProperty(
147                            VelocityEngine.RUNTIME_LOG_LOGSYSTEM_CLASS,
148                            PropsUtil.get(PropsKeys.VELOCITY_ENGINE_LOGGER));
149    
150                    extendedProperties.setProperty(
151                            VelocityEngine.RUNTIME_LOG_LOGSYSTEM + ".log4j.category",
152                            PropsUtil.get(PropsKeys.VELOCITY_ENGINE_LOGGER_CATEGORY));
153    
154                    extendedProperties.setProperty(
155                            RuntimeConstants.UBERSPECT_CLASSNAME,
156                            SecureUberspector.class.getName());
157    
158                    extendedProperties.setProperty(
159                            VelocityEngine.VM_LIBRARY,
160                            PropsUtil.get(PropsKeys.VELOCITY_ENGINE_VELOCIMACRO_LIBRARY));
161    
162                    extendedProperties.setProperty(
163                            VelocityEngine.VM_LIBRARY_AUTORELOAD, String.valueOf(cacheEnabled));
164    
165                    extendedProperties.setProperty(
166                            VelocityEngine.VM_PERM_ALLOW_INLINE_REPLACE_GLOBAL,
167                            String.valueOf(cacheEnabled));
168    
169                    _velocityEngine.setExtendedProperties(extendedProperties);
170    
171                    try {
172                            _velocityEngine.init();
173                    }
174                    catch (Exception e) {
175                            throw new TemplateException(e);
176                    }
177            }
178    
179            public void setTemplateContextHelper(
180                    TemplateContextHelper templateContextHelper) {
181    
182                    _templateContextHelper = templateContextHelper;
183            }
184    
185            protected VelocityContext getVelocityContext(
186                    TemplateContextType templateContextType) {
187    
188                    VelocityContext velocityContext = new VelocityContext();
189    
190                    Map<String, Object> helperUtilities =
191                            _templateContextHelper.getHelperUtilities(templateContextType);
192    
193                    for (Map.Entry<String, Object> entry : helperUtilities.entrySet()) {
194                            velocityContext.put(entry.getKey(), entry.getValue());
195                    }
196    
197                    return velocityContext;
198            }
199    
200            private TemplateContextHelper _templateContextHelper;
201            private VelocityEngine _velocityEngine;
202    
203    }