001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.staticexport;
029
030import org.opencms.file.CmsObject;
031import org.opencms.i18n.CmsLocaleManager;
032import org.opencms.i18n.CmsSingleTreeLocaleHandler;
033import org.opencms.main.OpenCms;
034import org.opencms.site.CmsSite;
035import org.opencms.util.CmsPair;
036import org.opencms.util.CmsStringUtil;
037import org.opencms.workplace.CmsWorkplace;
038
039import java.util.List;
040import java.util.Locale;
041import java.util.regex.Matcher;
042import java.util.regex.Pattern;
043
044/**
045 * Link substitution handler required to render single tree localized sites.<p>
046 */
047public class CmsLocalePrefixLinkSubstitutionHandler extends CmsDefaultLinkSubstitutionHandler {
048
049    /**
050     * @see org.opencms.staticexport.CmsDefaultLinkSubstitutionHandler#addVfsPrefix(org.opencms.file.CmsObject, java.lang.String, org.opencms.site.CmsSite, java.lang.String)
051     */
052    @Override
053    protected CmsPair<String, String> addVfsPrefix(
054        CmsObject cms,
055        String vfsName,
056        CmsSite targetSite,
057        String parameters) {
058
059        if (CmsSite.LocalizationMode.singleTree.equals(targetSite.getLocalizationMode())) {
060            // check if locale is specified via parameters
061            Locale localeFromParameter = null;
062            if (null != parameters) {
063                Pattern pattern = Pattern.compile("(.*)" + CmsLocaleManager.PARAMETER_LOCALE + "=([^&]*)(.*)");
064                Matcher matcher = pattern.matcher(parameters);
065                if (matcher.find()) {
066                    String localeFromParameterString = matcher.group(2);
067                    if ((localeFromParameterString != null) && !localeFromParameterString.isEmpty()) {
068                        Locale l = CmsLocaleManager.getLocale(localeFromParameterString);
069                        if (OpenCms.getLocaleManager().getAvailableLocales(cms, vfsName).contains(l)) {
070                            localeFromParameter = l;
071                            if (matcher.group(3).isEmpty()) {
072                                parameters = matcher.group(1).substring(0, matcher.group(1).length() - 1);
073                                if (parameters.isEmpty()) {
074                                    parameters = null;
075                                }
076                            } else {
077                                parameters = matcher.group(1) + matcher.group(3).substring(1);
078                            }
079                        }
080                    }
081                }
082            }
083            Locale requestedLocale = null == localeFromParameter
084            ? cms.getRequestContext().getLocale()
085            : localeFromParameter;
086            List<Locale> defaultLocales = OpenCms.getLocaleManager().getDefaultLocales(cms, vfsName);
087            List<Locale> availableLocales = OpenCms.getLocaleManager().getAvailableLocales(cms, vfsName);
088            Locale servedLocale = OpenCms.getLocaleManager().getBestMatchingLocale(
089                requestedLocale,
090                defaultLocales,
091                availableLocales);
092            // inject the current locale as a virtual path element
093            return new CmsPair<String, String>(
094                CmsStringUtil.joinPaths(
095                    OpenCms.getStaticExportManager().getVfsPrefix(),
096                    servedLocale.toString(),
097                    vfsName),
098                parameters);
099        } else {
100            return super.addVfsPrefix(cms, vfsName, targetSite, parameters);
101        }
102    }
103
104    /**
105     * @see org.opencms.staticexport.CmsDefaultLinkSubstitutionHandler#generateCacheKey(org.opencms.file.CmsObject, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
106     */
107    @Override
108    protected String generateCacheKey(
109        CmsObject cms,
110        String sourceSiteRoot,
111        String targetSiteRoot,
112        String detailPagePart,
113        String absoluteLink) {
114
115        return ""
116            + cms.getRequestContext().getCurrentUser().getId()
117            + ":"
118            + cms.getRequestContext().getSiteRoot()
119            + ":"
120            + sourceSiteRoot
121            + ":"
122            + targetSiteRoot
123            + ":"
124            + detailPagePart
125            + absoluteLink
126            + ":"
127            + cms.getRequestContext().getLocale().toString();
128    }
129
130    /**
131     * @see org.opencms.staticexport.CmsDefaultLinkSubstitutionHandler#getRootPathForSite(org.opencms.file.CmsObject, java.lang.String, java.lang.String, boolean)
132     */
133    @Override
134    protected String getRootPathForSite(CmsObject cms, String path, String siteRoot, boolean isRootPath) {
135
136        CmsSite site = OpenCms.getSiteManager().getSiteForSiteRoot(siteRoot);
137        if ((site != null) && CmsSite.LocalizationMode.singleTree.equals(site.getLocalizationMode())) {
138            if (isRootPath) {
139                path = path.substring(site.getSiteRoot().length());
140            }
141            Locale locale = CmsSingleTreeLocaleHandler.getLocaleFromPath(path);
142            if (locale != null) {
143                path = path.substring(locale.toString().length() + 1);
144            }
145            return cms.getRequestContext().addSiteRoot(site.getSiteRoot(), path);
146        } else {
147            return super.getRootPathForSite(cms, path, siteRoot, isRootPath);
148        }
149    }
150
151    /**
152     * @see org.opencms.staticexport.CmsDefaultLinkSubstitutionHandler#prepareExportParameters(org.opencms.file.CmsObject, java.lang.String, java.lang.String)
153     */
154    @Override
155    protected String prepareExportParameters(CmsObject cms, String vfsName, String parameters) {
156
157        CmsSite site = OpenCms.getSiteManager().getSiteForSiteRoot(cms.getRequestContext().getSiteRoot());
158        if ((site != null) && CmsSite.LocalizationMode.singleTree.equals(site.getLocalizationMode())) {
159            if (!(OpenCms.getSiteManager().startsWithShared(vfsName)
160                || vfsName.startsWith(CmsWorkplace.VFS_PATH_SYSTEM))) {
161                if (parameters != null) {
162                    parameters += "&";
163                } else {
164                    parameters = "?";
165                }
166                parameters += CmsLocaleManager.PARAMETER_LOCALE + "=" + cms.getRequestContext().getLocale().toString();
167            }
168        }
169        return parameters;
170    }
171}