001/*
002 *  Copyright 2011 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 */
016
017package org.ametys.web;
018
019import org.apache.avalon.framework.component.Component;
020import org.apache.avalon.framework.context.Context;
021import org.apache.avalon.framework.context.ContextException;
022import org.apache.avalon.framework.context.Contextualizable;
023import org.apache.avalon.framework.service.ServiceException;
024import org.apache.avalon.framework.service.ServiceManager;
025import org.apache.avalon.framework.service.Serviceable;
026import org.apache.cocoon.components.ContextHelper;
027import org.apache.cocoon.environment.Request;
028import org.apache.commons.lang.StringUtils;
029
030import org.ametys.runtime.workspace.WorkspaceMatcher;
031import org.ametys.web.renderingcontext.RenderingContext;
032import org.ametys.web.renderingcontext.RenderingContextHandler;
033import org.ametys.web.repository.site.Site;
034import org.ametys.web.repository.site.SiteManager;
035
036/**
037 * Component providing base paths for computing URIs.
038 */
039public class URIPrefixHandler implements Serviceable, Contextualizable, Component
040{
041    /** Avalon role */
042    public static final String ROLE = URIPrefixHandler.class.getName();
043    
044    private RenderingContextHandler _renderingContexthandler;
045    private SiteManager _siteManager;
046    private Context _context;
047    
048    @Override
049    public void contextualize(Context context) throws ContextException
050    {
051        _context = context;
052    }
053    
054    @Override
055    public void service(ServiceManager manager) throws ServiceException
056    {
057        _renderingContexthandler = (RenderingContextHandler) manager.lookup(RenderingContextHandler.ROLE);
058        _siteManager = (SiteManager) manager.lookup(SiteManager.ROLE);
059    }
060    
061    /**
062     * Get the application context path. Can be empty if the application
063     * resides in the root context. Use it to create a link beginning with
064     * the application root.
065     * @return The application context path.
066     * @see Request#getContextPath()
067     */
068    public String getUriPrefix()
069    {
070        Request request = ContextHelper.getRequest(_context);
071        String prefix = (String) request.getAttribute(WebConstants.PATH_PREFIX);
072        String workspaceURI = (String) request.getAttribute(WorkspaceMatcher.WORKSPACE_URI);
073        
074        // _contextPath is set by the front-office or in certain particular cases to force FO-like links.
075        String externalContextPath = request.getParameter("_contextPath"); 
076        if (externalContextPath == null)
077        {
078            externalContextPath = (String) request.getAttribute("_contextPath");
079        }
080        
081        if (externalContextPath != null)
082        {
083            return externalContextPath;
084        }
085        else
086        {
087            return request.getContextPath() + workspaceURI + StringUtils.trimToEmpty(prefix);
088        }
089    }
090
091    
092    /**
093     * Get the full path to the workspace with site name.
094     * If the current workspace is the default one, the workspace path part will be empty.
095     * Use it when creating site-dependent links, such as page URIs.
096     * @param siteName the current site name.
097     * @return The workspace context path with site name.
098     */
099    public String getUriPrefix(String siteName)
100    {
101        if (_renderingContexthandler.getRenderingContext() == RenderingContext.FRONT)
102        {
103            return getUriPrefix();
104        }
105        
106        return getUriPrefix() + "/" + siteName;
107    }
108    
109    /**
110     * Get the absolutized version of the context path. Use it to create an absolute
111     * link beginning with the application root, for instance when sending a mail
112     * linking to the application.
113     * @return The absolute context path.
114     */
115    public String getAbsoluteUriPrefix()
116    {
117        Request request = ContextHelper.getRequest(_context);
118        
119        // _baseServerPath is set by the front-office or in certain particular cases to force FO-like links.
120        String baseServerPath = request.getParameter("_baseServerPath");
121        if (baseServerPath == null)
122        {
123            baseServerPath = (String) request.getAttribute("_baseServerPath");
124        }
125        
126        String uriPrefix = getUriPrefix();
127        
128        if (StringUtils.isNotEmpty(baseServerPath))
129        {
130            uriPrefix = baseServerPath + uriPrefix;
131        }
132        
133        if (!uriPrefix.startsWith("http"))
134        {
135            uriPrefix = request.getScheme() + "://" + request.getServerName() + (request.getServerPort() != 80 ? ":" + request.getServerPort() : "") + uriPrefix;
136        }
137        
138        return uriPrefix;
139    }
140    
141    /**
142     * Get an absolutized version of the workspace context path. Use it when
143     * linking to a page or an URI from outside the server, for instance when
144     * sending a link to a specific page in an e-mail.
145     * @param siteName The name of the current site.
146     * @return The absolute workspace context path.
147     */
148    public String getAbsoluteUriPrefix(String siteName)
149    {
150        if (_renderingContexthandler.getRenderingContext() == RenderingContext.FRONT)
151        {
152            Site site = _siteManager.getSite(siteName);
153            return site.getUrl();
154        }
155        
156        return getAbsoluteUriPrefix() + "/" + siteName; 
157    }
158}