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