001/*
002 * (C) Copyright 2006-2007 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Jean-Marc Orliaguet, Chalmers
018 *
019 * $Id$
020 */
021
022package org.nuxeo.theme.html.ui;
023
024import java.net.MalformedURLException;
025import java.net.URL;
026import java.util.List;
027import java.util.Map;
028
029import org.apache.commons.logging.Log;
030import org.apache.commons.logging.LogFactory;
031import org.nuxeo.ecm.platform.web.common.vh.VirtualHostHelper;
032import org.nuxeo.theme.Manager;
033import org.nuxeo.theme.resources.ResourceManager;
034
035public class Resources {
036
037    private static final Log log = LogFactory.getLog(Resources.class);
038
039    public static String render(Map<String, String> params, boolean virtualHosting) {
040        StringBuilder sb = new StringBuilder();
041
042        String resourcePath = VirtualHostHelper.getContextPathProperty() + "/nxthemes-lib/";
043        final String themeUrl = params.get("themeUrl");
044        final String path = params.get("path");
045        final String basepath = params.get("basepath");
046        String nxthemeBasePath = basepath;
047
048        final ResourceManager resourceManager = Manager.getResourceManager();
049
050        final StringBuilder combinedStyles = new StringBuilder();
051        final StringBuilder combinedScripts = new StringBuilder();
052        combinedStyles.append(resourcePath);
053        combinedScripts.append(resourcePath);
054
055        boolean hasScripts = false;
056        boolean hasStyles = false;
057
058        boolean ignoreLocal = false;
059        if (params.containsKey("ignoreLocal")) {
060            ignoreLocal = Boolean.parseBoolean(params.get("ignoreLocal"));
061        }
062
063        List<String> resourceNames;
064        if (ignoreLocal) {
065            resourceNames = resourceManager.getGlobalResourcesFor(themeUrl);
066        } else {
067            resourceNames = resourceManager.getResourcesFor(themeUrl);
068        }
069
070        for (String resourceName : resourceNames) {
071            if (resourceName.endsWith(".css")) {
072                combinedStyles.append(resourceName).append(",");
073                hasStyles = true;
074            } else if (resourceName.endsWith(".js")) {
075                combinedScripts.append(resourceName).append(",");
076                hasScripts = true;
077            }
078        }
079
080        combinedStyles.deleteCharAt(combinedStyles.length() - 1);
081        combinedScripts.deleteCharAt(combinedScripts.length() - 1);
082
083        long timestamp = getTimestamp(themeUrl);
084        combinedStyles.append("?path=").append(path).append("&amp;basepath=").append(basepath).append("&amp;timestamp=").append(
085                timestamp);
086        combinedScripts.append("?path=").append(path).append("&amp;basepath=").append(basepath).append(
087                "&amp;timestamp=").append(timestamp);
088
089        // styles
090        if (hasStyles) {
091            sb.append(String.format("<link type=\"text/css\" rel=\"stylesheet\" media=\"all\" href=\"%s\"/>",
092                    combinedStyles.toString()));
093        }
094
095        final String contextPath = params.get("contextPath");
096        // scripts
097        sb.append(String.format("<script type=\"text/javascript\"><!--\n" + "var nxthemesPath = \"%s\";\n"
098                + "var nxthemesBasePath = \"%s\";\n" + "var nxContextPath = \"%s\";\n" + "//--></script>\n", path,
099                nxthemeBasePath, contextPath));
100        if (hasScripts) {
101            sb.append(String.format("<script type=\"text/javascript\" src=\"%s\"></script>", combinedScripts.toString()));
102        }
103
104        // Flush local resources
105        resourceManager.flush();
106        return sb.toString();
107    }
108
109    /**
110     * Return the timestamp to use for resources URL, useful to work-around caching when hot-reloading theme resources.
111     *
112     * @since 5.6
113     * @param themeUrl
114     */
115    protected static long getTimestamp(String themeUrl) {
116        long timestamp = 0;
117        if (themeUrl != null) {
118            try {
119                Long val = Manager.getThemeManager().getLastModified(new URL(themeUrl));
120                if (val != null) {
121                    timestamp = val.longValue();
122                }
123            } catch (MalformedURLException e) {
124                log.warn(String.format("Error while generating last modified" + " timestamp for theme url '%s'",
125                        themeUrl), e);
126            }
127        }
128        return timestamp;
129    }
130}