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.thread.ThreadSafe; 026import org.apache.cocoon.acting.ServiceableAction; 027import org.apache.cocoon.environment.ObjectModelHelper; 028import org.apache.cocoon.environment.PermanentRedirector; 029import org.apache.cocoon.environment.Redirector; 030import org.apache.cocoon.environment.Request; 031import org.apache.cocoon.environment.Response; 032import org.apache.cocoon.environment.SourceResolver; 033import org.apache.commons.lang3.StringUtils; 034import org.apache.excalibur.source.SourceNotFoundException; 035 036import org.ametys.plugins.site.Site; 037import org.ametys.plugins.site.SiteInformationCache; 038import org.ametys.plugins.site.SiteUrl; 039 040/** 041 * Get the site from server path, port and path. 042 */ 043public class GetSiteAction extends ServiceableAction implements ThreadSafe 044{ 045 /** 046 * sub_path in the uri to indicate the edition mode, and parameter passed to back 047 */ 048 public static final String EDITION_URI = "edition"; 049 050 private SiteInformationCache _siteCache; 051 052 /** 053 * Get the site information cache 054 * @return the SiteInformationCache 055 */ 056 protected SiteInformationCache _getSiteInformationCache() 057 { 058 if (_siteCache == null) 059 { 060 try 061 { 062 _siteCache = (SiteInformationCache) manager.lookup(SiteInformationCache.ROLE); 063 } 064 catch (ServiceException e) 065 { 066 throw new IllegalStateException("Cannot get SiteInformationCache", e); 067 } 068 } 069 return _siteCache; 070 } 071 072 @Override 073 public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception 074 { 075 Request request = ObjectModelHelper.getRequest(objectModel); 076 Response response = ObjectModelHelper.getResponse(objectModel); 077 078 String frontServer = request.getServerName(); 079 String frontPort = String.valueOf(request.getServerPort()); 080 String frontPath = request.getRequestURI(); 081 082 frontPath = frontPath.endsWith("/") ? frontPath.substring(0, frontPath.length() - 1) : frontPath; 083 084 Map<SiteUrl, Site> sites = _getSiteInformationCache().getSites(); 085 Iterator<SiteUrl> it = sites.keySet().iterator(); 086 087 Site result = null; 088 String pathInSite = null; 089 String path = null; 090 HashMap<String, String> map = new HashMap<>(); 091 092 while (result == null && it.hasNext()) 093 { 094 SiteUrl url = it.next(); 095 Site site = sites.get(url); 096 String serverName = url.getServerName(); 097 String port = url.getServerPort(); 098 path = url.getServerPath(); 099 path = path.endsWith("/") ? path.substring(0, path.length() - 1) : path; 100 101 if (serverName.equals(frontServer) && frontPort.equals(port) && frontPath.startsWith(path)) 102 { 103 // same server and port, the path starts with the configured context, the current site is eligible 104 result = site; 105 pathInSite = frontPath.equals(path) ? "" : frontPath.substring(path.length() + 1); 106 107 if (frontPath.equals(path) || "index.html".equals(pathInSite)) 108 { 109 // root was requested 110 List<String> languages = site.getLanguages(); 111 112 String language = _findLanguage(request, languages); 113 114 String redirectURI = url.getServerPath() + "/" + language + "/index.html"; 115 116 if (redirector instanceof PermanentRedirector) 117 { 118 ((PermanentRedirector) redirector).permanentRedirect(false, redirectURI); 119 response.setHeader("Cache-Control", "no-cache"); 120 } 121 else 122 { 123 redirector.redirect(false, redirectURI); 124 } 125 126 return null; 127 } 128 129 if (pathInSite.startsWith(EDITION_URI + "/")) 130 { 131 url = new SiteUrl(url.getServerName(), url.getServerPort(), url.getServerPath() + "/" + EDITION_URI); 132 path += "/" + EDITION_URI; 133 pathInSite = pathInSite.substring(EDITION_URI.length() + 1); 134 135 request.setAttribute(EDITION_URI, "true"); 136 } 137 138 request.setAttribute("site", result); 139 request.setAttribute("url", url); 140 request.setAttribute("path", pathInSite); 141 request.setAttribute("requestedURI", request.getRequestURI()); 142 } 143 } 144 145 if (result == null) 146 { 147 throw new SourceNotFoundException("There's no site registered in the cms for url http(s)://" + frontServer + ":" + frontPort + frontPath + "/"); 148 } 149 150 map.put("site", result.getName()); 151 map.put("path", pathInSite); 152 153 String p = path; 154 p = StringUtils.removeStart(p, request.getContextPath()); 155 p = StringUtils.removeStart(p, "/"); 156 p = StringUtils.isBlank(p) ? "" : (p + "/"); 157 map.put("sitePath", p); 158 request.setAttribute("sitePath", p); 159 160 return map; 161 } 162 163 private String _findLanguage(Request request, List<String> availableLanguages) 164 { 165 String requestLanguage = request.getLocale().getLanguage(); 166 167 return availableLanguages.contains(requestLanguage) ? requestLanguage : availableLanguages.contains("en") ? "en" : availableLanguages.get(0); 168 } 169}