001/*
002 *  Copyright 2010 Anyware Services
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 */
016package org.ametys.site;
017
018import java.util.HashMap;
019import java.util.Iterator;
020import java.util.List;
021import java.util.Map;
022
023import org.apache.avalon.framework.parameters.Parameters;
024import org.apache.avalon.framework.service.ServiceException;
025import org.apache.avalon.framework.service.ServiceManager;
026import org.apache.avalon.framework.thread.ThreadSafe;
027import org.apache.cocoon.acting.ServiceableAction;
028import org.apache.cocoon.environment.ObjectModelHelper;
029import org.apache.cocoon.environment.PermanentRedirector;
030import org.apache.cocoon.environment.Redirector;
031import org.apache.cocoon.environment.Request;
032import org.apache.cocoon.environment.Response;
033import org.apache.cocoon.environment.SourceResolver;
034import org.apache.commons.lang3.StringUtils;
035import org.apache.excalibur.source.SourceNotFoundException;
036
037import org.ametys.plugins.site.Site;
038import org.ametys.plugins.site.SiteInformationCache;
039import org.ametys.plugins.site.SiteUrl;
040
041/**
042 * Get the site from server path, port and path.
043 */
044public class GetSiteAction extends ServiceableAction implements ThreadSafe
045{
046    private SiteInformationCache _siteCache;
047    
048    @Override
049    public void service(ServiceManager sManager) throws ServiceException
050    {
051        super.service(sManager);
052        _siteCache = (SiteInformationCache) sManager.lookup(SiteInformationCache.ROLE);
053    }
054    
055    @Override
056    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception
057    {
058        Request request = ObjectModelHelper.getRequest(objectModel);
059        Response response = ObjectModelHelper.getResponse(objectModel);
060        
061        String frontServer = request.getServerName();
062        String frontPort = String.valueOf(request.getServerPort());
063        String frontPath = request.getRequestURI();
064        
065        frontPath = frontPath.endsWith("/") ? frontPath.substring(0, frontPath.length() - 1) : frontPath;
066
067        Map<SiteUrl, Site> sites = _siteCache.getSites();
068        Iterator<SiteUrl> it = sites.keySet().iterator();
069        
070        Site result = null;
071        String pathInSite = null;
072        String path = null;
073        
074        while (result == null && it.hasNext())
075        {
076            SiteUrl url = it.next();
077            Site site = sites.get(url);
078            String serverName = url.getServerName();
079            String port = url.getServerPort();
080            path = url.getServerPath();
081            path = path.endsWith("/") ? path.substring(0, path.length() - 1) : path;
082
083            if (serverName.equals(frontServer) && frontPort.equals(port) && frontPath.startsWith(path))
084            {
085                // same server and port, the path starts with the configured context, the current site is eligible
086                result = site;
087                pathInSite = frontPath.equals(path) ? "" : frontPath.substring(path.length() + 1);
088                
089                if (frontPath.equals(path) || "index.html".equals(pathInSite))
090                {
091                    // root was requested
092                    List<String> languages = site.getLanguages();
093                    
094                    String language = _findLanguage(request, languages);
095                    
096                    String redirectURI = url.getServerPath() + "/" + language + "/index.html";
097                    
098                    if (redirector instanceof PermanentRedirector)
099                    {
100                        ((PermanentRedirector) redirector).permanentRedirect(false, redirectURI);
101                        response.setHeader("Cache-Control", "no-cache");
102                    }
103                    else
104                    {
105                        redirector.redirect(false, redirectURI);
106                    }
107                    
108                    return null;
109                }
110
111                request.setAttribute("site", result);
112                request.setAttribute("url", url);
113                request.setAttribute("path", pathInSite);
114                request.setAttribute("requestedURI", request.getRequestURI());
115            }
116        }
117        
118        if (result == null)
119        {
120            throw new SourceNotFoundException("There's no site registrered in the cms for url http(s)://" + frontServer + ":" + frontPort + frontPath + "/");
121        }
122        
123        HashMap<String, String> map = new HashMap<>();
124        map.put("site", result.getName());
125        map.put("path", pathInSite);
126        
127        String p = path;
128        p = StringUtils.removeStart(p, request.getContextPath());
129        p = StringUtils.removeStart(p, "/");
130        map.put("sitePath", StringUtils.isBlank(p) ? "" : (p + "/"));
131        return map;
132    }
133    
134    private String _findLanguage(Request request, List<String> availableLanguages)
135    {
136        String requestLanguage = request.getLocale().getLanguage();
137        
138        return availableLanguages.contains(requestLanguage) ? requestLanguage : availableLanguages.contains("en") ? "en" : availableLanguages.get(0);
139    }
140}