org.opencms.file.CmsRequestContext Maven / Gradle / Ivy
Show all versions of opencms-core Show documentation
/*
* This library is part of OpenCms -
* the Open Source Content Management System
*
* Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* For further information about Alkacon Software GmbH & Co. KG, please see the
* company website: http://www.alkacon.com
*
* For further information about OpenCms, please see the
* project website: http://www.opencms.org
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.opencms.file;
import org.opencms.main.CmsIllegalArgumentException;
import org.opencms.main.OpenCms;
import org.opencms.security.CmsOrganizationalUnit;
import org.opencms.site.CmsSiteMatcher;
import org.opencms.util.CmsResourceTranslator;
import org.opencms.util.CmsUUID;
import org.opencms.workplace.CmsWorkplace;
import java.util.Hashtable;
import java.util.Locale;
import java.util.Map;
/**
* Stores the information about the current users OpenCms context,
* for example the requested URI, the current project, the selected site and more.
*
* @since 6.0.0
*/
public final class CmsRequestContext {
/** Request context attribute for indicating that an editor is currently open. */
public static final String ATTRIBUTE_EDITOR = CmsRequestContext.class.getName() + ".ATTRIBUTE_EDITOR";
/** Request context attribute for indicating we want full links generated for HTML fields. */
public static final String ATTRIBUTE_FULLLINKS = CmsRequestContext.class.getName() + ".ATTRIBUTE_FULLLINKS";
/** Request context attribute for indicating the model file for a create resource operation. */
public static final String ATTRIBUTE_MODEL = CmsRequestContext.class.getName() + ".ATTRIBUTE_MODEL";
/** Request context attribute for the ADE context path. */
public static final String ATTRIBUTE_ADE_CONTEXT_PATH = CmsRequestContext.class.getName() + ".ADE_CONTEXT_PATH";
/** Request context attribute for indicating content locale for a create resource operation. */
public static final String ATTRIBUTE_NEW_RESOURCE_LOCALE = CmsRequestContext.class.getName()
+ ".NEW_RESOURCE_LOCALE";
/** A map for storing (optional) request context attributes. */
private Map m_attributeMap;
/** The current project. */
private CmsProject m_currentProject;
/** The detail content resource (possibly null). */
private CmsResource m_detailResource;
/** Directory name translator. */
private CmsResourceTranslator m_directoryTranslator;
/** Current encoding. */
private String m_encoding;
/** File name translator. */
private CmsResourceTranslator m_fileTranslator;
/** Flag to control whether links should be absolute even if we're linking to the current site. */
private boolean m_forceAbsoluteLinks;
/** The secure request flag. */
private boolean m_isSecureRequest;
/** The locale used by this request context. */
private Locale m_locale;
/** The fully qualified name of the organizational unit for this request. */
private String m_ouFqn;
/** The remote ip address. */
private String m_remoteAddr;
/** the matcher for the current request, that is the host part of the URI from the original http request. */
private CmsSiteMatcher m_requestMatcher;
/** The current request time. */
private long m_requestTime;
/** The name of the root, e.g. /site_a/vfs. */
private String m_siteRoot;
/** Flag to indicate that this context should not update the user session. */
private boolean m_updateSession;
/** The URI for getUri() in case it is "overwritten". */
private String m_uri;
/** The current user. */
private CmsUser m_user;
/**
* Constructs a new request context.
*
* @param user the current user
* @param project the current project
* @param requestedUri the requested OpenCms VFS URI
* @param requestMatcher the matcher for the current request, that is the host part of the URI from the original http request
* @param siteRoot the users current site root
* @param isSecureRequest true if this is a secure request
* @param locale the users current locale
* @param encoding the encoding to use for this request
* @param remoteAddr the remote IP address of the user
* @param requestTime the time of the request (used for resource publication / expiration date)
* @param directoryTranslator the directory translator
* @param fileTranslator the file translator
* @param ouFqn the fully qualified name of the organizational unit
* @param forceAbsoluteLinks if true, links should be generated with a server prefix even if we're linking to the current site
*/
public CmsRequestContext(
CmsUser user,
CmsProject project,
String requestedUri,
CmsSiteMatcher requestMatcher,
String siteRoot,
boolean isSecureRequest,
Locale locale,
String encoding,
String remoteAddr,
long requestTime,
CmsResourceTranslator directoryTranslator,
CmsResourceTranslator fileTranslator,
String ouFqn,
boolean forceAbsoluteLinks) {
m_updateSession = true;
m_user = user;
m_currentProject = project;
m_uri = requestedUri;
m_requestMatcher = requestMatcher;
m_isSecureRequest = isSecureRequest;
setSiteRoot(siteRoot);
m_locale = locale;
m_encoding = encoding;
m_remoteAddr = remoteAddr;
m_requestTime = requestTime;
m_directoryTranslator = directoryTranslator;
m_fileTranslator = fileTranslator;
setOuFqn(ouFqn);
m_forceAbsoluteLinks = forceAbsoluteLinks;
}
/**
* Returns the adjusted site root for a resource using the provided site root as a base.
*
* Usually, this would be the site root for the current site.
* However, if a resource from the /system/
folder is requested,
* this will be the empty String.
*
* @param siteRoot the site root of the current site
* @param resourcename the resource name to get the adjusted site root for
*
* @return the adjusted site root for the resource
*/
public static String getAdjustedSiteRoot(String siteRoot, String resourcename) {
if (resourcename.startsWith(CmsWorkplace.VFS_PATH_SYSTEM)
|| OpenCms.getSiteManager().startsWithShared(resourcename)
|| (resourcename.startsWith(CmsWorkplace.VFS_PATH_SITES) && !resourcename.startsWith(siteRoot))) {
return "";
} else {
return siteRoot;
}
}
/**
* Adds the current site root of this context to the given resource name,
* and also translates the resource name with the configured the directory translator.
*
* @param resourcename the resource name
* @return the translated resource name including site root
* @see #addSiteRoot(String, String)
*/
public String addSiteRoot(String resourcename) {
return addSiteRoot(m_siteRoot, resourcename);
}
/**
* Adds the given site root of this context to the given resource name,
* taking into account special folders like "/system" where no site root must be added,
* and also translates the resource name with the configured the directory translator.
*
* @param siteRoot the site root to add
* @param resourcename the resource name
* @return the translated resource name including site root
*/
public String addSiteRoot(String siteRoot, String resourcename) {
if ((resourcename == null) || (siteRoot == null)) {
return null;
}
siteRoot = getAdjustedSiteRoot(siteRoot, resourcename);
StringBuffer result = new StringBuffer(128);
result.append(siteRoot);
if (((siteRoot.length() == 0) || (siteRoot.charAt(siteRoot.length() - 1) != '/'))
&& ((resourcename.length() == 0) || (resourcename.charAt(0) != '/'))) {
// add slash between site root and resource if required
result.append('/');
}
result.append(resourcename);
return m_directoryTranslator.translateResource(result.toString());
}
/**
* Returns the current project of the current user.
*
* @return the current project of the current user
*
* @deprecated use {@link #getCurrentProject()} instead
*/
@Deprecated
public CmsProject currentProject() {
return getCurrentProject();
}
/**
* Returns the current user object.
*
* @return the current user object
*
* @deprecated use {@link #getCurrentUser()} instead
*/
@Deprecated
public CmsUser currentUser() {
return getCurrentUser();
}
/**
* Returns the adjusted site root for a resource this context current site root.
*
* @param resourcename the resource name to get the adjusted site root for
*
* @return the adjusted site root for the resource
*
* @see #getAdjustedSiteRoot(String, String)
*/
public String getAdjustedSiteRoot(String resourcename) {
return getAdjustedSiteRoot(m_siteRoot, resourcename);
}
/**
* Gets the value of an attribute from the OpenCms request context attribute list.
*
* @param attributeName the attribute name
* @return Object the attribute value, or null
if the attribute was not found
*/
public Object getAttribute(String attributeName) {
if (m_attributeMap == null) {
return null;
}
return m_attributeMap.get(attributeName);
}
/**
* Returns the current project of the current user.
*
* @return the current project of the current user
*/
public CmsProject getCurrentProject() {
return m_currentProject;
}
/**
* Returns the current user object.
*
* @return the current user object
*/
public CmsUser getCurrentUser() {
return m_user;
}
/**
* Gets the detail content structure id (or null if no detail content has been loaded).
*
* @return the detail content id
*/
public CmsUUID getDetailContentId() {
if (m_detailResource == null) {
return null;
}
return m_detailResource.getStructureId();
}
/**
* Gets the detail content resource (or null if no detail content has been loaded).
*
* @return the detail content resource
*/
public CmsResource getDetailResource() {
return m_detailResource;
}
/**
* Returns the directory name translator this context was initialized with.
*
* The directory translator is used to translate old VFS path information
* to a new location. Example: /bodys/index.html --> /system/bodies/
.
*
* @return the directory name translator this context was initialized with
*/
public CmsResourceTranslator getDirectoryTranslator() {
return m_directoryTranslator;
}
/**
* Returns the current content encoding to be used in HTTP response.
*
* @return the encoding
*/
public String getEncoding() {
return m_encoding;
}
/**
* Returns the file name translator this context was initialized with.
*
* The file name translator is used to translate filenames from uploaded files
* to valid OpenCms filenames. Example: Wüste Wörter.doc --> Wueste_Woerter.doc
.
*
* @return the file name translator this context was initialized with
*/
public CmsResourceTranslator getFileTranslator() {
return m_fileTranslator;
}
/**
* Gets the name of the parent folder of the requested file.
*
* @return the name of the parent folder of the requested file
*/
public String getFolderUri() {
return CmsResource.getFolderPath(m_uri);
}
/**
* Returns the locale used by this request context.
*
* In normal operation, the request context locale is initialized using
* {@link org.opencms.i18n.I_CmsLocaleHandler#getI18nInfo(javax.servlet.http.HttpServletRequest, CmsUser, CmsProject, String)}
* depending on the requested resource URI.
*
* @return the locale used by this request context
*
* @see org.opencms.i18n.I_CmsLocaleHandler#getI18nInfo(javax.servlet.http.HttpServletRequest, CmsUser, CmsProject, String)
* @see org.opencms.i18n.CmsLocaleManager#getDefaultLocale(CmsObject, String)
*/
public Locale getLocale() {
return m_locale;
}
/**
* Returns the fully qualified name of the organizational unit.
*
* @return the fully qualified name of the organizational unit
*/
public String getOuFqn() {
return m_ouFqn;
}
/**
* Returns the remote ip address.
*
* @return the remote ip address as string
*/
public String getRemoteAddress() {
return m_remoteAddr;
}
/**
* Returns the matcher for the current request, that is the host part of the URI from the original http request.
*
* @return the matcher for the current request, that is the host part of the URI from the original http request
*/
public CmsSiteMatcher getRequestMatcher() {
return m_requestMatcher;
}
/**
* Returns the current request time.
*
* @return the current request time
*/
public long getRequestTime() {
return m_requestTime;
}
/**
* Returns this request contexts uri extended with the current site root path.
*
* @return this request contexts uri extended with the current site root path
*
* @see #getUri()
* @see #addSiteRoot(String)
*/
public String getRootUri() {
return addSiteRoot(m_siteRoot, m_uri);
}
/**
* Adjusts the absolute resource root path for the current site.
*
* The full root path of a resource is always available using
* {@link CmsResource#getRootPath()}
. From this name this method cuts
* of the current site root using
* {@link CmsRequestContext#removeSiteRoot(String)}
.
*
* If the resource root path does not start with the current site root,
* it is left untouched.
*
* @param resource the resource to get the adjusted site root path for
*
* @return the absolute resource path adjusted for the current site
*
* @see #removeSiteRoot(String)
* @see CmsResource#getRootPath()
* @see CmsObject#getSitePath(CmsResource)
*/
public String getSitePath(CmsResource resource) {
return removeSiteRoot(resource.getRootPath());
}
/**
* Returns the current root directory in the virtual file system.
*
* @return the current root directory in the virtual file system
*/
public String getSiteRoot() {
return m_siteRoot;
}
/**
* Returns the OpenCms VFS URI of the requested resource.
*
* @return the OpenCms VFS URI of the requested resource
*/
public String getUri() {
return m_uri;
}
/**
* Returns true if links to the current site should be generated as absolute links, i.e. with a server prefix.
*
* @return true if links to the current site should be absolute
*/
public boolean isForceAbsoluteLinks() {
return m_forceAbsoluteLinks;
}
/**
* Returns true if this is a secure request.
*
* @return true if this is secure
*/
public boolean isSecureRequest() {
return m_isSecureRequest;
}
/**
* Check if this request context will update the session.
*
* This is used mainly for CmsReports that continue to use the
* users context, even after the http request is already finished.
*
* @return true if this request context will update the session, false otherwise
*/
public boolean isUpdateSessionEnabled() {
return m_updateSession;
}
/**
* Removes an attribute from the request context.
*
* @param key the name of the attribute to remove
*
* @return the removed attribute, or null
if no attribute was set with this name
*/
public Object removeAttribute(String key) {
if (m_attributeMap != null) {
return m_attributeMap.remove(key);
}
return null;
}
/**
* Removes the current site root prefix from the absolute path in the resource name,
* that is adjusts the resource name for the current site root.
*
* If the resource name does not start with the current site root,
* it is left untouched.
*
* @param resourcename the resource name
*
* @return the resource name adjusted for the current site root
*
* @see #getSitePath(CmsResource)
*/
public String removeSiteRoot(String resourcename) {
String siteRoot = getAdjustedSiteRoot(m_siteRoot, resourcename);
if ((siteRoot == m_siteRoot)
&& resourcename.startsWith(siteRoot)
&& ((resourcename.length() == siteRoot.length()) || (resourcename.charAt(siteRoot.length()) == '/'))) {
resourcename = resourcename.substring(siteRoot.length());
}
if (resourcename.length() == 0) {
// input was a site root folder without trailing slash
resourcename = "/";
}
return resourcename;
}
/**
* Sets an attribute in the request context.
*
* @param key the attribute name
* @param value the attribute value
*/
public void setAttribute(String key, Object value) {
if (m_attributeMap == null) {
// hash table is still the most efficient form of a synchronized Map
m_attributeMap = new Hashtable();
}
m_attributeMap.put(key, value);
}
/**
* Sets the current project for the user.
*
* @param project the project to be set as current project
*
* @return the CmsProject instance
*/
public CmsProject setCurrentProject(CmsProject project) {
if (project != null) {
m_currentProject = project;
}
return m_currentProject;
}
/**
* Sets the detail content resource.
*
* @param detailResource the detail content resource
*/
public void setDetailResource(CmsResource detailResource) {
m_detailResource = detailResource;
}
/**
* Sets the current content encoding to be used in HTTP response.
*
* @param encoding the encoding
*/
public void setEncoding(String encoding) {
m_encoding = encoding;
}
/**
* Enables/disables link generation with full server prefix for the current site.
*
* @param forceAbsoluteLinks true if links to the current site should be generated with server prefix
*/
public void setForceAbsoluteLinks(boolean forceAbsoluteLinks) {
m_forceAbsoluteLinks = forceAbsoluteLinks;
}
/**
* Sets the locale used by this request context.
*
* @param locale the locale to set
*
* @see #getLocale() for more information about how the locale is set in normal operation
*/
public void setLocale(Locale locale) {
m_locale = locale;
}
/**
* Sets the organizational unit fully qualified name.
*
* @param ouFqn the organizational unit fully qualified name
*/
public void setOuFqn(String ouFqn) {
String userOu = CmsOrganizationalUnit.getParentFqn(m_user.getName());
if (ouFqn != null) {
if (ouFqn.startsWith(userOu)
|| (ouFqn.startsWith(CmsOrganizationalUnit.SEPARATOR) && ouFqn.substring(1).startsWith(userOu))) {
m_ouFqn = ouFqn;
} else {
throw new CmsIllegalArgumentException(
Messages.get().container(Messages.ERR_BAD_ORGUNIT_2, ouFqn, userOu));
}
} else {
m_ouFqn = userOu;
}
m_ouFqn = CmsOrganizationalUnit.removeLeadingSeparator(m_ouFqn);
}
/**
* Sets the current request time.
*
* @param time the request time
*/
public void setRequestTime(long time) {
m_requestTime = time;
}
/**
* Sets the 'secure request' status.
*
* @param secureRequest the new value
*/
public void setSecureRequest(boolean secureRequest) {
m_isSecureRequest = secureRequest;
}
/**
* Sets the current root directory in the virtual file system.
*
* @param root the name of the new root directory
*/
public void setSiteRoot(String root) {
// site roots must never end with a "/"
if (root.endsWith("/")) {
m_siteRoot = root.substring(0, root.length() - 1);
} else {
m_siteRoot = root;
}
}
/**
* Mark this request context to update the session or not.
*
* @param value true if this request context will update the session, false otherwise
*/
public void setUpdateSessionEnabled(boolean value) {
m_updateSession = value;
}
/**
* Set the requested resource OpenCms VFS URI, that is the value returned by {@link #getUri()}.
*
* Use this with caution! Many things (caches etc.) depend on this value.
* If you change this value, better make sure that you change it only temporarily
* and reset it in a try { // do something // } finally { // reset URI // }
statement.
*
* @param value the value to set the Uri to, must be a complete OpenCms path name like /system/workplace/style.css
*/
public void setUri(String value) {
m_uri = value;
}
/**
* Switches the user in the context, required after a login.
*
* @param user the new user to use
* @param project the new users current project
* @param ouFqn the organizational unit
*/
protected void switchUser(CmsUser user, CmsProject project, String ouFqn) {
m_user = user;
m_currentProject = project;
setOuFqn(ouFqn);
}
}