All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opencms.site.CmsSiteManagerImpl Maven / Gradle / Ivy

Go to download

OpenCms is an enterprise-ready, easy to use website content management system based on Java and XML technology. Offering a complete set of features, OpenCms helps content managers worldwide to create and maintain beautiful websites fast and efficiently.

There is a newer version: 17.0
Show newest version
/*
 * 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.site;

import com.alkacon.simapi.CmykJpegReader.StringUtil;

import org.opencms.configuration.CmsConfigurationException;
import org.opencms.configuration.CmsSitesConfiguration;
import org.opencms.db.CmsPublishedResource;
import org.opencms.file.CmsObject;
import org.opencms.file.CmsProject;
import org.opencms.file.CmsPropertyDefinition;
import org.opencms.file.CmsResource;
import org.opencms.file.CmsResourceFilter;
import org.opencms.main.CmsContextInfo;
import org.opencms.main.CmsEvent;
import org.opencms.main.CmsException;
import org.opencms.main.CmsLog;
import org.opencms.main.CmsRuntimeException;
import org.opencms.main.I_CmsEventListener;
import org.opencms.main.OpenCms;
import org.opencms.main.OpenCmsCore;
import org.opencms.security.CmsOrganizationalUnit;
import org.opencms.security.CmsPermissionSet;
import org.opencms.security.CmsRole;
import org.opencms.util.CmsFileUtil;
import org.opencms.util.CmsPath;
import org.opencms.util.CmsStringUtil;
import org.opencms.util.CmsUUID;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.logging.Log;

import com.google.common.base.Optional;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

/**
 * Manages all configured sites in OpenCms.

* * To obtain the configured site manager instance, use {@link OpenCms#getSiteManager()}.

* * @since 7.0.2 */ public final class CmsSiteManagerImpl implements I_CmsEventListener { /** * Holds data for the alternative site root mappings. */ private static class AlternativeSiteData { /** Map from site roots as strings to the corresponding alternative site roots. */ private Map m_alternativeSites = new HashMap<>(); /** Site roots for the alternative site data. */ private Set m_siteRoots = new HashSet<>(); /** * Creates a new instance from the alternative site root mappings of the given site. * * @param normalSites the normal sites */ public AlternativeSiteData(Collection normalSites) { for (CmsSite site : normalSites) { if (site.getAlternativeSiteRootMapping().isPresent()) { CmsSite extensionSite = site.createAlternativeSiteRootSite(); CmsPath key = new CmsPath(extensionSite.getSiteRoot()); m_alternativeSites.put(key, extensionSite); m_siteRoots.add(key.asString()); } } } /** * Gets the site for the given root path, or null if no site for that path is found. * * @param path a root path * @return the site for the root path, or null */ public CmsSite getSiteForRootPath(String path) { for (Map.Entry entry : m_alternativeSites.entrySet()) { CmsPath key = entry.getKey(); if (key.isPrefixOfStr(path)) { return entry.getValue(); } } return null; } /** * Gets the site for the given site root. * * @param path a site root * @return the site for the site root */ public CmsSite getSiteForSiteRoot(String path) { CmsPath key = new CmsPath(path); CmsSite result = m_alternativeSites.get(key); return result; } /** * Gets the site roots for the alternative site root mappings. * * @return the site roots */ public Set getSiteRoots() { return Collections.unmodifiableSet(m_siteRoots); } } /** The default shared folder name. */ public static final String DEFAULT_SHARED_FOLDER = "shared"; /** * The VFS root path to the system shared folder, where shared content that belongs to modules, * and that should not be edited by normal editors can be stored. * The folder is searched in the gallery search when shared folders should be searched. */ public static final String PATH_SYSTEM_SHARED_FOLDER = "/system/shared/"; /** A placeholder for the title of the shared folder. */ public static final String SHARED_FOLDER_TITLE = "%SHARED_FOLDER%"; /** Path to config template. */ public static final String WEB_SERVER_CONFIG_CONFIGTEMPLATE = "configtemplate"; /**prefix for files. */ public static final String WEB_SERVER_CONFIG_FILENAMEPREFIX = "filenameprefix"; /**Path to write logs to. */ public static final String WEB_SERVER_CONFIG_LOGGINGDIR = "loggingdir"; /** Path to secure template. */ public static final String WEB_SERVER_CONFIG_SECURETEMPLATE = "securetemplate"; /** Path to target. */ public static final String WEB_SERVER_CONFIG_TARGETPATH = "targetpath"; /** Path of webserver script.*/ public static final String WEB_SERVER_CONFIG_WEBSERVERSCRIPT = "webserverscript"; /** The static log object for this class. */ private static final Log LOG = CmsLog.getLog(CmsSiteManagerImpl.class); /** The path to the "/sites/" folder. */ private static final String SITES_FOLDER = "/sites/"; /** The length of the "/sites/" folder plus 1. */ private static final int SITES_FOLDER_POS = SITES_FOLDER.length() + 1; /** A list of additional site roots, that is site roots that are not below the "/sites/" folder. */ private List m_additionalSiteRoots; /** Data for the alternative site root rules. */ private volatile AlternativeSiteData m_alternativeSiteData = new AlternativeSiteData(new ArrayList<>()); /**Map with webserver scripting parameter. */ private Map m_apacheConfig; /**CmsObject.*/ private CmsObject m_clone; /** The default site root. */ private CmsSite m_defaultSite; /** The default URI. */ private String m_defaultUri; /** Indicates if the configuration is finalized (frozen). */ private boolean m_frozen; /**Is the publish listener already set? */ private boolean m_isListenerSet; /**Old style secure server allowed? */ private boolean m_oldStyleSecureServer; /**Site which are only available for offline project. */ private List m_onlyOfflineSites; /** The shared folder name. */ private String m_sharedFolder; /** Contains all configured site matchers in a list for direct access. */ private List m_siteMatchers; /** Maps site matchers to sites. */ private Map m_siteMatcherSites; /** Maps site roots to sites. */ private Map m_siteRootSites; /**Map from CmsUUID to CmsSite.*/ private Map m_siteUUIDs; /** The workplace site matchers. */ private List m_workplaceMatchers; /** The workplace servers. */ private Map m_workplaceServers; /** * Creates a new CmsSiteManager.

* */ public CmsSiteManagerImpl() { m_siteMatcherSites = new HashMap(); m_siteRootSites = new HashMap(); m_additionalSiteRoots = new ArrayList(); m_workplaceServers = new LinkedHashMap(); m_workplaceMatchers = new ArrayList(); m_oldStyleSecureServer = true; if (CmsLog.INIT.isInfoEnabled()) { CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_START_SITE_CONFIG_0)); } } /** * Creates a site matcher for an alias read from the configuration. * * @param alias the alias * @param redirect redirection enabled (true/false) * @param offset time offset or empty * * @return the alias site matcher */ public static CmsSiteMatcher createAliasSiteMatcher(String alias, String redirect, String offset) { long timeOffset = 0; try { timeOffset = Long.parseLong(offset); } catch (Throwable e) { // ignore } CmsSiteMatcher siteMatcher = new CmsSiteMatcher(alias, timeOffset); boolean redirectVal = new Boolean(redirect).booleanValue(); siteMatcher.setRedirect(redirectVal); return siteMatcher; } /** * Parses the given string as an URI and returns its host component. * * @param uriStr the URI string * @return the host component, or null if the URI can't be parsed */ private static String getHost(String uriStr) { try { URI uri = new URI(uriStr); return uri.getHost(); } catch (URISyntaxException e) { return null; } } /** * Adds a site.

* * @param cms the CMS object * @param site the site to add * * @throws CmsException if something goes wrong */ public void addSite(CmsObject cms, CmsSite site) throws CmsException { // check permissions if (OpenCms.getRunLevel() > OpenCms.RUNLEVEL_1_CORE_OBJECT) { // simple unit tests will have runlevel 1 and no CmsObject OpenCms.getRoleManager().checkRole(cms, CmsRole.DATABASE_MANAGER); } validateSiteRoot(site.getSiteRoot()); // un-freeze m_frozen = false; String secureUrl = null; if (site.hasSecureServer()) { secureUrl = site.getSecureUrl(); } // add the site addSite( site.getUrl(), site.getSiteRoot(), site.getTitle(), Float.toString(site.getPosition()), site.getErrorPage(), Boolean.toString(site.isWebserver()), site.getSSLMode().getXMLValue(), secureUrl, Boolean.toString(site.isExclusiveUrl()), Boolean.toString(site.isExclusiveError()), Boolean.toString(site.usesPermanentRedirects()), Boolean.toString(site.isSubsiteSelectionEnabled()), site.getParameters(), site.getAliases(), site.getAlternativeSiteRootMapping()); // re-initialize, will freeze the state when finished initialize(cms); OpenCms.writeConfiguration(CmsSitesConfiguration.class); } /** * Adds a new CmsSite to the list of configured sites, * this is only allowed during configuration.

* * If this method is called after the configuration is finished, * a RuntimeException is thrown.

* * @param server the Server * @param uri the VFS path * @param title the display title for this site * @param position the display order for this site * @param errorPage the URI to use as error page for this site * @param sslMode the SSLMode of the site * @param webserver indicates whether to write the web server configuration for this site or not * @param secureServer a secure server, can be null * @param exclusive if set to true, secure resources will only be available using the configured secure url * @param error if exclusive, and set to true will generate a 404 error, * if set to false will redirect to secure URL * @param usePermanentRedirects if set to "true", permanent redirects should be used when redirecting to the secure URL * @param subsiteSelection true if subsite selection should be enabled * @param params the site parameters * @param aliases the aliases for the site * @param alternativeSiteRootMapping an optional alternative site root mapping * * @throws CmsConfigurationException if the site contains a server name, that is already assigned */ public void addSite( String server, String uri, String title, String position, String errorPage, String webserver, String sslMode, String secureServer, String exclusive, String error, String usePermanentRedirects, String subsiteSelection, SortedMap params, List aliases, java.util.Optional alternativeSiteRootMapping) throws CmsConfigurationException { if (m_frozen) { throw new CmsRuntimeException(Messages.get().container(Messages.ERR_CONFIG_FROZEN_0)); } if (getSiteRoots().contains(uri)) { throw new CmsRuntimeException(Messages.get().container(Messages.ERR_SITE_ALREADY_CONFIGURED_1, uri)); } if (CmsStringUtil.isEmptyOrWhitespaceOnly(server)) { throw new CmsRuntimeException(Messages.get().container(Messages.ERR_EMPTY_SERVER_URL_0)); } validateSiteRoot(uri); // create a new site object CmsSiteMatcher matcher = new CmsSiteMatcher(server); CmsSite site = new CmsSite(uri, matcher); // set the title site.setTitle(title); // set the position if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(position)) { float pos = Float.MAX_VALUE; try { pos = Float.parseFloat(position); } catch (Throwable e) { // m_position will have Float.MAX_VALUE, so this site will appear last } site.setPosition(pos); } // set the error page site.setErrorPage(errorPage); site.setWebserver(Boolean.valueOf(webserver).booleanValue()); site.setSSLMode(CmsSSLMode.getModeFromXML(sslMode)); if (CmsStringUtil.isNotEmpty(secureServer)) { matcher = new CmsSiteMatcher(secureServer); site.setSecureServer(matcher); site.setExclusiveUrl(Boolean.valueOf(exclusive).booleanValue()); site.setExclusiveError(Boolean.valueOf(error).booleanValue()); site.setUsePermanentRedirects(Boolean.valueOf(usePermanentRedirects).booleanValue()); } site.setSubsiteSelectionEnabled(Boolean.parseBoolean(subsiteSelection)); // note that Digester first calls the addAliasToConfigSite method. // therefore, the aliases are already set site.setAliases(aliases); boolean valid = true; List toAdd = new ArrayList(); for (CmsSiteMatcher matcherToAdd : site.getAllMatchers()) { valid = valid & isServerValid(matcherToAdd) & !toAdd.contains(matcherToAdd); toAdd.add(matcherToAdd); } if (!valid) { throw new CmsConfigurationException( Messages.get().container(Messages.ERR_DUPLICATE_SERVER_NAME_1, matcher.getUrl())); } for (CmsSiteMatcher matcherToAdd : site.getAllMatchers()) { addServer(matcherToAdd, site); } site.setParameters(params); site.setAlternativeSiteRootMapping(alternativeSiteRootMapping); m_siteRootSites = new HashMap(m_siteRootSites); m_siteRootSites.put(site.getSiteRoot(), site); if (CmsLog.INIT.isInfoEnabled()) { CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_SITE_ROOT_ADDED_1, site.toString())); } } /** * Adds a new CmsSite to the list of configured sites, * this is only allowed during configuration.

* * If this method is called after the configuration is finished, * a RuntimeException is thrown.

* * @param server the Server * @param uri the VFS path * @param title the display title for this site * @param position the display order for this site * @param errorPage the URI to use as error page for this site * @param sslMode the SSLMode of the site * @param webserver indicates whether to write the web server configuration for this site or not * @param secureServer a secure server, can be null * @param exclusive if set to true, secure resources will only be available using the configured secure url * @param error if exclusive, and set to true will generate a 404 error, * if set to false will redirect to secure URL * @param usePermanentRedirects if set to "true", permanent redirects should be used when redirecting to the secure URL * @param subsiteSelection true if subsite selection should be enabled for this site * @param params the site parameters * @param aliases the aliases * @param alternativeSiteRoot an optional alternative site root mapping * * @throws CmsConfigurationException in case the site was not configured correctly * */ public void addSiteInternally( String server, String uri, String title, String position, String errorPage, String webserver, String sslMode, String secureServer, String exclusive, String error, String usePermanentRedirects, String subsiteSelection, SortedMap params, List aliases, java.util.Optional alternativeSiteRoot) throws CmsConfigurationException { try { addSite( server, uri, title, position, errorPage, webserver, sslMode, secureServer, exclusive, error, usePermanentRedirects, subsiteSelection, params, aliases, alternativeSiteRoot); } catch (CmsConfigurationException e) { LOG.error("Error reading definitions. Trying to read without aliases.", e); //If this fails, the webserver was defined before ->throw exception addSite( server, uri, title, position, errorPage, webserver, sslMode, secureServer, exclusive, error, usePermanentRedirects, subsiteSelection, params, new ArrayList<>(), alternativeSiteRoot); //If the aliases are making problems, just remove thems } } /** * Adds a workplace server, this is only allowed during configuration.

* * @param workplaceServer the workplace server * @param sslmode CmsSSLMode of workplace server */ public void addWorkplaceServer(String workplaceServer, String sslmode) { if (m_frozen) { throw new CmsRuntimeException(Messages.get().container(Messages.ERR_CONFIG_FROZEN_0)); } if (!m_workplaceServers.containsKey(workplaceServer)) { m_workplaceServers.put(workplaceServer, CmsSSLMode.getModeFromXML(sslmode)); } } /** * @see org.opencms.main.I_CmsEventListener#cmsEvent(org.opencms.main.CmsEvent) */ public void cmsEvent(CmsEvent event) { try { CmsProject project = getOfflineProject(); m_clone.getRequestContext().setCurrentProject(project); List res = null; List foundSites = new ArrayList(); res = m_clone.readPublishedResources( new CmsUUID((String)event.getData().get(I_CmsEventListener.KEY_PUBLISHID))); if (res != null) { for (CmsPublishedResource r : res) { if (!foundSites.contains(r)) { if (m_siteUUIDs.containsKey(r.getStructureId())) { foundSites.add(r); } } } } project = m_clone.readProject(CmsProject.ONLINE_PROJECT_ID); m_clone.getRequestContext().setCurrentProject(project); Map updateMap = new HashMap(); for (CmsPublishedResource r : foundSites) { if (m_clone.existsResource(r.getStructureId())) { //Resource was not deleted CmsResource siteRoot = m_clone.readResource(r.getStructureId()); if (!m_siteRootSites.containsKey(CmsFileUtil.removeTrailingSeparator(siteRoot.getRootPath())) | m_onlyOfflineSites.contains(m_siteUUIDs.get(r.getStructureId()))) { //Site was moved or site root was renamed.. or site was published the first time CmsSite oldSite = m_siteUUIDs.get(siteRoot.getStructureId()); CmsSite newSite = oldSite.clone(); newSite.setSiteRoot(siteRoot.getRootPath()); updateMap.put(oldSite, newSite); } } } for (CmsSite site : updateMap.keySet()) { updateSite(m_clone, site, updateMap.get(site)); } } catch (CmsException e) { LOG.error("Unable to handle publish event", e); } } /** * Returns all wrong configured sites.

* * @param cms CmsObject * @param workplaceMode workplace mode * @return List of CmsSite */ public List getAvailableCorruptedSites(CmsObject cms, boolean workplaceMode) { List res = new ArrayList(); List visSites = getAvailableSites(cms, workplaceMode); Map allsites = getSites(); for (CmsSiteMatcher matcher : allsites.keySet()) { CmsSite site = allsites.get(matcher); if (!visSites.contains(site) & !res.contains(site)) { res.add(site); } } return res; } /** * Returns a list of all sites available (visible) for the current user.

* * @param cms the current OpenCms user context * @param workplaceMode if true, the root and current site is included for the admin user * and the view permission is required to see the site root * * @return a list of all sites available for the current user */ public List getAvailableSites(CmsObject cms, boolean workplaceMode) { return getAvailableSites(cms, workplaceMode, cms.getRequestContext().getOuFqn()); } /** * Returns a list of all {@link CmsSite} instances that are compatible to the given organizational unit.

* * @param cms the current OpenCms user context * @param workplaceMode if true, the root and current site is included for the admin user * and the view permission is required to see the site root * @param showShared if the shared folder should be shown * @param ouFqn the organizational unit * * @return a list of all site available for the current user */ public List getAvailableSites(CmsObject cms, boolean workplaceMode, boolean showShared, String ouFqn) { return getAvailableSites(cms, workplaceMode, showShared, ouFqn, null); } /** * Returns a list of all {@link CmsSite} instances that are compatible to the given organizational unit.

* * @param cms the current OpenCms user context * @param workplaceMode if true, the root and current site is included for the admin user * and the view permission is required to see the site root * @param showShared if the shared folder should be shown * @param ouFqn the organizational unit * @param filterMode The CmsSLLMode to filter, null if no filter * * @return a list of all site available for the current user */ public List getAvailableSites( CmsObject cms, boolean workplaceMode, boolean showShared, String ouFqn, CmsSSLMode filterMode) { List siteroots = new ArrayList(m_siteMatcherSites.size() + 1); Map siteServers = new HashMap(m_siteMatcherSites.size() + 1); List result = new ArrayList(m_siteMatcherSites.size() + 1); for (CmsSite mainSite : m_siteMatcherSites.values()) { List sitesToProcess = new ArrayList<>(); sitesToProcess.add(mainSite); CmsSite extensionFolderSite = mainSite.createAlternativeSiteRootSite(); if (extensionFolderSite != null) { sitesToProcess.add(extensionFolderSite); } for (CmsSite site : sitesToProcess) { String folder = CmsFileUtil.addTrailingSeparator(site.getSiteRoot()); if (!siteroots.contains(folder)) { siteroots.add(folder); siteServers.put(folder, site.getSiteMatcher()); } } } // add default site if (workplaceMode && (m_defaultSite != null)) { String folder = CmsFileUtil.addTrailingSeparator(m_defaultSite.getSiteRoot()); if (!siteroots.contains(folder)) { siteroots.add(folder); } } String storedSiteRoot = cms.getRequestContext().getSiteRoot(); try { // for all operations here we need no context cms.getRequestContext().setSiteRoot("/"); if (workplaceMode && OpenCms.getRoleManager().hasRole(cms, CmsRole.VFS_MANAGER)) { if (!siteroots.contains("/")) { // add the root site if the user is in the workplace and has the required role siteroots.add("/"); } if (!siteroots.contains(CmsFileUtil.addTrailingSeparator(storedSiteRoot))) { siteroots.add(CmsFileUtil.addTrailingSeparator(storedSiteRoot)); } } // add the shared site String shared = OpenCms.getSiteManager().getSharedFolder(); if (showShared && (shared != null) && !siteroots.contains(shared)) { siteroots.add(shared); } // all sites are compatible for root admins in the root OU, skip unnecessary tests boolean allCompatible = OpenCms.getRoleManager().hasRole(cms, CmsRole.ROOT_ADMIN) && (ouFqn.isEmpty() || ouFqn.equals(CmsOrganizationalUnit.SEPARATOR)); List resources = Collections.emptyList(); if (!allCompatible) { try { resources = OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, ouFqn); } catch (CmsException e) { return Collections.emptyList(); } } Collections.sort(siteroots); // sort by resource name Iterator roots = siteroots.iterator(); while (roots.hasNext()) { String folder = roots.next(); boolean compatible = allCompatible; if (!compatible) { Iterator itResources = resources.iterator(); while (itResources.hasNext()) { CmsResource resource = itResources.next(); if (resource.getRootPath().startsWith(folder) || folder.startsWith(resource.getRootPath())) { compatible = true; break; } } } // select only sites compatibles to the given organizational unit if (compatible) { try { CmsResource res = cms.readResource(folder); if (!workplaceMode || cms.hasPermissions( res, CmsPermissionSet.ACCESS_VIEW, false, CmsResourceFilter.ONLY_VISIBLE)) { // get the title and the position from the system configuration first CmsSite configuredSite = getSiteForSiteRoot(CmsFileUtil.removeTrailingSeparator(folder)); // CmsSite configuredSite = m_siteRootSites.get(CmsFileUtil.removeTrailingSeparator(folder)); // get the title String title = null; if ((configuredSite != null) && CmsStringUtil.isNotEmptyOrWhitespaceOnly(configuredSite.getTitle())) { title = configuredSite.getTitle(); } if (title == null) { title = getSiteTitle(cms, res); } // get the position String position = null; if ((configuredSite != null) && (configuredSite.getPosition() != Float.MAX_VALUE)) { position = Float.toString(configuredSite.getPosition()); } if (position == null) { // not found, use the 'NavPos' property position = cms.readPropertyObject( res, CmsPropertyDefinition.PROPERTY_NAVPOS, false).getValue(); } if (configuredSite != null) { float pos = Float.MAX_VALUE; try { pos = Float.parseFloat(position); } catch (Throwable e) { // m_position will have Float.MAX_VALUE, so this site will appear last } CmsSite clone = configuredSite.clone(); clone.setPosition(pos); clone.setTitle(title); if (filterMode == null) { result.add(clone); } else { if (filterMode.equals(clone.getSSLMode())) { result.add(clone); } } } else { // add the site to the result result.add( new CmsSite( folder, res.getStructureId(), title, siteServers.get(folder), position)); } } } catch (CmsException e) { // user probably has no read access to the folder, ignore and continue iterating } } } // sort and ensure that the shared folder is the last element in the list Collections.sort(result, new Comparator() { public int compare(CmsSite o1, CmsSite o2) { if (isSharedFolder(o1.getSiteRoot())) { return +1; } if (isSharedFolder(o2.getSiteRoot())) { return -1; } return o1.compareTo(o2); } }); } catch (Throwable t) { LOG.error(Messages.get().getBundle().key(Messages.LOG_READ_SITE_PROP_FAILED_0), t); } finally { // restore the user's current context cms.getRequestContext().setSiteRoot(storedSiteRoot); } return result; } /** * Returns a list of all sites available (visible) for the current user.

* * @param cms the current OpenCms user context * @param workplaceMode if true, the root and current site is included for the admin user * and the view permission is required to see the site root * @param filterMode The CmsSLLMode to filter, null if no filter * * @return a list of all sites available for the current user */ public List getAvailableSites(CmsObject cms, boolean workplaceMode, CmsSSLMode filterMode) { return getAvailableSites(cms, workplaceMode, workplaceMode, cms.getRequestContext().getOuFqn(), filterMode); } /** * Returns a list of all {@link CmsSite} instances that are compatible to the given organizational unit.

* * @param cms the current OpenCms user context * @param workplaceMode if true, the root and current site is included for the admin user * and the view permission is required to see the site root * @param ouFqn the organizational unit * * @return a list of all site available for the current user */ public List getAvailableSites(CmsObject cms, boolean workplaceMode, String ouFqn) { return getAvailableSites(cms, workplaceMode, workplaceMode, ouFqn); } /** * Returns the current site for the provided OpenCms user context object.

* * In the unlikely case that no site matches with the provided OpenCms user context, * the default site is returned.

* * @param cms the OpenCms user context object to check for the site * * @return the current site for the provided OpenCms user context object */ public CmsSite getCurrentSite(CmsObject cms) { CmsSite site = getSiteForSiteRoot(cms.getRequestContext().getSiteRoot()); return (site == null) ? m_defaultSite : site; } /** * Returns the default site.

* * @return the default site */ public CmsSite getDefaultSite() { return m_defaultSite; } /** * Returns the defaultUri.

* * @return the defaultUri */ public String getDefaultUri() { return m_defaultUri; } /** * Returns the shared folder path.

* * @return the shared folder path */ public String getSharedFolder() { return m_sharedFolder; } /** * Returns the site for the given resource path, using the fall back site root * in case the resource path is no root path.

* * In case neither the given resource path, nor the given fall back site root * matches any configured site, the default site is returned.

* * Usually the fall back site root should be taken from {@link org.opencms.file.CmsRequestContext#getSiteRoot()}, * in which case a site for the site root should always exist.

* * This is the same as first calling {@link #getSiteForRootPath(String)} with the * resourcePath parameter, and if this fails calling * {@link #getSiteForSiteRoot(String)} with the fallbackSiteRoot parameter, * and if this fails calling {@link #getDefaultSite()}.

* * @param rootPath the resource root path to get the site for * @param fallbackSiteRoot site root to use in case the resource path is no root path * * @return the site for the given resource path, using the fall back site root * in case the resource path is no root path * * @see #getSiteForRootPath(String) */ public CmsSite getSite(String rootPath, String fallbackSiteRoot) { CmsSite result = getSiteForRootPath(rootPath); if (result == null) { result = getSiteForSiteRoot(fallbackSiteRoot); if (result == null) { result = getDefaultSite(); } } return result; } /** * Gets the site which is mapped to the default uri, or the 'absent' value of no such site exists.

* * @return the optional site mapped to the default uri */ public Optional getSiteForDefaultUri() { String defaultUri = getDefaultUri(); CmsSite candidate = m_siteRootSites.get(CmsFileUtil.removeTrailingSeparator(defaultUri)); return Optional.fromNullable(candidate); } /** * Returns the site for the given resources root path, * or null if the resources root path does not match any site.

* * @param rootPath the root path of a resource * * @return the site for the given resources root path, * or null if the resources root path does not match any site * * @see #getSiteForSiteRoot(String) * @see #getSiteRoot(String) */ public CmsSite getSiteForRootPath(String rootPath) { if ((rootPath.length() > 0) && !rootPath.endsWith("/")) { rootPath = rootPath + "/"; } // most sites will be below the "/sites/" folder, CmsSite result = lookupSitesFolder(rootPath); if (result != null) { return result; } // look through all folders that are not below "/sites/" String siteRoot = lookupAdditionalSite(rootPath); if (siteRoot != null) { return getSiteForSiteRoot(siteRoot); } return m_alternativeSiteData.getSiteForRootPath(rootPath); } /** * Returns the site with has the provided site root, * or null if no configured site has that site root.

* * The site root must have the form: * /sites/default.
* That means there must be a leading, but no trailing slash.

* * @param siteRoot the site root to look up the site for * * @return the site with has the provided site root, * or null if no configured site has that site root * * @see #getSiteForRootPath(String) */ public CmsSite getSiteForSiteRoot(String siteRoot) { if (siteRoot == null) { return null; } CmsSite result = m_siteRootSites.get(siteRoot); if (result != null) { return result; } else { return m_alternativeSiteData.getSiteForSiteRoot(siteRoot); } } /** * Returns the site root part for the given resources root path, * or null if the given resources root path does not match any site root.

* * The site root returned will have the form: * /sites/default.
* That means there will a leading, but no trailing slash.

* * @param rootPath the root path of a resource * * @return the site root part of the resources root path, * or null if the path does not match any site root * * @see #getSiteForRootPath(String) */ public String getSiteRoot(String rootPath) { // add a trailing slash, because the path may be the path of a site root itself if (!rootPath.endsWith("/")) { rootPath = rootPath + "/"; } // most sites will be below the "/sites/" folder, CmsSite site = lookupSitesFolder(rootPath); if (site != null) { return site.getSiteRoot(); } // look through all folders that are not below "/sites/" String result = lookupAdditionalSite(rootPath); if (result != null) { return result; } CmsSite extSite = m_alternativeSiteData.getSiteForRootPath(rootPath); if (extSite != null) { result = extSite.getSiteRoot(); } return result; } /** * Returns an unmodifiable set of all configured site roots (Strings).

* * @return an unmodifiable set of all configured site roots (Strings) */ public Set getSiteRoots() { return Sets.union(m_siteRootSites.keySet(), m_alternativeSiteData.getSiteRoots()); } /** * Returns the map of configured sites, using * {@link CmsSiteMatcher} objects as keys and {@link CmsSite} objects as values.

* * @return the map of configured sites, using {@link CmsSiteMatcher} * objects as keys and {@link CmsSite} objects as values */ public Map getSites() { return m_siteMatcherSites; } /** * Returns the site title.

* * @param cms the cms context * @param resource the site root resource * * @return the title * * @throws CmsException in case reading the title property fails */ public String getSiteTitle(CmsObject cms, CmsResource resource) throws CmsException { String title = cms.readPropertyObject(resource, CmsPropertyDefinition.PROPERTY_TITLE, false).getValue(); if (title == null) { title = resource.getRootPath(); } if (resource.getRootPath().equals(getSharedFolder())) { title = SHARED_FOLDER_TITLE; } return title; } /** * Gets the SSLMode for given workplace server.

* * @param server to obtain ssl mode for * @return CmsSSLMode */ public CmsSSLMode getSSLModeForWorkplaceServer(String server) { if (server == null) { return CmsSSLMode.NO; } if (!m_workplaceServers.containsKey(server)) { return CmsSSLMode.NO; } return m_workplaceServers.get(server); } /** * Get web server scripting configurations.

* * @return Map with configuration data */ public Map getWebServerConfig() { return m_apacheConfig; } /** * Returns the workplace server.

* * @return the workplace server */ public String getWorkplaceServer() { return m_workplaceServers.keySet().isEmpty() ? null : m_workplaceServers.keySet().iterator().next(); } /** * Gets the first configured workplace server that matches the host from the current CmsRequestContext, or * the first configured workplace server if there is no match. * *

If there are no workplace configured at all, null is returned. * * @param cms the CmsObject used to check the host * @return the workplace server */ public String getWorkplaceServer(CmsObject cms) { if (m_workplaceServers.keySet().isEmpty()) { return null; } CmsSiteMatcher requestMatcher = cms.getRequestContext().getRequestMatcher(); if (requestMatcher != null) { String reqHost = getHost(requestMatcher.toString()); if (reqHost != null) { for (String wpServer : m_workplaceServers.keySet()) { String wpHost = getHost(wpServer); if (reqHost.equals(wpHost)) { return wpServer; } } } } return m_workplaceServers.keySet().iterator().next(); } /** * Returns the configured worklace servers.

* * @return the workplace servers */ public List getWorkplaceServers() { return Collections.unmodifiableList(new ArrayList(m_workplaceServers.keySet())); } /** * Returns the configured worklace servers.

* * @param filterMode CmsSSLMode to filter results for. * @return the workplace servers */ public List getWorkplaceServers(CmsSSLMode filterMode) { if (filterMode == null) { return getWorkplaceServers(); } List ret = new ArrayList(); for (String server : m_workplaceServers.keySet()) { if (m_workplaceServers.get(server).equals(filterMode)) { ret.add(server); } } return ret; } /** * Returns the configured worklace servers.

* * @return the workplace servers */ public Map getWorkplaceServersMap() { return Collections.unmodifiableMap(m_workplaceServers); } /** * Returns the site matcher that matches the workplace site.

* * @return the site matcher that matches the workplace site */ public CmsSiteMatcher getWorkplaceSiteMatcher() { return m_workplaceMatchers.isEmpty() ? null : m_workplaceMatchers.get(0); } /** * Initializes the site manager with the OpenCms system configuration.

* * @param cms an OpenCms context object that must have been initialized with "Admin" permissions */ public void initialize(CmsObject cms) { if (CmsLog.INIT.isInfoEnabled()) { CmsLog.INIT.info( Messages.get().getBundle().key( Messages.INIT_NUM_SITE_ROOTS_CONFIGURED_1, new Integer((m_siteMatcherSites.size() + ((m_defaultUri != null) ? 1 : 0))))); } try { m_clone = OpenCms.initCmsObject(cms); m_clone.getRequestContext().setSiteRoot(""); m_clone.getRequestContext().setCurrentProject(m_clone.readProject(CmsProject.ONLINE_PROJECT_NAME)); CmsObject cms_offline = OpenCms.initCmsObject(m_clone); CmsProject tempProject = cms_offline.createProject( "tempProjectSites", "", "/Users", "/Users", CmsProject.PROJECT_TYPE_TEMPORARY); cms_offline.getRequestContext().setCurrentProject(tempProject); m_siteUUIDs = new HashMap(); // check the presence of sites in VFS m_onlyOfflineSites = new ArrayList(); for (CmsSite site : m_siteMatcherSites.values()) { checkUUIDOfSiteRoot(site, m_clone, cms_offline); try { CmsResource siteRes = m_clone.readResource(site.getSiteRoot()); site.setSiteRootUUID(siteRes.getStructureId()); m_siteUUIDs.put(siteRes.getStructureId(), site); // during server startup the digester can not access properties, so set the title afterwards if (CmsStringUtil.isEmptyOrWhitespaceOnly(site.getTitle())) { String title = m_clone.readPropertyObject( siteRes, CmsPropertyDefinition.PROPERTY_TITLE, false).getValue(); if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(title)) { site.setTitle(title); } } } catch (Throwable t) { if (CmsLog.INIT.isWarnEnabled()) { CmsLog.INIT.warn(Messages.get().getBundle().key(Messages.INIT_NO_ROOT_FOLDER_1, site)); } } } cms_offline.deleteProject(tempProject.getUuid()); // check the presence of the default site in VFS if (CmsStringUtil.isEmptyOrWhitespaceOnly(m_defaultUri)) { m_defaultSite = null; } else { m_defaultSite = new CmsSite(m_defaultUri, CmsSiteMatcher.DEFAULT_MATCHER); try { m_clone.readResource(m_defaultSite.getSiteRoot()); } catch (Throwable t) { if (CmsLog.INIT.isWarnEnabled()) { CmsLog.INIT.warn( Messages.get().getBundle().key(Messages.INIT_NO_ROOT_FOLDER_DEFAULT_SITE_1, m_defaultSite)); } } } if (m_defaultSite == null) { m_defaultSite = new CmsSite("/", CmsSiteMatcher.DEFAULT_MATCHER); } if (CmsLog.INIT.isInfoEnabled()) { if (m_defaultSite != null) { CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_DEFAULT_SITE_ROOT_1, m_defaultSite)); } else { CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_DEFAULT_SITE_ROOT_0)); } } initWorkplaceMatchers(); // set site lists to unmodifiable setSiteMatcherSites(m_siteMatcherSites); // store additional site roots to optimize lookups later for (String root : m_siteRootSites.keySet()) { if (!root.startsWith(SITES_FOLDER) || (root.split("/").length >= 4)) { m_additionalSiteRoots.add(root); } } initExtensionSites(); if (m_sharedFolder == null) { m_sharedFolder = DEFAULT_SHARED_FOLDER; } // initialization is done, set the frozen flag to true m_frozen = true; } catch (CmsException e) { LOG.warn(e); } if (!m_isListenerSet) { OpenCms.addCmsEventListener(this, new int[] {I_CmsEventListener.EVENT_PUBLISH_PROJECT}); m_isListenerSet = true; } } /** * Checks if web server scripting is enabled.

* * @return true if web server scripting is set to available */ public boolean isConfigurableWebServer() { return m_apacheConfig != null; } /** * Returns true if the given site matcher matches any configured site, * which includes the workplace site.

* * @param matcher the site matcher to match the site with * * @return true if the matcher matches a site */ public boolean isMatching(CmsSiteMatcher matcher) { boolean result = m_siteMatcherSites.get(matcher) != null; if (!result) { // try to match the workplace site result = isWorkplaceRequest(matcher); } return result; } /** * Returns true if the given site matcher matches the current site.

* * @param cms the current OpenCms user context * @param matcher the site matcher to match the site with * * @return true if the matcher matches the current site */ public boolean isMatchingCurrentSite(CmsObject cms, CmsSiteMatcher matcher) { return m_siteMatcherSites.get(matcher) == getCurrentSite(cms); } /** * Checks if old style secure server is allowed.

* * @return boolean */ public boolean isOldStyleSecureServerAllowed() { return m_oldStyleSecureServer; } /** * Indicates if given site is only available for offline repository.

* * @param site to be looked up * @return true if only offline exists, false otherwise */ public boolean isOnlyOfflineSite(CmsSite site) { return m_onlyOfflineSites.contains(site); } /** * Checks if the given path is that of a shared folder.

* * @param name a path prefix * * @return true if the given prefix represents a shared folder */ public boolean isSharedFolder(String name) { return (m_sharedFolder != null) && m_sharedFolder.equals(CmsStringUtil.joinPaths("/", name, "/")); } /** * Checks whether a given root path is a site root.

* * @param rootPath a root path * * @return true if the given path is the path of a site root */ public boolean isSiteRoot(String rootPath) { String siteRoot = getSiteRoot(rootPath); rootPath = CmsStringUtil.joinPaths(rootPath, "/"); return rootPath.equals(siteRoot); } /** * Checks if a given site is under another site.

* * @param site CmsSite to check * @return true if given site is invalid */ public boolean isSiteUnderSite(CmsSite site) { return isSiteUnderSite(site.getSiteRoot()); } /** * Checks if a given site is under another site.

* * @param siteRootPath site root path to check * @return true if given site is invalid */ public boolean isSiteUnderSite(String siteRootPath) { for (String siteRoot : getSiteRoots()) { if ((siteRootPath.length() > siteRoot.length()) & siteRootPath.startsWith(CmsFileUtil.addTrailingSeparator(siteRoot))) { return true; } } return false; } /** * Returns true if the given site matcher matches the configured OpenCms workplace.

* * @param matcher the site matcher to match the site with * * @return true if the given site matcher matches the configured OpenCms workplace */ public boolean isWorkplaceRequest(CmsSiteMatcher matcher) { return m_workplaceMatchers.contains(matcher); } /** * Returns true if the given request is against the configured OpenCms workplace.

* * @param req the request to match * * @return true if the given request is against the configured OpenCms workplace */ public boolean isWorkplaceRequest(HttpServletRequest req) { if (req == null) { // this may be true inside a static export test case scenario return false; } return isWorkplaceRequest(getRequestMatcher(req)); } /** * Matches the given request against all configures sites and returns * the matching site, or the default site if no sites matches.

* * @param req the request to match * * @return the matching site, or the default site if no sites matches */ public CmsSite matchRequest(HttpServletRequest req) { CmsSiteMatcher matcher = getRequestMatcher(req); if (matcher.getTimeOffset() != 0) { HttpSession session = req.getSession(); if (session != null) { session.setAttribute( CmsContextInfo.ATTRIBUTE_REQUEST_TIME, new Long(System.currentTimeMillis() + matcher.getTimeOffset())); } } CmsSite site = matchSite(matcher); if (site.matchAlternativeSiteRoot(OpenCmsCore.getPathInfo(req))) { CmsSite alternativeSite = site.createAlternativeSiteRootSite(); if (alternativeSite != null) { LOG.debug( req.getRequestURL().toString() + ": " + "Matched extension folder rule, changing site root from " + site.getSiteRoot() + " to " + alternativeSite.getSiteRoot()); site = alternativeSite; } } if (LOG.isDebugEnabled()) { String requestServer = req.getScheme() + "://" + req.getServerName() + ":" + req.getServerPort(); LOG.debug( Messages.get().getBundle().key( Messages.LOG_MATCHING_REQUEST_TO_SITE_2, requestServer, site.toString())); } return site; } /** * Return the configured site that matches the given site matcher, * or the default site if no sites matches.

* * Does NOT match auto-generated sites from alternative site root mappings, since the site matcher does not contain path information. * * @param matcher the site matcher to match the site with * @return the matching site, or the default site if no sites matches */ public CmsSite matchSite(CmsSiteMatcher matcher) { CmsSite site = m_siteMatcherSites.get(matcher); if (site == null) { // return the default site (might be null as well) site = m_defaultSite; } return site; } /** * Removes a site from the list of configured sites.

* * @param cms the cms object * @param site the site to remove * * @throws CmsException if something goes wrong */ public void removeSite(CmsObject cms, CmsSite site) throws CmsException { // check permissions if (OpenCms.getRunLevel() > OpenCms.RUNLEVEL_1_CORE_OBJECT) { // simple unit tests will have runlevel 1 and no CmsObject OpenCms.getRoleManager().checkRole(cms, CmsRole.DATABASE_MANAGER); } // un-freeze m_frozen = false; // create a new map containing all existing sites without the one to remove Map siteMatcherSites = new HashMap(); List matchersForSite = site.getAllMatchers(); for (Map.Entry entry : m_siteMatcherSites.entrySet()) { if (!(matchersForSite.contains(entry.getKey()))) { // entry not the site itself nor an alias of the site nor the secure URL of the site, so add it siteMatcherSites.put(entry.getKey(), entry.getValue()); } } setSiteMatcherSites(siteMatcherSites); // remove the site from the map holding the site roots as keys and the sites as values Map siteRootSites = new HashMap(m_siteRootSites); siteRootSites.remove(site.getSiteRoot()); m_siteRootSites = Collections.unmodifiableMap(siteRootSites); // re-initialize, will freeze the state when finished initialize(cms); OpenCms.writeConfiguration(CmsSitesConfiguration.class); } /** * Sets the default URI, this is only allowed during configuration.

* * If this method is called after the configuration is finished, * a RuntimeException is thrown.

* * @param defaultUri the defaultUri to set */ public void setDefaultUri(String defaultUri) { if (m_frozen) { throw new CmsRuntimeException(Messages.get().container(Messages.ERR_CONFIG_FROZEN_0)); } m_defaultUri = defaultUri; } /** * Sets the old style secure server boolean.

* * @param value value */ public void setOldStyleSecureServerAllowed(String value) { m_oldStyleSecureServer = Boolean.parseBoolean(StringUtil.toLowerCase(value)); } /** * Sets the shared folder path.

* * @param sharedFolder the shared folder path */ public void setSharedFolder(String sharedFolder) { if (m_frozen) { throw new CmsRuntimeException(Messages.get().container(Messages.ERR_CONFIG_FROZEN_0)); } m_sharedFolder = CmsStringUtil.joinPaths("/", sharedFolder, "/"); } /** * Set webserver script configuration.

* * * @param webserverscript path * @param targetpath path * @param configtemplate path * @param securetemplate path * @param filenameprefix to add to files * @param loggingdir path */ public void setWebServerScripting( String webserverscript, String targetpath, String configtemplate, String securetemplate, String filenameprefix, String loggingdir) { m_apacheConfig = new HashMap(); m_apacheConfig.put(WEB_SERVER_CONFIG_WEBSERVERSCRIPT, webserverscript); m_apacheConfig.put(WEB_SERVER_CONFIG_TARGETPATH, targetpath); m_apacheConfig.put(WEB_SERVER_CONFIG_CONFIGTEMPLATE, configtemplate); m_apacheConfig.put(WEB_SERVER_CONFIG_SECURETEMPLATE, securetemplate); m_apacheConfig.put(WEB_SERVER_CONFIG_FILENAMEPREFIX, filenameprefix); m_apacheConfig.put(WEB_SERVER_CONFIG_LOGGINGDIR, loggingdir); } /** * Returns true if the path starts with the shared folder path.

* * @param path the path to check * * @return true if the path starts with the shared folder path */ public boolean startsWithShared(String path) { return (m_sharedFolder != null) && CmsFileUtil.addTrailingSeparator(path).startsWith(m_sharedFolder); } /** * Method for backward compability reasons. Not sure if really needed //TODO check! * CmsSSLMode are set to No as default.

* * @param cms the cms to use * @param defaultUri the default URI * @param workplaceServersList the workplace server URLs * @param sharedFolder the shared folder URI * * @throws CmsException if something goes wrong */ public void updateGeneralSettings( CmsObject cms, String defaultUri, List workplaceServersList, String sharedFolder) throws CmsException { Map workplaceServers = new LinkedHashMap(); for (String server : workplaceServersList) { if (m_workplaceServers.containsKey(server)) { workplaceServers.put(server, m_workplaceServers.get(server)); } else { workplaceServers.put(server, CmsSSLMode.NO); } } updateGeneralSettings(cms, defaultUri, workplaceServers, sharedFolder); } /** * Updates the general settings.

* * @param cms the cms to use * @param defaulrUri the default URI * @param workplaceServers the workplace server URLs * @param sharedFolder the shared folder URI * * @throws CmsException if something goes wrong */ public void updateGeneralSettings( CmsObject cms, String defaulrUri, Map workplaceServers, String sharedFolder) throws CmsException { CmsObject clone = OpenCms.initCmsObject(cms); clone.getRequestContext().setSiteRoot(""); // set the shared folder if ((sharedFolder == null) || sharedFolder.equals("") || sharedFolder.equals("/") || !sharedFolder.startsWith("/") || !sharedFolder.endsWith("/") || sharedFolder.startsWith("/sites/")) { throw new CmsException( Messages.get().container(Messages.ERR_INVALID_PATH_FOR_SHARED_FOLDER_1, sharedFolder)); } m_frozen = false; setDefaultUri(clone.readResource(defaulrUri).getRootPath()); setSharedFolder(clone.readResource(sharedFolder).getRootPath()); m_workplaceServers = workplaceServers; initialize(cms); m_frozen = true; } /** * Updates or creates a site.

* * @param cms the CMS object * @param oldSite the site to remove if not null * @param newSite the site to add if not null * * @throws CmsException if something goes wrong */ public void updateSite(CmsObject cms, CmsSite oldSite, CmsSite newSite) throws CmsException { if (oldSite != null) { // remove the old site removeSite(cms, oldSite); } if (newSite != null) { // add the new site addSite(cms, newSite); } } /** * Returns true if this request goes to a secure site.

* * @param req the request to check * * @return true if the request goes to a secure site */ public boolean usesSecureSite(HttpServletRequest req) { CmsSite site = matchRequest(req); if (site == null) { return false; } CmsSiteMatcher secureMatcher = site.getSecureServerMatcher(); boolean result = false; if (secureMatcher != null) { result = secureMatcher.equals(getRequestMatcher(req)); } return result; } /** * Validates the site root, throwing an exception if the validation fails. * * @param siteRoot the site root to check */ public void validateSiteRoot(String siteRoot) { if (!isValidSiteRoot(siteRoot)) { throw new CmsRuntimeException(Messages.get().container(Messages.ERR_INVALID_SITE_ROOT_1, siteRoot)); } } /** * Adds a new Site matcher object to the map of server names. * * @param matcher the SiteMatcher of the server * @param site the site to add */ private void addServer(CmsSiteMatcher matcher, CmsSite site) { Map siteMatcherSites = new HashMap(m_siteMatcherSites); siteMatcherSites.put(matcher, site); setSiteMatcherSites(siteMatcherSites); } /** * Fetches UUID for given site root from online and offline repository.

* * @param site to read and set UUID for * @param clone online CmsObject * @param cms_offline offline CmsObject */ private void checkUUIDOfSiteRoot(CmsSite site, CmsObject clone, CmsObject cms_offline) { CmsUUID id = null; try { id = clone.readResource(site.getSiteRoot()).getStructureId(); } catch (CmsException e) { //Ok, site root not available for online repository. } if (id == null) { try { id = cms_offline.readResource(site.getSiteRoot()).getStructureId(); m_onlyOfflineSites.add(site); } catch (CmsException e) { //Siteroot not valid for on- and offline repository. } } if (id != null) { site.setSiteRootUUID(id); m_siteUUIDs.put(id, site); } } /** * Gets an offline project to read offline resources from.

* * @return CmsProject */ private CmsProject getOfflineProject() { try { return m_clone.readProject("Offline"); } catch (CmsException e) { try { for (CmsProject p : OpenCms.getOrgUnitManager().getAllAccessibleProjects(m_clone, "/", true)) { if (!p.isOnlineProject()) { return p; } } } catch (CmsException e1) { LOG.error("Unable to get ptoject", e); } } return null; } /** * Returns the site matcher for the given request.

* * @param req the request to get the site matcher for * * @return the site matcher for the given request */ private CmsSiteMatcher getRequestMatcher(HttpServletRequest req) { CmsSiteMatcher matcher = new CmsSiteMatcher(req.getScheme(), req.getServerName(), req.getServerPort()); // this is required to get the right configured time offset int index = m_siteMatchers.indexOf(matcher); if (index < 0) { return matcher; } return m_siteMatchers.get(index); } /** * Finds the configured extension folders for all normal sites and stores them in a separate list. */ private void initExtensionSites() { m_alternativeSiteData = new AlternativeSiteData(m_siteMatcherSites.values()); } /** * Initializes the workplace matchers.

*/ private void initWorkplaceMatchers() { List matchers = new ArrayList(); if (!m_workplaceServers.isEmpty()) { Map matchersByUrl = Maps.newHashMap(); for (String server : m_workplaceServers.keySet()) { CmsSSLMode mode = m_workplaceServers.get(server); CmsSiteMatcher matcher = new CmsSiteMatcher(server); if ((mode == CmsSSLMode.LETS_ENCRYPT) || (mode == CmsSSLMode.MANUAL_EP_TERMINATION)) { CmsSiteMatcher httpMatcher = matcher.forDifferentScheme("http"); CmsSiteMatcher httpsMatcher = matcher.forDifferentScheme("https"); for (CmsSiteMatcher current : new CmsSiteMatcher[] {httpMatcher, httpsMatcher}) { matchersByUrl.put(current.getUrl(), current); if (CmsLog.INIT.isInfoEnabled()) { CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_WORKPLACE_SITE_1, matcher)); } } } else { matchersByUrl.put(matcher.getUrl(), matcher); if (CmsLog.INIT.isInfoEnabled()) { CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_WORKPLACE_SITE_1, matcher)); } } } matchers = Lists.newArrayList(matchersByUrl.values()); } else if (CmsLog.INIT.isInfoEnabled()) { CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_WORKPLACE_SITE_0)); } m_workplaceMatchers = matchers; } /** * Checks whether the given matcher is included in the currently configured and valid matchers.

* * @param matcher the matcher to check * * @return true in case the given matcher is included in the currently configured and valid matchers */ private boolean isServerValid(CmsSiteMatcher matcher) { return !m_siteMatcherSites.containsKey(matcher); } /** * Validates the site root. * * @param uri the site root to validate * @return true if the site root is valid */ private boolean isValidSiteRoot(String uri) { if ("".equals(uri) || "/".equals(uri)) { return false; } return true; } /** * Returns true if the given root path matches any of the stored additional sites.

* * @param rootPath the root path to check * * @return true if the given root path matches any of the stored additional sites */ private String lookupAdditionalSite(String rootPath) { for (int i = 0, size = m_additionalSiteRoots.size(); i < size; i++) { String siteRoot = m_additionalSiteRoots.get(i); if (rootPath.startsWith(siteRoot + "/")) { return siteRoot; } } return null; } /** * Returns the configured site if the given root path matches site in the "/sites/" folder, * or null otherwise.

* * @param rootPath the root path to check * * @return the configured site if the given root path matches site in the "/sites/" folder, * or null otherwise */ private CmsSite lookupSitesFolder(String rootPath) { int pos = rootPath.indexOf('/', SITES_FOLDER_POS); if (pos > 0) { // this assumes that the root path may likely start with something like "/sites/default/" // just cut the first 2 directories from the root path and do a direct lookup in the internal map return m_siteRootSites.get(rootPath.substring(0, pos)); } return null; } /** * Sets the class member variables {@link #m_siteMatcherSites} and {@link #m_siteMatchers} * from the provided map of configured site matchers.

* * @param siteMatcherSites the site matches to set */ private void setSiteMatcherSites(Map siteMatcherSites) { m_siteMatcherSites = Collections.unmodifiableMap(siteMatcherSites); m_siteMatchers = Collections.unmodifiableList(new ArrayList(m_siteMatcherSites.keySet())); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy