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