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.freemarker;
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.ReflectionUtil;
023    import com.liferay.portal.kernel.util.StringPool;
024    import com.liferay.portal.template.BaseTemplateManager;
025    import com.liferay.portal.template.RestrictedTemplate;
026    import com.liferay.portal.util.PropsValues;
027    
028    import freemarker.cache.TemplateCache;
029    
030    import freemarker.debug.impl.DebuggerService;
031    
032    import freemarker.template.Configuration;
033    
034    import java.lang.reflect.Field;
035    
036    import java.util.Map;
037    
038    /**
039     * @author Mika Koivisto
040     * @author Tina Tina
041     */
042    @DoPrivileged
043    public class FreeMarkerManager extends BaseTemplateManager {
044    
045            @Override
046            public void destroy() {
047                    if (_configuration == null) {
048                            return;
049                    }
050    
051                    _configuration.clearEncodingMap();
052                    _configuration.clearSharedVariables();
053                    _configuration.clearTemplateCache();
054    
055                    _configuration = null;
056    
057                    templateContextHelper.removeAllHelperUtilities();
058    
059                    templateContextHelper = null;
060    
061                    if (isEnableDebuggerService()) {
062                            DebuggerService.shutdown();
063                    }
064            }
065    
066            @Override
067            public void destroy(ClassLoader classLoader) {
068                    templateContextHelper.removeHelperUtilities(classLoader);
069            }
070    
071            @Override
072            public String getName() {
073                    return TemplateConstants.LANG_TYPE_FTL;
074            }
075    
076            @Override
077            public void init() throws TemplateException {
078                    if (_configuration != null) {
079                            return;
080                    }
081    
082                    _configuration = new Configuration();
083    
084                    try {
085                            Field field = ReflectionUtil.getDeclaredField(
086                                    Configuration.class, "cache");
087    
088                            TemplateCache templateCache = new LiferayTemplateCache(
089                                    _configuration);
090    
091                            field.set(_configuration, templateCache);
092                    }
093                    catch (Exception e) {
094                            throw new TemplateException(
095                                    "Unable to Initialize Freemarker manager");
096                    }
097    
098                    _configuration.setDefaultEncoding(StringPool.UTF8);
099                    _configuration.setLocalizedLookup(
100                            PropsValues.FREEMARKER_ENGINE_LOCALIZED_LOOKUP);
101                    _configuration.setNewBuiltinClassResolver(
102                            new LiferayTemplateClassResolver());
103                    _configuration.setObjectWrapper(new LiferayObjectWrapper());
104    
105                    try {
106                            _configuration.setSetting(
107                                    "auto_import", PropsValues.FREEMARKER_ENGINE_MACRO_LIBRARY);
108                            _configuration.setSetting(
109                                    "template_exception_handler",
110                                    PropsValues.FREEMARKER_ENGINE_TEMPLATE_EXCEPTION_HANDLER);
111                    }
112                    catch (Exception e) {
113                            throw new TemplateException("Unable to init freemarker manager", e);
114                    }
115    
116                    if (isEnableDebuggerService()) {
117                            DebuggerService.getBreakpoints("*");
118                    }
119            }
120    
121            @Override
122            protected Template doGetTemplate(
123                    TemplateResource templateResource,
124                    TemplateResource errorTemplateResource, boolean restricted,
125                    Map<String, Object> helperUtilities, boolean privileged) {
126    
127                    Template template = new FreeMarkerTemplate(
128                            templateResource, errorTemplateResource, helperUtilities,
129                            _configuration, templateContextHelper, privileged);
130    
131                    if (restricted) {
132                            template = new RestrictedTemplate(
133                                    template, templateContextHelper.getRestrictedVariables());
134                    }
135    
136                    return template;
137            }
138    
139            protected boolean isEnableDebuggerService() {
140                    if ((System.getProperty("freemarker.debug.password") != null) &&
141                            (System.getProperty("freemarker.debug.port") != null)) {
142    
143                            return true;
144                    }
145    
146                    return false;
147            }
148    
149            private Configuration _configuration;
150    
151    }