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.deploy.sandbox.SandboxHandler;
018    import com.liferay.portal.kernel.util.PropsKeys;
019    import com.liferay.portal.kernel.util.ReflectionUtil;
020    import com.liferay.portal.util.PropsUtil;
021    
022    import java.io.IOException;
023    
024    import java.lang.reflect.Field;
025    
026    import java.security.AccessController;
027    import java.security.PrivilegedActionException;
028    import java.security.PrivilegedExceptionAction;
029    
030    import org.apache.commons.collections.ExtendedProperties;
031    import org.apache.velocity.runtime.RuntimeInstance;
032    import org.apache.velocity.runtime.RuntimeServices;
033    import org.apache.velocity.runtime.resource.Resource;
034    import org.apache.velocity.runtime.resource.ResourceManager;
035    import org.apache.velocity.runtime.resource.ResourceManagerImpl;
036    
037    /**
038     * @author Brian Wing Shun Chan
039     * @author Shuyang Zhou
040     */
041    public class LiferayResourceManager extends ResourceManagerImpl {
042    
043            @Override
044            public String getLoaderNameForResource(String source) {
045    
046                    // Velocity's default implementation makes its cache useless because
047                    // getResourceStream is called to test the availability of a template
048    
049                    if ((globalCache.get(ResourceManager.RESOURCE_CONTENT + source) !=
050                                    null) ||
051                            (globalCache.get(ResourceManager.RESOURCE_TEMPLATE + source) !=
052                                    null)) {
053    
054                            return LiferayResourceLoader.class.getName();
055                    }
056                    else {
057                            return super.getLoaderNameForResource(source);
058                    }
059            }
060    
061            @Override
062            public Resource getResource(
063                            String resourceName, int resourceType, String encoding)
064                    throws Exception {
065    
066                    String[] macroTemplateIds = PropsUtil.getArray(
067                            PropsKeys.VELOCITY_ENGINE_VELOCIMACRO_LIBRARY);
068    
069                    for (String macroTemplateId : macroTemplateIds) {
070                            if (resourceName.equals(macroTemplateId)) {
071    
072                                    // This resource is provided by the portal, so invoke it from an
073                                    // access controller
074    
075                                    try {
076                                            return AccessController.doPrivileged(
077                                                    new ResourcePrivilegedExceptionAction(
078                                                            resourceName, resourceType, encoding));
079                                    }
080                                    catch (PrivilegedActionException pae) {
081                                            throw (IOException)pae.getException();
082                                    }
083                            }
084                    }
085    
086                    return doGetResource(resourceName, resourceType, encoding);
087            }
088    
089            @Override
090            public synchronized void initialize(RuntimeServices runtimeServices)
091                    throws Exception {
092    
093                    ExtendedProperties extendedProperties =
094                            runtimeServices.getConfiguration();
095    
096                    Field field = ReflectionUtil.getDeclaredField(
097                            RuntimeInstance.class, "configuration");
098    
099                    field.set(
100                            runtimeServices, new FastExtendedProperties(extendedProperties));
101    
102                    super.initialize(runtimeServices);
103            }
104    
105            private Resource doGetResource(
106                            String resourceName, int resourceType, String encoding)
107                    throws Exception {
108    
109                    if (resourceName.contains(SandboxHandler.SANDBOX_MARKER)) {
110                            return loadResource(resourceName, resourceType, encoding);
111                    }
112                    else {
113                            return super.getResource(resourceName, resourceType, encoding);
114                    }
115            }
116    
117            private class ResourcePrivilegedExceptionAction
118                    implements PrivilegedExceptionAction<Resource> {
119    
120                    public ResourcePrivilegedExceptionAction(
121                            String resourceName, int resourceType, String encoding) {
122    
123                            _resourceName = resourceName;
124                            _resourceType = resourceType;
125                            _encoding = encoding;
126                    }
127    
128                    @Override
129                    public Resource run() throws Exception {
130                            return doGetResource(_resourceName, _resourceType, _encoding);
131                    }
132    
133                    private String _encoding;
134                    private String _resourceName;
135                    private int _resourceType;
136    
137            }
138    
139    }