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

org.opencms.ade.sitemap.CmsVfsSitemapService 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: 18.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, 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.ade.sitemap;

import org.opencms.ade.configuration.CmsADEConfigData;
import org.opencms.ade.configuration.CmsADEManager;
import org.opencms.ade.configuration.CmsFunctionReference;
import org.opencms.ade.configuration.CmsModelPageConfig;
import org.opencms.ade.configuration.CmsResourceTypeConfig;
import org.opencms.ade.detailpage.CmsDetailPageConfigurationWriter;
import org.opencms.ade.detailpage.CmsDetailPageInfo;
import org.opencms.ade.sitemap.shared.CmsClientSitemapEntry;
import org.opencms.ade.sitemap.shared.CmsClientSitemapEntry.EntryType;
import org.opencms.ade.sitemap.shared.CmsDetailPageTable;
import org.opencms.ade.sitemap.shared.CmsGalleryFolderEntry;
import org.opencms.ade.sitemap.shared.CmsGalleryType;
import org.opencms.ade.sitemap.shared.CmsLocaleComparePropertyData;
import org.opencms.ade.sitemap.shared.CmsModelInfo;
import org.opencms.ade.sitemap.shared.CmsModelPageEntry;
import org.opencms.ade.sitemap.shared.CmsNewResourceInfo;
import org.opencms.ade.sitemap.shared.CmsSitemapCategoryData;
import org.opencms.ade.sitemap.shared.CmsSitemapChange;
import org.opencms.ade.sitemap.shared.CmsSitemapChange.ChangeType;
import org.opencms.ade.sitemap.shared.CmsSitemapClipboardData;
import org.opencms.ade.sitemap.shared.CmsSitemapData;
import org.opencms.ade.sitemap.shared.CmsSitemapData.EditorMode;
import org.opencms.ade.sitemap.shared.CmsSitemapInfo;
import org.opencms.ade.sitemap.shared.rpc.I_CmsSitemapService;
import org.opencms.configuration.CmsDefaultUserSettings;
import org.opencms.db.CmsAlias;
import org.opencms.db.CmsAliasManager;
import org.opencms.db.CmsRewriteAlias;
import org.opencms.file.CmsFile;
import org.opencms.file.CmsObject;
import org.opencms.file.CmsProject;
import org.opencms.file.CmsProperty;
import org.opencms.file.CmsPropertyDefinition;
import org.opencms.file.CmsResource;
import org.opencms.file.CmsResourceFilter;
import org.opencms.file.CmsUser;
import org.opencms.file.CmsVfsResourceNotFoundException;
import org.opencms.file.history.CmsHistoryResourceHandler;
import org.opencms.file.types.CmsResourceTypeFolder;
import org.opencms.file.types.CmsResourceTypeFolderExtended;
import org.opencms.file.types.CmsResourceTypeFolderSubSitemap;
import org.opencms.file.types.CmsResourceTypeUnknownFolder;
import org.opencms.file.types.CmsResourceTypeXmlContainerPage;
import org.opencms.file.types.I_CmsResourceType;
import org.opencms.flex.CmsFlexController;
import org.opencms.gwt.CmsCoreService;
import org.opencms.gwt.CmsGwtService;
import org.opencms.gwt.CmsRpcException;
import org.opencms.gwt.CmsTemplateFinder;
import org.opencms.gwt.shared.CmsBrokenLinkBean;
import org.opencms.gwt.shared.CmsCategoryTreeEntry;
import org.opencms.gwt.shared.CmsClientLock;
import org.opencms.gwt.shared.CmsCoreData;
import org.opencms.gwt.shared.CmsCoreData.AdeContext;
import org.opencms.gwt.shared.CmsListInfoBean;
import org.opencms.gwt.shared.alias.CmsAliasEditValidationReply;
import org.opencms.gwt.shared.alias.CmsAliasEditValidationRequest;
import org.opencms.gwt.shared.alias.CmsAliasImportResult;
import org.opencms.gwt.shared.alias.CmsAliasInitialFetchResult;
import org.opencms.gwt.shared.alias.CmsAliasSaveValidationRequest;
import org.opencms.gwt.shared.alias.CmsAliasTableRow;
import org.opencms.gwt.shared.alias.CmsRewriteAliasTableRow;
import org.opencms.gwt.shared.alias.CmsRewriteAliasValidationReply;
import org.opencms.gwt.shared.alias.CmsRewriteAliasValidationRequest;
import org.opencms.gwt.shared.property.CmsClientProperty;
import org.opencms.gwt.shared.property.CmsPropertyModification;
import org.opencms.i18n.CmsLocaleManager;
import org.opencms.json.JSONArray;
import org.opencms.jsp.CmsJspNavBuilder;
import org.opencms.jsp.CmsJspNavBuilder.Visibility;
import org.opencms.jsp.CmsJspNavElement;
import org.opencms.loader.CmsLoaderException;
import org.opencms.lock.CmsLock;
import org.opencms.lock.CmsLockUtil;
import org.opencms.main.CmsException;
import org.opencms.main.CmsLog;
import org.opencms.main.OpenCms;
import org.opencms.relations.CmsCategory;
import org.opencms.relations.CmsCategoryService;
import org.opencms.search.galleries.CmsGallerySearch;
import org.opencms.search.galleries.CmsGallerySearchResult;
import org.opencms.security.CmsPermissionSet;
import org.opencms.security.CmsRole;
import org.opencms.security.CmsRoleViolationException;
import org.opencms.security.CmsSecurityException;
import org.opencms.site.CmsSite;
import org.opencms.ui.apps.CmsQuickLaunchLocationCache;
import org.opencms.util.CmsDateUtil;
import org.opencms.util.CmsFileUtil;
import org.opencms.util.CmsStringUtil;
import org.opencms.util.CmsUUID;
import org.opencms.workplace.CmsWorkplaceManager;
import org.opencms.workplace.CmsWorkplaceMessages;
import org.opencms.workplace.explorer.CmsExplorerTypeAccess;
import org.opencms.workplace.explorer.CmsExplorerTypeSettings;
import org.opencms.workplace.galleries.A_CmsAjaxGallery;
import org.opencms.xml.CmsXmlException;
import org.opencms.xml.I_CmsXmlDocument;
import org.opencms.xml.containerpage.CmsADESessionCache;
import org.opencms.xml.containerpage.CmsContainerBean;
import org.opencms.xml.containerpage.CmsContainerElementBean;
import org.opencms.xml.containerpage.CmsContainerPageBean;
import org.opencms.xml.containerpage.CmsDynamicFunctionBean;
import org.opencms.xml.containerpage.CmsXmlContainerPage;
import org.opencms.xml.containerpage.CmsXmlContainerPageFactory;
import org.opencms.xml.content.CmsXmlContentFactory;
import org.opencms.xml.content.CmsXmlContentProperty;
import org.opencms.xml.types.I_CmsXmlContentValue;

import java.io.Closeable;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;

import com.google.common.collect.ComparisonChain;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Ordering;

/**
 * Handles all RPC services related to the vfs sitemap.

* * @since 8.0.0 * * @see org.opencms.ade.sitemap.shared.rpc.I_CmsSitemapService * @see org.opencms.ade.sitemap.shared.rpc.I_CmsSitemapServiceAsync */ public class CmsVfsSitemapService extends CmsGwtService implements I_CmsSitemapService { /** Helper class for representing information about a lock. */ protected class LockInfo { /** The lock state. */ private CmsLock m_lock; /** True if the lock was just locked. */ private boolean m_wasJustLocked; /** * Creates a new LockInfo object.

* * @param lock the lock state * @param wasJustLocked true if the lock was just locked */ public LockInfo(CmsLock lock, boolean wasJustLocked) { m_lock = lock; m_wasJustLocked = wasJustLocked; } /** * Returns the lock state.

* * @return the lock state */ public CmsLock getLock() { return m_lock; } /** * Returns true if the lock was just locked.

* * @return true if the lock was just locked */ public boolean wasJustLocked() { return m_wasJustLocked; } } /** The path of the JSP used to download aliases. */ public static final String ALIAS_DOWNLOAD_PATH = "/system/workplace/commons/download-aliases.jsp"; /** The path to the JSP used to upload aliases. */ public static final String ALIAS_IMPORT_PATH = "/system/workplace/commons/import-aliases.jsp"; /** The show model edit confirm dialog attribute name. */ public static final String ATTR_SHOW_MODEL_EDIT_CONFIRM = "showModelEditConfirm"; /** The galleries folder name. */ public static final String GALLERIES_FOLDER_NAME = ".galleries"; /** The configuration key for the functionDetail attribute in the container.info property. */ public static final String KEY_FUNCTION_DETAIL = "functionDetail"; /** The additional user info key for deleted list. */ private static final String ADDINFO_ADE_DELETED_LIST = "ADE_DELETED_LIST"; /** The additional user info key for modified list. */ private static final String ADDINFO_ADE_MODIFIED_LIST = "ADE_MODIFIED_LIST"; /** The lock table to prevent multiple users from editing the alias table concurrently. */ private static CmsAliasEditorLockTable aliasEditorLockTable = new CmsAliasEditorLockTable(); /** The table containing the alias import results. */ private static CmsAliasImportResponseTable aliasImportResponseTable = new CmsAliasImportResponseTable(); /** The static log object for this class. */ private static final Log LOG = CmsLog.getLog(CmsVfsSitemapService.class); /** The redirect recource type name. */ private static final String RECOURCE_TYPE_NAME_REDIRECT = "htmlredirect"; /** The redirect target XPath. */ private static final String REDIRECT_LINK_TARGET_XPATH = "Link"; /** Serialization uid. */ private static final long serialVersionUID = -7236544324371767330L; /** The VFS path of the redirect copy page for navigation level entries. */ private static final String SUB_LEVEL_REDIRECT_COPY_PAGE = "/system/modules/org.opencms.ade.config/copyresources/sub-level-redirect.html"; /** The navigation builder. */ private CmsJspNavBuilder m_navBuilder; /** * Adds an alias import result.

* * @param results the list of alias import results to add * * @return the key to retrieve the alias import results */ public static String addAliasImportResult(List results) { return aliasImportResponseTable.addImportResult(results); } /** * Creates a client property bean from a server-side property.

* * @param prop the property from which to create the client property * @param preserveOrigin if true, the origin will be copied into the new object * * @return the new client property */ public static CmsClientProperty createClientProperty(CmsProperty prop, boolean preserveOrigin) { CmsClientProperty result = new CmsClientProperty( prop.getName(), prop.getStructureValue(), prop.getResourceValue()); if (preserveOrigin) { result.setOrigin(prop.getOrigin()); } return result; } /** * Fetches the sitemap data.

* * @param request the current request * @param sitemapUri the site relative path * * @return the sitemap data * * @throws CmsRpcException if something goes wrong */ public static CmsSitemapData prefetch(HttpServletRequest request, String sitemapUri) throws CmsRpcException { CmsVfsSitemapService service = new CmsVfsSitemapService(); service.setCms(CmsFlexController.getCmsObject(request)); service.setRequest(request); CmsSitemapData result = null; try { result = service.prefetch(sitemapUri); } finally { service.clearThreadStorage(); } return result; } /** * Converts a sequence of properties to a map of client-side property beans.

* * @param props the sequence of properties * @param preserveOrigin if true, the origin of the properties should be copied to the client properties * * @return the map of client properties * */ static Map createClientProperties(Iterable props, boolean preserveOrigin) { Map result = new HashMap(); for (CmsProperty prop : props) { CmsClientProperty clientProp = createClientProperty(prop, preserveOrigin); result.put(prop.getName(), clientProp); } return result; } /** * @see org.opencms.ade.sitemap.shared.rpc.I_CmsSitemapService#changeCategory(java.lang.String, org.opencms.util.CmsUUID, java.lang.String, java.lang.String) */ public void changeCategory(String entryPoint, CmsUUID id, String title, String name) throws CmsRpcException { try { name = OpenCms.getResourceManager().getFileTranslator().translateResource(name.trim().replace('/', '-')); CmsObject cms = getCmsObject(); CmsResource categoryResource = cms.readResource(id); ensureLock(categoryResource); String sitePath = cms.getSitePath(categoryResource); String newPath = CmsStringUtil.joinPaths(CmsResource.getParentFolder(sitePath), name); cms.writePropertyObject(sitePath, new CmsProperty(CmsPropertyDefinition.PROPERTY_TITLE, title, null)); if (!CmsStringUtil.joinPaths("/", newPath, "/").equals(CmsStringUtil.joinPaths("/", sitePath, "/"))) { cms.moveResource(sitePath, newPath); } } catch (Exception e) { error(e); } } /** * @see org.opencms.gwt.CmsGwtService#checkPermissions(org.opencms.file.CmsObject) */ @Override public void checkPermissions(CmsObject cms) throws CmsRoleViolationException { OpenCms.getRoleManager().checkRole(cms, CmsRole.EDITOR); } /** * @see org.opencms.ade.sitemap.shared.rpc.I_CmsSitemapService#createCategory(java.lang.String, org.opencms.util.CmsUUID, java.lang.String, java.lang.String) */ public void createCategory(String entryPoint, CmsUUID id, String title, String name) throws CmsRpcException { try { name = OpenCms.getResourceManager().getFileTranslator().translateResource(name.trim().replace('/', '-')); CmsObject cms = getCmsObject(); CmsCategoryService catService = CmsCategoryService.getInstance(); CmsCategory createdCategory = null; if (id.isNullUUID()) { String localRepositoryPath = CmsStringUtil.joinPaths( entryPoint, CmsCategoryService.getInstance().getRepositoryBaseFolderName(getCmsObject())); // ensure category repository exists if (!cms.existsResource(localRepositoryPath)) { tryUnlock( cms.createResource( localRepositoryPath, OpenCms.getResourceManager().getResourceType(CmsResourceTypeFolder.getStaticTypeName()))); } createdCategory = catService.createCategory(cms, null, name, title, "", localRepositoryPath); } else { CmsResource parentResource = cms.readResource(id); CmsCategory parent = catService.getCategory(cms, parentResource); createdCategory = catService.createCategory( cms, parent, name, title, "", cms.getRequestContext().removeSiteRoot(parentResource.getRootPath())); } tryUnlock(cms.readResource(createdCategory.getId())); } catch (Exception e) { error(e); } } /** * @see org.opencms.ade.sitemap.shared.rpc.I_CmsSitemapService#createNewGalleryFolder(java.lang.String, java.lang.String, int) */ public CmsGalleryFolderEntry createNewGalleryFolder(String parentFolder, String title, int folderTypeId) throws CmsRpcException { CmsObject cms = getCmsObject(); CmsGalleryFolderEntry folderEntry = null; try { if (!cms.existsResource(parentFolder, CmsResourceFilter.IGNORE_EXPIRATION)) { CmsResource parent = cms.createResource( parentFolder, OpenCms.getResourceManager().getResourceType(CmsResourceTypeFolder.getStaticTypeName())); tryUnlock(parent); } String folderName = OpenCms.getResourceManager().getFileTranslator().translateResource(title); folderName = OpenCms.getResourceManager().getNameGenerator().getUniqueFileName( cms, parentFolder, folderName); String folderPath = CmsStringUtil.joinPaths(parentFolder, folderName); @SuppressWarnings("deprecation") CmsResource galleryFolder = cms.createResource( folderPath, folderTypeId, null, Collections.singletonList(new CmsProperty(CmsPropertyDefinition.PROPERTY_TITLE, title, null))); folderEntry = readGalleryFolderEntry( galleryFolder, OpenCms.getResourceManager().getResourceType(galleryFolder).getTypeName()); tryUnlock(galleryFolder); } catch (CmsException e) { error(e); } return folderEntry; } /** * @see org.opencms.ade.sitemap.shared.rpc.I_CmsSitemapService#createNewModelPage(java.lang.String, java.lang.String, java.lang.String, org.opencms.util.CmsUUID, boolean) */ public CmsModelPageEntry createNewModelPage( String entryPointUri, String title, String description, CmsUUID copyId, boolean isModelGroup) throws CmsRpcException { try { CmsObject cms = getCmsObject(); CmsResource rootResource = cms.readResource(entryPointUri); CmsModelPageHelper helper = new CmsModelPageHelper(getCmsObject(), rootResource); CmsResource page; if (isModelGroup) { page = helper.createModelGroupPage(title, description, copyId); } else { page = helper.createPageInModelFolder(title, description, copyId); String configPath = CmsStringUtil.joinPaths(entryPointUri, ".content/.config"); CmsResource configResource = cms.readResource(configPath); helper.addModelPageToSitemapConfiguration(configResource, page, false); } CmsModelPageEntry result = helper.createModelPageEntry(page, false, false, getWorkplaceLocale()); OpenCms.getADEManager().waitForCacheUpdate(false); return result; } catch (Throwable e) { error(e); return null; } } /** * @see org.opencms.ade.sitemap.shared.rpc.I_CmsSitemapService#createSubSitemap(org.opencms.util.CmsUUID) */ public CmsSitemapChange createSubSitemap(CmsUUID entryId) throws CmsRpcException { CmsObject cms = getCmsObject(); try { ensureSession(); CmsResource subSitemapFolder = cms.readResource(entryId); ensureLock(subSitemapFolder); String sitePath = cms.getSitePath(subSitemapFolder); createSitemapContentFolder(cms, subSitemapFolder); subSitemapFolder.setType(getSubsitemapType()); cms.writeResource(subSitemapFolder); tryUnlock(subSitemapFolder); CmsSitemapClipboardData clipboard = getClipboardData(); CmsClientSitemapEntry entry = toClientEntry( getNavBuilder().getNavigationForResource(sitePath, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED), false); clipboard.addModified(entry); setClipboardData(clipboard); CmsSitemapChange result = new CmsSitemapChange(entry.getId(), entry.getSitePath(), ChangeType.modify); result.setUpdatedEntry(entry); return result; } catch (Exception e) { error(e); } return null; } /** * @see org.opencms.ade.sitemap.shared.rpc.I_CmsSitemapService#disableModelPage(java.lang.String, org.opencms.util.CmsUUID, boolean) */ public void disableModelPage(String baseUri, CmsUUID modelPageId, boolean disabled) throws CmsRpcException { try { CmsObject cms = getCmsObject(); CmsResource rootResource = cms.readResource(baseUri); CmsModelPageHelper helper = new CmsModelPageHelper(getCmsObject(), rootResource); String configPath = CmsStringUtil.joinPaths(baseUri, ".content/.config"); CmsResource configResource = cms.readResource(configPath); helper.disableModelPage(configResource, modelPageId, disabled); OpenCms.getADEManager().waitForCacheUpdate(false); } catch (Throwable e) { error(e); } } /** * @see org.opencms.ade.sitemap.shared.rpc.I_CmsSitemapService#getAliasImportResult(java.lang.String) */ public List getAliasImportResult(String resultKey) { return aliasImportResponseTable.getAndRemove(resultKey); } /** * @see org.opencms.ade.sitemap.shared.rpc.I_CmsSitemapService#getAliasTable() */ public CmsAliasInitialFetchResult getAliasTable() throws CmsRpcException { try { CmsObject cms = getCmsObject(); CmsAliasManager aliasManager = OpenCms.getAliasManager(); List aliases = aliasManager.getAliasesForSite(cms, cms.getRequestContext().getSiteRoot()); List rows = new ArrayList(); CmsAliasInitialFetchResult result = new CmsAliasInitialFetchResult(); for (CmsAlias alias : aliases) { CmsAliasTableRow row = createAliasTableEntry(cms, alias); rows.add(row); } result.setRows(rows); List rewriteAliases = aliasManager.getRewriteAliases( cms, cms.getRequestContext().getSiteRoot()); List rewriteRows = new ArrayList(); for (CmsRewriteAlias rewriteAlias : rewriteAliases) { CmsRewriteAliasTableRow rewriteRow = new CmsRewriteAliasTableRow( rewriteAlias.getId(), rewriteAlias.getPatternString(), rewriteAlias.getReplacementString(), rewriteAlias.getMode()); rewriteRows.add(rewriteRow); } result.setRewriteRows(rewriteRows); CmsUser otherLockOwner = aliasEditorLockTable.update(cms, cms.getRequestContext().getSiteRoot()); if (otherLockOwner != null) { result.setAliasLockOwner(otherLockOwner.getName()); } result.setDownloadUrl(OpenCms.getLinkManager().substituteLinkForRootPath(cms, ALIAS_DOWNLOAD_PATH)); return result; } catch (Throwable e) { error(e); return null; } } /** * @see org.opencms.ade.sitemap.shared.rpc.I_CmsSitemapService#getCategoryData(java.lang.String) */ public CmsSitemapCategoryData getCategoryData(String entryPoint) throws CmsRpcException { CmsObject cms = getCmsObject(); try { CmsResource entryPointResource = cms.readResource(entryPoint); String basePath = CmsStringUtil.joinPaths( entryPointResource.getRootPath(), CmsCategoryService.getInstance().getRepositoryBaseFolderName(getCmsObject())); List entries = CmsCoreService.getCategoriesForSitePathStatic( cms, entryPoint, cms.getRequestContext().removeSiteRoot(basePath)); CmsSitemapCategoryData categoryData = new CmsSitemapCategoryData(); for (CmsCategoryTreeEntry entry : entries) { categoryData.add(entry); } categoryData.setBasePath(basePath); return categoryData; } catch (Exception e) { error(e); return null; } } /** * @see org.opencms.ade.sitemap.shared.rpc.I_CmsSitemapService#getChildren(java.lang.String, org.opencms.util.CmsUUID, int) */ public CmsClientSitemapEntry getChildren(String entryPointUri, CmsUUID entryId, int levels) throws CmsRpcException { CmsClientSitemapEntry entry = null; try { CmsObject cms = getCmsObject(); //ensure that root ends with a '/' if it's a folder CmsResource rootRes = cms.readResource(entryId, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); String root = cms.getSitePath(rootRes); CmsJspNavElement navElement = getNavBuilder().getNavigationForResource( root, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); boolean isRoot = root.equals(entryPointUri); entry = toClientEntry(navElement, isRoot); if ((levels > 0) && (isRoot || (rootRes.isFolder()))) { entry.setSubEntries(getChildren(root, levels, null), null); } } catch (Throwable e) { error(e); } return entry; } /** * @see org.opencms.ade.sitemap.shared.rpc.I_CmsSitemapService#getGalleryData(java.lang.String) */ public Map> getGalleryData(String entryPointUri) { List subSitePaths = OpenCms.getADEManager().getSubSitePaths( getCmsObject(), getCmsObject().getRequestContext().addSiteRoot(entryPointUri)); List galleryTypes = collectGalleryTypes(); Map> result = new HashMap>(); for (CmsGalleryType type : galleryTypes) { List galleries = null; try { galleries = getGalleriesForType(entryPointUri, type, subSitePaths); } catch (CmsException e) { log(e.getLocalizedMessage(), e); } result.put(type, galleries); } return result; } /** * @see org.opencms.ade.sitemap.shared.rpc.I_CmsSitemapService#getModelInfos(org.opencms.util.CmsUUID) */ public CmsModelInfo getModelInfos(CmsUUID rootId) throws CmsRpcException { try { CmsObject cms = getCmsObject(); CmsResource rootResource = cms.readResource(rootId); CmsModelPageHelper modelPageHelper = new CmsModelPageHelper(getCmsObject(), rootResource); return modelPageHelper.getModelInfo(); } catch (Throwable e) { error(e); return null; // will never be reached } } /** * @see org.opencms.ade.sitemap.shared.rpc.I_CmsSitemapService#getNewElementInfo(java.lang.String) */ public List getNewElementInfo(String entryPointUri) throws CmsRpcException { try { CmsObject cms = getCmsObject(); String rootPath = cms.getRequestContext().addSiteRoot(entryPointUri); CmsADEConfigData config = OpenCms.getADEManager().lookupConfiguration(cms, rootPath); List result = getNewResourceInfos(cms, config, getWorkplaceLocale()); return result; } catch (Throwable e) { error(e); return null; } } /** * @see org.opencms.ade.sitemap.shared.rpc.I_CmsSitemapService#loadPropertyDataForLocaleCompareView(org.opencms.util.CmsUUID, org.opencms.util.CmsUUID) */ public CmsLocaleComparePropertyData loadPropertyDataForLocaleCompareView(CmsUUID id, CmsUUID rootId) throws CmsRpcException { try { CmsLocaleComparePropertyData result = new CmsLocaleComparePropertyData(); CmsObject cms = getCmsObject(); CmsResourceFilter filter = CmsResourceFilter.IGNORE_EXPIRATION; CmsResource resource = cms.readResource(id, filter); CmsResource defaultFile = cms.readDefaultFile(id.toString()); result.setDefaultFileId(defaultFile != null ? defaultFile.getStructureId() : null); result.setId(id); result.setFolder(resource.isFolder()); List props = cms.readPropertyObjects(resource, false); List defaultFileProps = cms.readPropertyObjects(defaultFile, false); Map clientProps = createClientProperties(props, true); Map clientDefaultFileProps = createClientProperties(defaultFileProps, true); result.setOwnProperties(clientProps); result.setDefaultFileProperties(clientDefaultFileProps); CmsResource parent = cms.readParentFolder(resource.getStructureId()); List resourcesInSameFolder = cms.readResources(parent, CmsResourceFilter.ALL, false); List forbiddenUrlNames = Lists.newArrayList(); for (CmsResource resourceInSameFolder : resourcesInSameFolder) { String otherName = CmsResource.getName(resourceInSameFolder.getRootPath()); forbiddenUrlNames.add(otherName); } result.setForbiddenUrlNames(forbiddenUrlNames); result.setInheritedProperties(createClientProperties(cms.readPropertyObjects(parent, true), true)); result.setPath(resource.getRootPath()); String name = CmsFileUtil.removeTrailingSeparator(CmsResource.getName(resource.getRootPath())); result.setName(name); result.setHasEditableName(!CmsStringUtil.isEmptyOrWhitespaceOnly(name)); return result; } catch (Exception e) { error(e); return null; } } /** * @see org.opencms.ade.sitemap.shared.rpc.I_CmsSitemapService#mergeSubSitemap(java.lang.String, org.opencms.util.CmsUUID) */ @SuppressWarnings("deprecation") public CmsSitemapChange mergeSubSitemap(String entryPoint, CmsUUID subSitemapId) throws CmsRpcException { CmsObject cms = getCmsObject(); try { ensureSession(); CmsResource subSitemapFolder = cms.readResource(subSitemapId, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); ensureLock(subSitemapFolder); subSitemapFolder.setType( OpenCms.getResourceManager().getResourceType(CmsResourceTypeFolder.RESOURCE_TYPE_NAME).getTypeId()); cms.writeResource(subSitemapFolder); String sitePath = cms.getSitePath(subSitemapFolder); String sitemapConfigName = CmsStringUtil.joinPaths( sitePath, CmsADEManager.CONTENT_FOLDER_NAME, CmsADEManager.CONFIG_FILE_NAME); if (cms.existsResource(sitemapConfigName)) { cms.deleteResource(sitemapConfigName, CmsResource.DELETE_PRESERVE_SIBLINGS); } tryUnlock(subSitemapFolder); CmsSitemapClipboardData clipboard = getClipboardData(); CmsClientSitemapEntry entry = toClientEntry( getNavBuilder().getNavigationForResource( cms.getSitePath(subSitemapFolder), CmsResourceFilter.ONLY_VISIBLE_NO_DELETED), false); clipboard.addModified(entry); setClipboardData(clipboard); entry = getChildren(entryPoint, subSitemapId, 1); CmsSitemapChange result = new CmsSitemapChange(entry.getId(), entry.getSitePath(), ChangeType.modify); result.setUpdatedEntry(entry); return result; } catch (Exception e) { error(e); } return null; } /** * @see org.opencms.ade.sitemap.shared.rpc.I_CmsSitemapService#prefetch(java.lang.String) */ public CmsSitemapData prefetch(String sitemapUri) throws CmsRpcException { CmsSitemapData result = null; CmsObject cms = getCmsObject(); try { OpenCms.getRoleManager().checkRole(cms, CmsRole.EDITOR); String openPath = getRequest().getParameter(CmsCoreData.PARAM_PATH); if (!isValidOpenPath(cms, openPath)) { // if no path is supplied, start from root openPath = "/"; } CmsQuickLaunchLocationCache.getLocationCache(getRequest().getSession()).setSitemapEditorLocation( cms.getRequestContext().getSiteRoot(), openPath); CmsADEConfigData configData = OpenCms.getADEManager().lookupConfiguration( cms, cms.getRequestContext().addSiteRoot(openPath)); Map propertyConfig = new LinkedHashMap( configData.getPropertyConfigurationAsMap()); Map parentProperties = generateParentProperties(configData.getBasePath()); String siteRoot = cms.getRequestContext().getSiteRoot(); String exportRfsPrefix = OpenCms.getStaticExportManager().getDefaultRfsPrefix(); CmsSite site = OpenCms.getSiteManager().getSiteForSiteRoot(siteRoot); boolean isSecure = (site != null) && site.hasSecureServer(); String parentSitemap = null; if (configData.getBasePath() != null) { CmsADEConfigData parentConfigData = OpenCms.getADEManager().lookupConfiguration( cms, CmsResource.getParentFolder(configData.getBasePath())); parentSitemap = parentConfigData.getBasePath(); if (parentSitemap != null) { parentSitemap = cms.getRequestContext().removeSiteRoot(parentSitemap); } } String noEdit = ""; CmsNewResourceInfo defaultNewInfo = null; List newResourceInfos = null; CmsDetailPageTable detailPages = null; List resourceTypeInfos = null; boolean canEditDetailPages = false; boolean isOnlineProject = CmsProject.isOnlineProject(cms.getRequestContext().getCurrentProject().getUuid()); String defaultGalleryFolder = GALLERIES_FOLDER_NAME; try { CmsObject rootCms = OpenCms.initCmsObject(cms); rootCms.getRequestContext().setSiteRoot(""); CmsResource baseDir = rootCms.readResource( configData.getBasePath(), CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); CmsProperty galleryFolderProp = cms.readPropertyObject( baseDir, CmsPropertyDefinition.PROPERTY_GALLERIES_FOLDER, true); if (!galleryFolderProp.isNullProperty() && CmsStringUtil.isNotEmptyOrWhitespaceOnly(galleryFolderProp.getValue())) { defaultGalleryFolder = galleryFolderProp.getValue(); } } catch (CmsException e) { LOG.warn(e.getLocalizedMessage(), e); } detailPages = new CmsDetailPageTable(configData.getAllDetailPages()); if (!isOnlineProject) { newResourceInfos = getNewResourceInfos(cms, configData, getWorkplaceLocale()); CmsResource modelResource = null; if (configData.getDefaultModelPage() != null) { if (cms.existsResource(configData.getDefaultModelPage().getResource().getStructureId())) { modelResource = configData.getDefaultModelPage().getResource(); } else { try { modelResource = cms.readResource( cms.getSitePath(configData.getDefaultModelPage().getResource()), CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); } catch (CmsException e) { LOG.warn(e.getLocalizedMessage(), e); } } } if ((modelResource == null) && !newResourceInfos.isEmpty()) { try { modelResource = cms.readResource(newResourceInfos.get(0).getCopyResourceId()); } catch (CmsException e) { LOG.warn(e.getLocalizedMessage(), e); } } if (modelResource != null) { resourceTypeInfos = getResourceTypeInfos( getCmsObject(), configData.getResourceTypes(), configData.getFunctionReferences(), modelResource, getWorkplaceLocale()); try { defaultNewInfo = createNewResourceInfo(cms, modelResource, getWorkplaceLocale()); } catch (CmsException e) { LOG.warn(e.getLocalizedMessage(), e); } } canEditDetailPages = !(configData.isModuleConfiguration()); } if (isOnlineProject) { noEdit = Messages.get().getBundle(getWorkplaceLocale()).key(Messages.GUI_SITEMAP_NO_EDIT_ONLINE_0); } List allPropNames = getPropertyNames(cms); String returnCode = getRequest().getParameter(CmsCoreData.PARAM_RETURNCODE); if (!isValidReturnCode(returnCode)) { returnCode = null; } cms.getRequestContext().getSiteRoot(); String aliasImportUrl = OpenCms.getLinkManager().substituteLinkForRootPath(cms, ALIAS_IMPORT_PATH); boolean canEditAliases = OpenCms.getAliasManager().hasPermissionsForMassEdit(cms, siteRoot); List subsitemapFolderTypeInfos = collectSitemapTypeInfos(cms, configData); // evaluate the editor mode EditorMode editorMode = CmsADESessionCache.getCache(getRequest(), getCmsObject()).getSitemapEditorMode(); if ((editorMode == null) || (editorMode == EditorMode.compareLocales)) { editorMode = EditorMode.navigation; } String basePath = configData.getBasePath(); if (!cms.existsResource( cms.getRequestContext().removeSiteRoot(basePath), CmsResourceFilter.ONLY_VISIBLE_NO_DELETED)) { basePath = cms.getRequestContext().getSiteRoot(); } Boolean showModelEditConfirm = (Boolean)getRequest().getSession().getAttribute( ATTR_SHOW_MODEL_EDIT_CONFIRM); if (showModelEditConfirm == null) { showModelEditConfirm = Boolean.TRUE; } boolean showLocaleComparison = !(getCmsObject().getRequestContext().getCurrentProject().isOnlineProject()) && (site != null) && (site.getMainTranslationLocale(null) != null); result = new CmsSitemapData( (new CmsTemplateFinder(cms)).getTemplates(), propertyConfig, getClipboardData(), CmsCoreService.getContextMenuEntries( cms, configData.getResource().getStructureId(), AdeContext.sitemap), parentProperties, allPropNames, exportRfsPrefix, isSecure, noEdit, isDisplayToolbar(getRequest()), defaultNewInfo, newResourceInfos, createResourceTypeInfo(OpenCms.getResourceManager().getResourceType(RECOURCE_TYPE_NAME_REDIRECT), null), createNavigationLevelTypeInfo(), getSitemapInfo(basePath), parentSitemap, getRootEntry(basePath, CmsResource.getFolderPath(openPath)), openPath, 30, detailPages, resourceTypeInfos, returnCode, canEditDetailPages, aliasImportUrl, canEditAliases, OpenCms.getWorkplaceManager().getDefaultUserSettings().getSubsitemapCreationMode() == CmsDefaultUserSettings.SubsitemapCreationMode.createfolder, OpenCms.getRoleManager().hasRole(cms, CmsRole.GALLERY_EDITOR), OpenCms.getRoleManager().hasRole(cms, CmsRole.CATEGORY_EDITOR), subsitemapFolderTypeInfos, editorMode, defaultGalleryFolder, showModelEditConfirm.booleanValue()); CmsUUID rootId = cms.readResource("/", CmsResourceFilter.ALL).getStructureId(); result.setSiteRootId(rootId); result.setLocaleComparisonEnabled(showLocaleComparison); } catch (Throwable e) { error(e); } return result; } /** * @see org.opencms.ade.sitemap.shared.rpc.I_CmsSitemapService#prepareReloadSitemap(org.opencms.util.CmsUUID, org.opencms.ade.sitemap.shared.CmsSitemapData.EditorMode) */ public String prepareReloadSitemap(CmsUUID rootId, EditorMode mode) throws CmsRpcException { try { CmsObject cms = getCmsObject(); CmsResource res = cms.readResource(CmsADEManager.PATH_SITEMAP_EDITOR_JSP); CmsResource target = cms.readResource(rootId, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); String targetRootPath = OpenCms.getADEManager().getSubSiteRoot(cms, target.getRootPath()); CmsSite targetSite = OpenCms.getSiteManager().getSiteForRootPath(targetRootPath); CmsADESessionCache.getCache(getRequest(), getCmsObject()).setSitemapEditorMode(mode); if (targetSite != null) { cms.getRequestContext().setSiteRoot(targetSite.getSiteRoot()); String path = cms.getRequestContext().removeSiteRoot(targetRootPath); String link = OpenCms.getLinkManager().substituteLink(cms, res); link = link + "?path=" + path; return link; } return null; } catch (Exception e) { error(e); return null; } } /** * @see org.opencms.ade.sitemap.shared.rpc.I_CmsSitemapService#removeModelPage(java.lang.String, org.opencms.util.CmsUUID) */ public void removeModelPage(String entryPointUri, CmsUUID id) throws CmsRpcException { try { CmsObject cms = getCmsObject(); CmsResource rootResource = cms.readResource(entryPointUri); CmsModelPageHelper helper = new CmsModelPageHelper(getCmsObject(), rootResource); String configPath = CmsStringUtil.joinPaths(entryPointUri, ".content/.config"); CmsResource configResource = cms.readResource(configPath); helper.removeModelPage(configResource, id); OpenCms.getADEManager().waitForCacheUpdate(false); } catch (Throwable e) { error(e); } } /** * @see org.opencms.ade.sitemap.shared.rpc.I_CmsSitemapService#save(java.lang.String, org.opencms.ade.sitemap.shared.CmsSitemapChange) */ public CmsSitemapChange save(String entryPoint, CmsSitemapChange change) throws CmsRpcException { CmsSitemapChange result = null; try { result = saveInternal(entryPoint, change); } catch (Exception e) { error(e); } return result; } /** * @see org.opencms.ade.sitemap.shared.rpc.I_CmsSitemapService#saveAliases(org.opencms.gwt.shared.alias.CmsAliasSaveValidationRequest) */ public CmsAliasEditValidationReply saveAliases(CmsAliasSaveValidationRequest saveRequest) throws CmsRpcException { CmsObject cms = getCmsObject(); CmsAliasBulkEditHelper helper = new CmsAliasBulkEditHelper(cms); try { return helper.saveAliases(saveRequest); } catch (Exception e) { error(e); return null; } } /** * @see org.opencms.ade.sitemap.shared.rpc.I_CmsSitemapService#savePropertiesForLocaleCompareMode(org.opencms.util.CmsUUID, java.lang.String, java.util.List, boolean) */ public void savePropertiesForLocaleCompareMode( CmsUUID id, String newUrlName, List propertyChanges, boolean editedName) throws CmsRpcException { try { CmsObject cms = getCmsObject(); CmsResource ownRes = cms.readResource(id, CmsResourceFilter.IGNORE_EXPIRATION); CmsResource defaultFileRes = cms.readDefaultFile("" + id); try (Closeable c = CmsLockUtil.withLockedResources(cms, ownRes)) { updateProperties(cms, ownRes, defaultFileRes, propertyChanges); if (editedName) { String parent = CmsResource.getParentFolder(ownRes.getRootPath()); newUrlName = CmsFileUtil.removeTrailingSeparator(newUrlName); String newPath = CmsStringUtil.joinPaths(parent, newUrlName); CmsObject rootCms = OpenCms.initCmsObject(cms); rootCms.getRequestContext().setSiteRoot(""); rootCms.moveResource(ownRes.getRootPath(), newPath); } } } catch (Exception e) { error(e); } } /** * @see org.opencms.ade.sitemap.shared.rpc.I_CmsSitemapService#saveSync(java.lang.String, org.opencms.ade.sitemap.shared.CmsSitemapChange) */ public CmsSitemapChange saveSync(String entryPoint, CmsSitemapChange change) throws CmsRpcException { return save(entryPoint, change); } /** * @see org.opencms.ade.sitemap.shared.rpc.I_CmsSitemapService#setDefaultModel(org.opencms.util.CmsUUID, org.opencms.util.CmsUUID) */ public CmsModelInfo setDefaultModel(CmsUUID rootId, CmsUUID modelId) throws CmsRpcException { CmsModelInfo result = null; try { CmsObject cms = getCmsObject(); CmsResource rootResource = cms.readResource(rootId); CmsModelPageHelper modelPageHelper = new CmsModelPageHelper(getCmsObject(), rootResource); CmsResource configFile = OpenCms.getADEManager().lookupConfiguration( cms, rootResource.getRootPath()).getResource(); ensureLock(configFile); result = modelPageHelper.setDefaultModelPage(configFile, modelId); tryUnlock(configFile); } catch (Throwable e) { error(e); } return result; } /** * @see org.opencms.ade.sitemap.shared.rpc.I_CmsSitemapService#setEditorMode(org.opencms.ade.sitemap.shared.CmsSitemapData.EditorMode) */ public void setEditorMode(EditorMode editorMode) { CmsADESessionCache.getCache(getRequest(), getCmsObject()).setSitemapEditorMode(editorMode); } /** * @see org.opencms.ade.sitemap.shared.rpc.I_CmsSitemapService#updateAliasEditorStatus(boolean) */ public void updateAliasEditorStatus(boolean editing) { CmsObject cms = getCmsObject(); if (editing) { aliasEditorLockTable.update(cms, cms.getRequestContext().getSiteRoot()); } else { aliasEditorLockTable.clear(cms, cms.getRequestContext().getSiteRoot()); } } /** * @see org.opencms.ade.sitemap.shared.rpc.I_CmsSitemapService#validateAliases(org.opencms.gwt.shared.alias.CmsAliasEditValidationRequest) */ public CmsAliasEditValidationReply validateAliases(CmsAliasEditValidationRequest validationRequest) { CmsObject cms = getCmsObject(); CmsAliasBulkEditHelper helper = new CmsAliasBulkEditHelper(cms); return helper.validateAliases(validationRequest); } /** * @see org.opencms.ade.sitemap.shared.rpc.I_CmsSitemapService#validateRewriteAliases(org.opencms.gwt.shared.alias.CmsRewriteAliasValidationRequest) */ public CmsRewriteAliasValidationReply validateRewriteAliases(CmsRewriteAliasValidationRequest validationRequest) { CmsRewriteAliasValidationReply result = new CmsRewriteAliasValidationReply(); for (CmsRewriteAliasTableRow editedRow : validationRequest.getEditedRewriteAliases()) { try { String patternString = editedRow.getPatternString(); Pattern.compile(patternString); } catch (PatternSyntaxException e) { result.addError(editedRow.getId(), "Syntax error in regular expression: " + e.getMessage()); } } return result; } /** * Creates a "broken link" bean based on a resource.

* * @param resource the resource * * @return the "broken link" bean with the data from the resource * * @throws CmsException if something goes wrong */ protected CmsBrokenLinkBean createSitemapBrokenLinkBean(CmsResource resource) throws CmsException { CmsObject cms = getCmsObject(); CmsProperty titleProp = cms.readPropertyObject(resource, CmsPropertyDefinition.PROPERTY_TITLE, true); String defaultTitle = ""; String title = titleProp.getValue(defaultTitle); String path = cms.getSitePath(resource); String subtitle = path; return new CmsBrokenLinkBean(resource.getStructureId(), title, subtitle); } /** * Locks the given resource with a temporary, if not already locked by the current user. * Will throw an exception if the resource could not be locked for the current user.

* * @param resource the resource to lock * * @return the assigned lock * * @throws CmsException if the resource could not be locked */ protected LockInfo ensureLockAndGetInfo(CmsResource resource) throws CmsException { CmsObject cms = getCmsObject(); boolean justLocked = false; List blockingResources = cms.getBlockingLockedResources(resource); if ((blockingResources != null) && !blockingResources.isEmpty()) { throw new CmsException( org.opencms.gwt.Messages.get().container( org.opencms.gwt.Messages.ERR_RESOURCE_HAS_BLOCKING_LOCKED_CHILDREN_1, cms.getSitePath(resource))); } CmsUser user = cms.getRequestContext().getCurrentUser(); CmsLock lock = cms.getLock(resource); if (!lock.isOwnedBy(user)) { cms.lockResourceTemporary(resource); lock = cms.getLock(resource); justLocked = true; } else if (!lock.isOwnedInProjectBy(user, cms.getRequestContext().getCurrentProject())) { cms.changeLock(resource); lock = cms.getLock(resource); justLocked = true; } return new LockInfo(lock, justLocked); } /** * Internal method for saving a sitemap.

* * @param entryPoint the URI of the sitemap to save * @param change the change to save * * @return list of changed sitemap entries * * @throws CmsException if something goes wrong */ protected CmsSitemapChange saveInternal(String entryPoint, CmsSitemapChange change) throws CmsException { ensureSession(); switch (change.getChangeType()) { case clipboardOnly: // do nothing break; case remove: change = removeEntryFromNavigation(change); break; case undelete: change = undelete(change); break; default: change = applyChange(entryPoint, change); } setClipboardData(change.getClipBoardData()); return change; } /** * Removes unnecessary locales from a container page.

* * @param containerPage the container page which should be changed * @param localeRes the resource used to determine the locale * * @throws CmsException if something goes wrong */ void ensureSingleLocale(CmsXmlContainerPage containerPage, CmsResource localeRes) throws CmsException { CmsObject cms = getCmsObject(); Locale mainLocale = CmsLocaleManager.getMainLocale(cms, localeRes); OpenCms.getLocaleManager(); Locale defaultLocale = CmsLocaleManager.getDefaultLocale(); if (containerPage.hasLocale(mainLocale)) { removeAllLocalesExcept(containerPage, mainLocale); // remove other locales } else if (containerPage.hasLocale(defaultLocale)) { containerPage.copyLocale(defaultLocale, mainLocale); removeAllLocalesExcept(containerPage, mainLocale); } else if (containerPage.getLocales().size() > 0) { containerPage.copyLocale(containerPage.getLocales().get(0), mainLocale); removeAllLocalesExcept(containerPage, mainLocale); } else { containerPage.addLocale(cms, mainLocale); } } /** * Gets the properties of a resource as a map of client properties.

* * @param cms the CMS context to use * @param res the resource whose properties to read * @param search true if the inherited properties should be read * * @return the client properties as a map * * @throws CmsException if something goes wrong */ Map getClientProperties(CmsObject cms, CmsResource res, boolean search) throws CmsException { List props = cms.readPropertyObjects(res, search); Map result = createClientProperties(props, false); return result; } /** * Adds a function detail element to a container page.

* * @param cms the current CMS context * @param page the container page which should be changed * @param containerName the name of the container which should be used for function detail elements * @param elementId the structure id of the element to add * @param formatterId the structure id of the formatter for the element * * @throws CmsException if something goes wrong */ private void addFunctionDetailElement( CmsObject cms, CmsXmlContainerPage page, String containerName, CmsUUID elementId, CmsUUID formatterId) throws CmsException { CmsContainerPageBean bean = page.getContainerPage(cms); List containerBeans = new ArrayList(); Collection originalContainers = bean.getContainers().values(); if ((containerName == null) && !originalContainers.isEmpty()) { CmsContainerBean firstContainer = originalContainers.iterator().next(); containerName = firstContainer.getName(); } boolean foundContainer = false; for (CmsContainerBean cntBean : originalContainers) { boolean isDetailTarget = cntBean.getName().equals(containerName); if (isDetailTarget && !foundContainer) { foundContainer = true; List newElems = new ArrayList(); newElems.addAll(cntBean.getElements()); CmsContainerElementBean newElement = new CmsContainerElementBean( elementId, formatterId, new HashMap(), false); newElems.add(0, newElement); CmsContainerBean newCntBean = new CmsContainerBean( cntBean.getName(), cntBean.getType(), cntBean.getParentInstanceId(), cntBean.isRootContainer(), newElems); containerBeans.add(newCntBean); } else { containerBeans.add(cntBean); } } if (!foundContainer) { throw new CmsException( Messages.get().container(Messages.ERR_NO_FUNCTION_DETAIL_CONTAINER_1, page.getFile().getRootPath())); } CmsContainerPageBean bean2 = new CmsContainerPageBean(new ArrayList(containerBeans)); page.writeContainerPage(cms, bean2); } /** * Applys the given change to the VFS.

* * @param entryPoint the sitemap entry-point * @param change the change * * @return the updated entry * * @throws CmsException if something goes wrong */ private CmsSitemapChange applyChange(String entryPoint, CmsSitemapChange change) throws CmsException { CmsObject cms = getCmsObject(); CmsResource configFile = null; // lock the config file first, to avoid half done changes if (change.hasDetailPageInfos()) { CmsADEConfigData configData = OpenCms.getADEManager().lookupConfiguration( cms, cms.getRequestContext().addSiteRoot(entryPoint)); if (!configData.isModuleConfiguration() && (configData.getResource() != null)) { configFile = configData.getResource(); } if (configFile != null) { ensureLock(configFile); } } if (change.isNew()) { CmsClientSitemapEntry newEntry = createNewEntry(entryPoint, change); change.setUpdatedEntry(newEntry); change.setEntryId(newEntry.getId()); } else if (change.getChangeType() == ChangeType.delete) { delete(change); } else if (change.getEntryId() != null) { modifyEntry(change); } if (change.hasDetailPageInfos() && (configFile != null)) { saveDetailPages(change.getDetailPageInfos(), configFile, change.getEntryId(), change.getUpdatedEntry()); tryUnlock(configFile); } return change; } /** * Changes the navigation for a moved entry and its neighbors.

* * @param change the sitemap change * @param entryFolder the moved entry * * @throws CmsException if something goes wrong */ private void applyNavigationChanges(CmsSitemapChange change, CmsResource entryFolder) throws CmsException { CmsObject cms = getCmsObject(); String parentPath = null; if (change.hasNewParent()) { CmsResource parent = cms.readResource(change.getParentId()); parentPath = cms.getSitePath(parent); } else { parentPath = CmsResource.getParentFolder(cms.getSitePath(entryFolder)); } List navElements = getNavBuilder().getNavigationForFolder( parentPath, Visibility.all, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); CmsSitemapNavPosCalculator npc = new CmsSitemapNavPosCalculator(navElements, entryFolder, change.getPosition()); List navs = npc.getNavigationChanges(); List needToUnlock = new ArrayList(); try { for (CmsJspNavElement nav : navs) { LockInfo lockInfo = ensureLockAndGetInfo(nav.getResource()); if (!nav.getResource().equals(entryFolder) && lockInfo.wasJustLocked()) { needToUnlock.add(nav.getResource()); } } for (CmsJspNavElement nav : navs) { CmsProperty property = new CmsProperty( CmsPropertyDefinition.PROPERTY_NAVPOS, "" + nav.getNavPosition(), null); cms.writePropertyObject(cms.getSitePath(nav.getResource()), property); } } finally { for (CmsResource lockedRes : needToUnlock) { try { cms.unlockResource(lockedRes); } catch (CmsException e) { // we catch this because we still want to unlock the other resources LOG.error(e.getLocalizedMessage(), e); } } } } /** * Builds the list info bean for a resource type which can be used as a sub-sitemap folder.

* * @param sitemapType the sitemap folder type * * @return the list info bean for the given type */ private CmsListInfoBean buildSitemapTypeInfo(I_CmsResourceType sitemapType) { CmsListInfoBean result = new CmsListInfoBean(); CmsWorkplaceManager wm = OpenCms.getWorkplaceManager(); String typeName = sitemapType.getTypeName(); Locale wpLocale = wm.getWorkplaceLocale(getCmsObject()); String title = typeName; String description = ""; try { title = CmsWorkplaceMessages.getResourceTypeName(wpLocale, typeName); } catch (Throwable e) { LOG.warn(e.getLocalizedMessage(), e); } try { description = CmsWorkplaceMessages.getResourceTypeDescription(wpLocale, typeName); } catch (Throwable e) { LOG.warn(e.getLocalizedMessage(), e); } result.setResourceType(typeName); result.setTitle(title); result.setSubTitle(description); return result; } /** * Returns all available gallery folder resource types.

* * @return the gallery folder resource types */ @SuppressWarnings("deprecation") private List collectGalleryTypes() { Locale wpLocale = OpenCms.getWorkplaceManager().getWorkplaceLocale(getCmsObject()); Map> galleryContentTypes = new HashMap>(); List result = new ArrayList(); for (I_CmsResourceType resourceType : OpenCms.getResourceManager().getResourceTypes()) { if (resourceType instanceof CmsResourceTypeFolderExtended) { // found a configured extended folder resource type CmsResourceTypeFolderExtended galleryType = (CmsResourceTypeFolderExtended)resourceType; String folderClassName = galleryType.getFolderClassName(); if (CmsStringUtil.isNotEmpty(folderClassName)) { // only process this as a gallery if the folder name is not empty try { // check, if the folder class is a subclass of A_CmsGallery if (A_CmsAjaxGallery.class.isAssignableFrom(Class.forName(folderClassName))) { CmsGalleryType gallery = new CmsGalleryType(); gallery.setTypeId(resourceType.getTypeId()); gallery.setTypeName(resourceType.getTypeName()); gallery.setNiceName( CmsWorkplaceMessages.getResourceTypeName(wpLocale, resourceType.getTypeName())); gallery.setDescription( CmsWorkplaceMessages.getResourceTypeDescription(wpLocale, resourceType.getTypeName())); result.add(gallery); } } catch (Exception e) { this.log(e.getLocalizedMessage(), e); } } } else { List galleryTypes = resourceType.getGalleryTypes(); if ((galleryTypes != null) && !galleryTypes.isEmpty()) { for (I_CmsResourceType galleryType : galleryTypes) { List typeList = galleryContentTypes.get(galleryType.getTypeName()); if (typeList == null) { typeList = new ArrayList(); galleryContentTypes.put(galleryType.getTypeName(), typeList); } typeList.add(resourceType.getTypeName()); } } } } for (CmsGalleryType galleryType : result) { galleryType.setContentTypeNames(galleryContentTypes.get(galleryType.getTypeName())); } return result; } /** * Gets the information for the available sitemap folder types.

* * @param cms the current CMS context * @param configData the configuration data for the current subsitemap * @return the list info beans corresponding to available sitemap folder types */ private List collectSitemapTypeInfos(CmsObject cms, CmsADEConfigData configData) { List subsitemapFolderTypeInfos = new ArrayList(); List sitemapTypeIds = CmsResourceTypeFolderSubSitemap.getSubSitemapResourceTypeIds(); String checkPath = configData.getBasePath(); if (checkPath != null) { checkPath = cms.getRequestContext().removeSiteRoot(checkPath); } else { checkPath = "/"; } CmsResource checkResource = null; try { checkResource = cms.readResource(checkPath); } catch (CmsException e) { LOG.warn(e.getLocalizedMessage(), e); } for (Integer typeId : sitemapTypeIds) { try { I_CmsResourceType sitemapType = OpenCms.getResourceManager().getResourceType(typeId.intValue()); String typeName = sitemapType.getTypeName(); CmsExplorerTypeSettings explorerType = OpenCms.getWorkplaceManager().getExplorerTypeSetting(typeName); // if explorer type and check resource available, perform a permission check if ((explorerType != null) && (checkResource != null)) { try { CmsExplorerTypeAccess access = explorerType.getAccess(); if (!access.getPermissions(cms, checkResource).requiresControlPermission()) { continue; } } catch (Exception e) { LOG.error(e.getLocalizedMessage(), e); } } CmsListInfoBean infoBean = buildSitemapTypeInfo(sitemapType); subsitemapFolderTypeInfos.add(infoBean); } catch (CmsLoaderException e) { LOG.warn("Could not read sitemap folder type " + typeId + ": " + e.getLocalizedMessage(), e); } } return subsitemapFolderTypeInfos; } /** * Creates a client alias bean from a server-side alias.

* * @param cms the current CMS context * @param alias the alias to convert * * @return the alias table row * * @throws CmsException if something goes wrong */ private CmsAliasTableRow createAliasTableEntry(CmsObject cms, CmsAlias alias) throws CmsException { CmsResource resource = cms.readResource(alias.getStructureId(), CmsResourceFilter.ALL); CmsAliasTableRow result = new CmsAliasTableRow(); result.setStructureId(alias.getStructureId()); result.setOriginalStructureId(alias.getStructureId()); result.setAliasPath(alias.getAliasPath()); result.setResourcePath(cms.getSitePath(resource)); result.setKey((new CmsUUID()).toString()); result.setMode(alias.getMode()); result.setChanged(false); return result; } /** * Creates a navigation level type info.

* * @return the navigation level type info bean * * @throws CmsException if reading the sub level redirect copy page fails */ private CmsNewResourceInfo createNavigationLevelTypeInfo() throws CmsException { String name = CmsResourceTypeFolder.getStaticTypeName(); Locale locale = getWorkplaceLocale(); String subtitle = Messages.get().getBundle(getWorkplaceLocale()).key(Messages.GUI_NAVIGATION_LEVEL_SUBTITLE_0); if (CmsStringUtil.isEmptyOrWhitespaceOnly(subtitle)) { subtitle = CmsWorkplaceMessages.getResourceTypeName(locale, name); } CmsNewResourceInfo result = new CmsNewResourceInfo( CmsResourceTypeFolder.getStaticTypeId(), name, Messages.get().getBundle(getWorkplaceLocale()).key(Messages.GUI_NAVIGATION_LEVEL_TITLE_0), subtitle, getCmsObject().readResource(SUB_LEVEL_REDIRECT_COPY_PAGE).getStructureId(), false, subtitle); result.setCreateParameter(CmsJspNavBuilder.NAVIGATION_LEVEL_FOLDER); return result; } /** * Creates new content elements if required by the model page.

* * @param cms the cms context * @param page the page * @param sitePath the resource site path * * @throws CmsException when unable to create the content elements */ private void createNewContainerElements(CmsObject cms, CmsXmlContainerPage page, String sitePath) throws CmsException { CmsADEConfigData configData = OpenCms.getADEManager().lookupConfiguration(cms, cms.addSiteRoot(sitePath)); Locale contentLocale = OpenCms.getLocaleManager().getDefaultLocale(cms, CmsResource.getFolderPath(sitePath)); CmsObject cloneCms = OpenCms.initCmsObject(cms); cloneCms.getRequestContext().setLocale(contentLocale); CmsContainerPageBean pageBean = page.getContainerPage(cms); boolean needsChanges = false; List updatedContainers = new ArrayList(); for (CmsContainerBean container : pageBean.getContainers().values()) { List updatedElements = new ArrayList(); for (CmsContainerElementBean element : container.getElements()) { if (element.isCreateNew() && !element.isGroupContainer(cms) && !element.isInheritedContainer(cms)) { needsChanges = true; String typeName = OpenCms.getResourceManager().getResourceType(element.getResource()).getTypeName(); CmsResourceTypeConfig typeConfig = configData.getResourceType(typeName); if (typeConfig == null) { throw new IllegalArgumentException( "Can not copy template model element '" + element.getResource().getRootPath() + "' because the resource type '" + typeName + "' is not available in this sitemap."); } CmsResource newResource = typeConfig.createNewElement( cloneCms, element.getResource(), CmsResource.getParentFolder(cms.getRequestContext().addSiteRoot(sitePath))); CmsContainerElementBean newBean = new CmsContainerElementBean( newResource.getStructureId(), element.getFormatterId(), element.getIndividualSettings(), false); updatedElements.add(newBean); } else { updatedElements.add(element); } } CmsContainerBean updatedContainer = new CmsContainerBean( container.getName(), container.getType(), container.getParentInstanceId(), container.isRootContainer(), container.getMaxElements(), updatedElements); updatedContainers.add(updatedContainer); } if (needsChanges) { CmsContainerPageBean updatedPage = new CmsContainerPageBean(updatedContainers); page.writeContainerPage(cms, updatedPage); } } /** * Creates a new page in navigation.

* * @param entryPoint the site-map entry-point * @param change the new change * * @return the updated entry * * @throws CmsException if something goes wrong */ @SuppressWarnings("deprecation") private CmsClientSitemapEntry createNewEntry(String entryPoint, CmsSitemapChange change) throws CmsException { CmsObject cms = getCmsObject(); CmsClientSitemapEntry newEntry = null; if (change.getParentId() != null) { CmsResource parentFolder = cms.readResource( change.getParentId(), CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); String entryPath = ""; CmsResource entryFolder = null; CmsResource newRes = null; byte[] content = null; List properties = Collections.emptyList(); CmsResource copyPage = null; if (change.getNewCopyResourceId() != null) { copyPage = cms.readResource(change.getNewCopyResourceId(), CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); content = cms.readFile(copyPage).getContents(); properties = cms.readPropertyObjects(copyPage, false); } List filteredProperties = new ArrayList(); for (CmsProperty property : properties) { if (!property.getName().equals(CmsPropertyDefinition.PROPERTY_DESCRIPTION)) { filteredProperties.add(property); } } properties = filteredProperties; if (isRedirectType(change.getNewResourceTypeId())) { entryPath = CmsStringUtil.joinPaths(cms.getSitePath(parentFolder), change.getName()); newRes = cms.createResource( entryPath, change.getNewResourceTypeId(), null, Collections.singletonList( new CmsProperty(CmsPropertyDefinition.PROPERTY_TITLE, change.getName(), null))); cms.writePropertyObjects(newRes, generateInheritProperties(change, newRes)); applyNavigationChanges(change, newRes); } else { String entryFolderPath = CmsStringUtil.joinPaths(cms.getSitePath(parentFolder), change.getName() + "/"); boolean idWasNull = change.getEntryId() == null; // we don't really need to create a folder object here anymore. if (idWasNull) { // need this for calculateNavPosition, even though the id will get overwritten change.setEntryId(new CmsUUID()); } boolean isFunctionDetail = false; boolean isNavigationLevel = false; if (change.getCreateParameter() != null) { if (CmsUUID.isValidUUID(change.getCreateParameter())) { isFunctionDetail = true; } else if (CmsJspNavBuilder.NAVIGATION_LEVEL_FOLDER.equals(change.getCreateParameter())) { isNavigationLevel = true; } } String folderType = CmsResourceTypeFolder.getStaticTypeName(); String createSitemapFolderType = change.getCreateSitemapFolderType(); if (createSitemapFolderType != null) { folderType = createSitemapFolderType; } int folderTypeId = OpenCms.getResourceManager().getResourceType(folderType).getTypeId(); entryFolder = new CmsResource( change.getEntryId(), new CmsUUID(), entryFolderPath, folderTypeId, true, 0, cms.getRequestContext().getCurrentProject().getUuid(), CmsResource.STATE_NEW, System.currentTimeMillis(), cms.getRequestContext().getCurrentUser().getId(), System.currentTimeMillis(), cms.getRequestContext().getCurrentUser().getId(), CmsResource.DATE_RELEASED_DEFAULT, CmsResource.DATE_EXPIRED_DEFAULT, 1, 0, System.currentTimeMillis(), 0); List folderProperties = generateInheritProperties(change, entryFolder); if (isNavigationLevel) { folderProperties.add( new CmsProperty( CmsPropertyDefinition.PROPERTY_DEFAULT_FILE, CmsJspNavBuilder.NAVIGATION_LEVEL_FOLDER, null)); } entryFolder = cms.createResource(entryFolderPath, folderTypeId, null, folderProperties); if (createSitemapFolderType != null) { createSitemapContentFolder(cms, entryFolder); } if (idWasNull) { change.setEntryId(entryFolder.getStructureId()); } applyNavigationChanges(change, entryFolder); entryPath = CmsStringUtil.joinPaths(entryFolderPath, "index.html"); boolean isContainerPage = change.getNewResourceTypeId() == CmsResourceTypeXmlContainerPage.getContainerPageTypeIdSafely(); if (isContainerPage && (copyPage != null)) { // do *NOT* get this from the cache, because we perform some destructive operation on the XML content CmsXmlContainerPage page = CmsXmlContainerPageFactory.unmarshal( cms, cms.readFile(copyPage), true, true); ensureSingleLocale(page, entryFolder); if (isFunctionDetail) { String functionDetailContainer = getFunctionDetailContainerName(parentFolder); CmsUUID functionStructureId = new CmsUUID(change.getCreateParameter()); CmsResource functionFormatter = cms.readResource( CmsDynamicFunctionBean.FORMATTER_PATH, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); addFunctionDetailElement( cms, page, functionDetailContainer, functionStructureId, functionFormatter.getStructureId()); } createNewContainerElements(cms, page, entryPath); content = page.marshal(); } newRes = cms.createResource( entryPath, copyPage != null ? copyPage.getTypeId() : change.getNewResourceTypeId(), content, properties); cms.writePropertyObjects(newRes, generateOwnProperties(change)); } if (entryFolder != null) { tryUnlock(entryFolder); String sitePath = cms.getSitePath(entryFolder); newEntry = toClientEntry( getNavBuilder().getNavigationForResource(sitePath, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED), false); newEntry.setSubEntries(getChildren(sitePath, 1, null), null); newEntry.setChildrenLoadedInitially(true); } if (newRes != null) { tryUnlock(newRes); } if (newEntry == null) { newEntry = toClientEntry( getNavBuilder().getNavigationForResource( cms.getSitePath(newRes), CmsResourceFilter.ONLY_VISIBLE_NO_DELETED), false); } // mark position as not set newEntry.setPosition(-1); newEntry.setNew(true); change.getClipBoardData().getModifications().remove(null); change.getClipBoardData().getModifications().put(newEntry.getId(), newEntry); } return newEntry; } /** * Creates a new resource info to a given model page resource.

* * @param cms the current CMS context * @param modelResource the model page resource * @param locale the locale used for retrieving descriptions/titles * * @return the new resource info * * @throws CmsException if something goes wrong */ private CmsNewResourceInfo createNewResourceInfo(CmsObject cms, CmsResource modelResource, Locale locale) throws CmsException { // if model page got overwritten by another resource, reread from site path if (!cms.existsResource(modelResource.getStructureId(), CmsResourceFilter.ONLY_VISIBLE_NO_DELETED)) { modelResource = cms.readResource(cms.getSitePath(modelResource), CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); } int typeId = modelResource.getTypeId(); String name = OpenCms.getResourceManager().getResourceType(typeId).getTypeName(); String title = cms.readPropertyObject( modelResource, CmsPropertyDefinition.PROPERTY_TITLE, false, locale).getValue(); String description = cms.readPropertyObject( modelResource, CmsPropertyDefinition.PROPERTY_DESCRIPTION, false, locale).getValue(); boolean editable = false; try { CmsResource freshModelResource = cms.readResource( modelResource.getStructureId(), CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); editable = cms.hasPermissions( freshModelResource, CmsPermissionSet.ACCESS_WRITE, false, CmsResourceFilter.DEFAULT); } catch (CmsException e) { LOG.warn(e.getLocalizedMessage(), e); } CmsNewResourceInfo info = new CmsNewResourceInfo( typeId, name, title, description, modelResource.getStructureId(), editable, description); Float navpos = null; try { CmsProperty navposProp = cms.readPropertyObject(modelResource, CmsPropertyDefinition.PROPERTY_NAVPOS, true); String navposStr = navposProp.getValue(); if (navposStr != null) { try { navpos = Float.valueOf(navposStr); } catch (NumberFormatException e) { // noop } } } catch (CmsException e) { LOG.warn(e.getLocalizedMessage(), e); } info.setNavPos(navpos); info.setDate( CmsDateUtil.getDate(new Date(modelResource.getDateLastModified()), DateFormat.LONG, getWorkplaceLocale())); info.setVfsPath(modelResource.getRootPath()); return info; } /** * Creates a resource type info bean for a given resource type.

* * @param resType the resource type * @param copyResource the structure id of the copy resource * * @return the resource type info bean */ @SuppressWarnings("deprecation") private CmsNewResourceInfo createResourceTypeInfo(I_CmsResourceType resType, CmsResource copyResource) { String name = resType.getTypeName(); Locale locale = getWorkplaceLocale(); String subtitle = CmsWorkplaceMessages.getResourceTypeDescription(locale, name); if (CmsStringUtil.isEmptyOrWhitespaceOnly(subtitle)) { subtitle = CmsWorkplaceMessages.getResourceTypeName(locale, name); } if (copyResource != null) { return new CmsNewResourceInfo( copyResource.getTypeId(), name, CmsWorkplaceMessages.getResourceTypeName(locale, name), CmsWorkplaceMessages.getResourceTypeDescription(locale, name), copyResource.getStructureId(), false, subtitle); } else { return new CmsNewResourceInfo( resType.getTypeId(), name, CmsWorkplaceMessages.getResourceTypeName(locale, name), CmsWorkplaceMessages.getResourceTypeDescription(locale, name), null, false, subtitle); } } /** * Helper method for creating the .content folder of a sub-sitemap.

* * @param cms the current CMS context * @param subSitemapFolder the sub-sitemap folder in which the .content folder should be created * * @throws CmsException if something goes wrong */ @SuppressWarnings("deprecation") private void createSitemapContentFolder(CmsObject cms, CmsResource subSitemapFolder) throws CmsException { String sitePath = cms.getSitePath(subSitemapFolder); String folderName = CmsStringUtil.joinPaths(sitePath, CmsADEManager.CONTENT_FOLDER_NAME + "/"); String sitemapConfigName = CmsStringUtil.joinPaths(folderName, CmsADEManager.CONFIG_FILE_NAME); if (!cms.existsResource(folderName)) { cms.createResource( folderName, OpenCms.getResourceManager().getResourceType(CmsADEManager.CONFIG_FOLDER_TYPE)); } I_CmsResourceType configType = OpenCms.getResourceManager().getResourceType(CmsADEManager.CONFIG_TYPE); if (cms.existsResource(sitemapConfigName)) { CmsResource configFile = cms.readResource(sitemapConfigName); if (configFile.getTypeId() != configType.getTypeId()) { throw new CmsException( Messages.get().container( Messages.ERR_CREATING_SUB_SITEMAP_WRONG_CONFIG_FILE_TYPE_2, sitemapConfigName, CmsADEManager.CONFIG_TYPE)); } } else { cms.createResource( sitemapConfigName, OpenCms.getResourceManager().getResourceType(CmsADEManager.CONFIG_TYPE)); } } /** * Deletes a resource according to the change data.

* * @param change the change data * * @return CmsClientSitemapEntry always null * * * @throws CmsException if something goes wrong */ private CmsClientSitemapEntry delete(CmsSitemapChange change) throws CmsException { CmsObject cms = getCmsObject(); CmsResource resource = cms.readResource(change.getEntryId(), CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); ensureLock(resource); cms.deleteResource(cms.getSitePath(resource), CmsResource.DELETE_PRESERVE_SIBLINGS); tryUnlock(resource); return null; } /** * Generates a client side lock info object representing the current lock state of the given resource.

* * @param resource the resource * * @return the client lock * * @throws CmsException if something goes wrong */ private CmsClientLock generateClientLock(CmsResource resource) throws CmsException { CmsObject cms = getCmsObject(); CmsLock lock = cms.getLock(resource); CmsClientLock clientLock = new CmsClientLock(); clientLock.setLockType(CmsClientLock.LockType.valueOf(lock.getType().getMode())); CmsUUID ownerId = lock.getUserId(); if (!lock.isUnlocked() && (ownerId != null)) { clientLock.setLockOwner(cms.readUser(ownerId).getDisplayName(cms, cms.getRequestContext().getLocale())); clientLock.setOwnedByUser(cms.getRequestContext().getCurrentUser().getId().equals(ownerId)); } return clientLock; } /** * Generates a list of property object to save to the sitemap entry folder to apply the given change.

* * @param change the change * @param entryFolder the entry folder * * @return the property objects */ private List generateInheritProperties(CmsSitemapChange change, CmsResource entryFolder) { List result = new ArrayList(); Map clientProps = change.getOwnInternalProperties(); boolean hasTitle = false; if (clientProps != null) { for (CmsClientProperty clientProp : clientProps.values()) { if (CmsPropertyDefinition.PROPERTY_TITLE.equals(clientProp.getName())) { hasTitle = true; } CmsProperty prop = new CmsProperty( clientProp.getName(), clientProp.getStructureValue(), clientProp.getResourceValue()); result.add(prop); } } if (!hasTitle) { result.add(new CmsProperty(CmsPropertyDefinition.PROPERTY_TITLE, change.getName(), null)); } return result; } /** * Generates a list of property object to save to the sitemap entry resource to apply the given change.

* * @param change the change * * @return the property objects */ private List generateOwnProperties(CmsSitemapChange change) { List result = new ArrayList(); Map clientProps = change.getDefaultFileProperties(); boolean hasTitle = false; if (clientProps != null) { for (CmsClientProperty clientProp : clientProps.values()) { if (CmsPropertyDefinition.PROPERTY_TITLE.equals(clientProp.getName())) { hasTitle = true; } CmsProperty prop = new CmsProperty( clientProp.getName(), clientProp.getStructureValue(), clientProp.getResourceValue()); result.add(prop); } } if (!hasTitle) { result.add(new CmsProperty(CmsPropertyDefinition.PROPERTY_TITLE, change.getName(), null)); } return result; } /** * Generates a list of property values inherited to the site-map root entry.

* * @param rootPath the root entry name * * @return the list of property values inherited to the site-map root entry * * @throws CmsException if something goes wrong reading the properties */ private Map generateParentProperties(String rootPath) throws CmsException { CmsObject cms = getCmsObject(); if (rootPath == null) { rootPath = cms.getRequestContext().addSiteRoot("/"); } CmsObject rootCms = OpenCms.initCmsObject(cms); rootCms.getRequestContext().setSiteRoot(""); String parentRootPath = CmsResource.getParentFolder(rootPath); Map result = new HashMap(); if (parentRootPath != null) { List props = rootCms.readPropertyObjects(parentRootPath, true); for (CmsProperty prop : props) { CmsClientProperty clientProp = createClientProperty(prop, true); result.put(clientProp.getName(), clientProp); } } return result; } /** * Returns the sitemap children for the given path with all descendants up to the given level or to the given target path, ie. *

levels=1
only children
levels=2
children and great children
* and so on.

* * @param root the site relative root * @param levels the levels to recurse * @param targetPath the target path * * @return the sitemap children */ private List getChildren(String root, int levels, String targetPath) { List children = new ArrayList(); int i = 0; for (CmsJspNavElement navElement : getNavBuilder().getNavigationForFolder( root, Visibility.all, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED)) { try { CmsClientSitemapEntry child = toClientEntry(navElement, false); if (child != null) { child.setPosition(i); children.add(child); int nextLevels = levels; if ((nextLevels == 2) && (targetPath != null) && targetPath.startsWith(child.getSitePath())) { nextLevels = 3; } if (child.isFolderType() && ((nextLevels > 1) || (nextLevels == -1)) && !isSubSitemap(navElement)) { child.setSubEntries(getChildren(child.getSitePath(), nextLevels - 1, targetPath), null); child.setChildrenLoadedInitially(true); } i++; } } catch (CmsException e) { LOG.error("Could not read sitemap entry.", e); } } return children; } /** * Returns the clipboard data from the current user.

* * @return the clipboard data */ private CmsSitemapClipboardData getClipboardData() { CmsSitemapClipboardData result = new CmsSitemapClipboardData(); result.setModifications(getModifiedList()); result.setDeletions(getDeletedList()); return result; } /** * Returns the deleted list from the current user.

* * @return the deleted list */ private LinkedHashMap getDeletedList() { CmsObject cms = getCmsObject(); CmsUser user = cms.getRequestContext().getCurrentUser(); Object obj = user.getAdditionalInfo(ADDINFO_ADE_DELETED_LIST); LinkedHashMap result = new LinkedHashMap(); if (obj instanceof String) { try { JSONArray array = new JSONArray((String)obj); for (int i = 0; i < array.length(); i++) { try { CmsUUID delId = new CmsUUID(array.getString(i)); CmsResource res = cms.readResource(delId, CmsResourceFilter.ALL); if (res.getState().isDeleted()) { // make sure resource is still deleted CmsClientSitemapEntry delEntry = new CmsClientSitemapEntry(); delEntry.setSitePath(cms.getSitePath(res)); delEntry.setOwnProperties(getClientProperties(cms, res, false)); delEntry.setName(res.getName()); delEntry.setVfsPath(cms.getSitePath(res)); delEntry.setResourceTypeName( OpenCms.getResourceManager().getResourceType(res).getTypeName()); delEntry.setEntryType( res.isFolder() ? EntryType.folder : isRedirectType(res.getTypeId()) ? EntryType.redirect : EntryType.leaf); delEntry.setId(delId); result.put(delId, delEntry); } } catch (Throwable e) { // should never happen, catches wrong or no longer existing values LOG.warn(e.getLocalizedMessage()); } } } catch (Throwable e) { // should never happen, catches json parsing LOG.warn(e.getLocalizedMessage()); } } return result; } /** * Gets the container name for function detail elements depending on the parent folder.

* * @param parent the parent folder * @return the name of the function detail container */ private String getFunctionDetailContainerName(CmsResource parent) { CmsObject cms = getCmsObject(); String notFound = null; String containerInfo = OpenCms.getTemplateContextManager().readPropertyFromTemplate( cms, parent, CmsPropertyDefinition.PROPERTY_CONTAINER_INFO, notFound); if (containerInfo == notFound) { return null; } Map attrs = CmsStringUtil.splitAsMap(containerInfo, "|", "="); //$NON-NLS-2$ String functionDetailContainerName = attrs.get(KEY_FUNCTION_DETAIL); return functionDetailContainerName; } /** * Returns the galleries of the given sub site for the requested gallery type.

* * @param entryPointUri the sub site entry point * @param galleryType the gallery type * @param subSitePaths the sub site paths * * @return the gallery folder entries * * @throws CmsException if reading the resources fails */ private List getGalleriesForType( String entryPointUri, CmsGalleryType galleryType, List subSitePaths) throws CmsException { List galleries = new ArrayList(); @SuppressWarnings("deprecation") List galleryFolders = getCmsObject().readResources( entryPointUri, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED.addRequireType(galleryType.getTypeId())); for (CmsResource folder : galleryFolders) { try { if (!isInSubsite(subSitePaths, folder.getRootPath())) { galleries.add(readGalleryFolderEntry(folder, galleryType.getTypeName())); } } catch (CmsException ex) { log(ex.getLocalizedMessage(), ex); } } // create a tree structure Collections.sort(galleries, new Comparator() { public int compare(CmsGalleryFolderEntry o1, CmsGalleryFolderEntry o2) { return o1.getSitePath().compareTo(o2.getSitePath()); } }); List galleryTree = new ArrayList(); for (int i = 0; i < galleries.size(); i++) { boolean isSubGallery = false; if (i > 0) { for (int j = i - 1; j >= 0; j--) { if (galleries.get(i).getSitePath().startsWith(galleries.get(j).getSitePath())) { galleries.get(j).addSubGallery(galleries.get(i)); isSubGallery = true; break; } } } if (!isSubGallery) { galleryTree.add(galleries.get(i)); } } return galleryTree; } /** * Returns the modified list from the current user.

* * @return the modified list */ private LinkedHashMap getModifiedList() { CmsObject cms = getCmsObject(); CmsUser user = cms.getRequestContext().getCurrentUser(); Object obj = user.getAdditionalInfo(ADDINFO_ADE_MODIFIED_LIST); LinkedHashMap result = new LinkedHashMap(); if (obj instanceof String) { try { JSONArray array = new JSONArray((String)obj); for (int i = 0; i < array.length(); i++) { try { CmsUUID modId = new CmsUUID(array.getString(i)); CmsResource res = cms.readResource(modId, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); String sitePath = cms.getSitePath(res); CmsJspNavElement navEntry = getNavBuilder().getNavigationForResource( sitePath, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); if (navEntry.isInNavigation()) { CmsClientSitemapEntry modEntry = toClientEntry(navEntry, false); result.put(modId, modEntry); } } catch (Throwable e) { // should never happen, catches wrong or no longer existing values LOG.warn(e.getLocalizedMessage()); } } } catch (Throwable e) { // should never happen, catches json parsing LOG.warn(e.getLocalizedMessage()); } } return result; } /** * Returns a navigation builder reference.

* * @return the navigation builder */ private CmsJspNavBuilder getNavBuilder() { if (m_navBuilder == null) { m_navBuilder = new CmsJspNavBuilder(getCmsObject()); } return m_navBuilder; } /** * Returns the new resource infos.

* * @param cms the current CMS context * @param configData the configuration data from which the new resource infos should be read * @param locale locale used for retrieving descriptions/titles * * @return the new resource infos */ private List getNewResourceInfos(CmsObject cms, CmsADEConfigData configData, Locale locale) { List result = new ArrayList(); for (CmsModelPageConfig modelConfig : configData.getModelPages()) { try { CmsNewResourceInfo info = createNewResourceInfo(cms, modelConfig.getResource(), locale); info.setDefault(modelConfig.isDefault()); result.add(info); } catch (CmsException e) { LOG.debug(e.getLocalizedMessage(), e); } } Collections.sort(result, new Comparator() { public int compare(CmsNewResourceInfo a, CmsNewResourceInfo b) { return ComparisonChain.start().compareTrueFirst(a.isDefault(), b.isDefault()).compare( a.getNavPos(), b.getNavPos(), Ordering.natural().nullsLast()).result(); } }); return result; } /** * Gets the names of all available properties.

* * @param cms the CMS context * * @return the list of all property names * * @throws CmsException if something goes wrong */ private List getPropertyNames(CmsObject cms) throws CmsException { List propDefs = cms.readAllPropertyDefinitions(); List result = new ArrayList(); for (CmsPropertyDefinition propDef : propDefs) { result.add(propDef.getName()); } return result; } /** * Gets the resource type info beans for types for which new detail pages can be created.

* * @param cms the current CMS context * @param resourceTypeConfigs the resource type configurations * @param functionReferences the function references * @param modelResource the model resource * @param locale the locale used for retrieving descriptions/titles * * @return the resource type info beans for types for which new detail pages can be created */ private List getResourceTypeInfos( CmsObject cms, List resourceTypeConfigs, List functionReferences, CmsResource modelResource, Locale locale) { List result = new ArrayList(); for (CmsResourceTypeConfig typeConfig : resourceTypeConfigs) { if (typeConfig.isDetailPagesDisabled()) { continue; } String typeName = typeConfig.getTypeName(); try { I_CmsResourceType resourceType = OpenCms.getResourceManager().getResourceType(typeName); result.add(createResourceTypeInfo(resourceType, modelResource)); } catch (CmsLoaderException e) { LOG.error(e.getLocalizedMessage(), e); } } for (CmsFunctionReference functionRef : functionReferences) { try { CmsResource functionRes = cms.readResource(functionRef.getStructureId()); String description = cms.readPropertyObject( functionRes, CmsPropertyDefinition.PROPERTY_DESCRIPTION, false).getValue(); String subtitle = description; try { CmsGallerySearchResult searchResult = CmsGallerySearch.searchById( cms, functionRef.getStructureId(), getWorkplaceLocale()); subtitle = searchResult.getDescription(); } catch (CmsException e) { LOG.warn(e.getLocalizedMessage(), e); } CmsNewResourceInfo info = new CmsNewResourceInfo( modelResource.getTypeId(), CmsDetailPageInfo.FUNCTION_PREFIX + functionRef.getName(), functionRef.getName(), description, modelResource.getStructureId(), false, subtitle); info.setCreateParameter(functionRef.getStructureId().toString()); info.setIsFunction(true); result.add(info); } catch (CmsVfsResourceNotFoundException e) { LOG.warn(e.getLocalizedMessage(), e); } catch (CmsException e) { LOG.error(e.getLocalizedMessage(), e); } } return result; } /** * Reeds the site root entry.

* * @param rootPath the root path of the sitemap root * @param targetPath the target path to open * * @return the site root entry * * @throws CmsSecurityException in case of insufficient permissions * @throws CmsException if something goes wrong */ private CmsClientSitemapEntry getRootEntry(String rootPath, String targetPath) throws CmsSecurityException, CmsException { String sitePath = "/"; if ((rootPath != null)) { sitePath = getCmsObject().getRequestContext().removeSiteRoot(rootPath); } CmsJspNavElement navElement = getNavBuilder().getNavigationForResource( sitePath, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); CmsClientSitemapEntry result = toClientEntry(navElement, true); if (result != null) { result.setPosition(0); result.setChildrenLoadedInitially(true); result.setSubEntries(getChildren(sitePath, 2, targetPath), null); } return result; } /** * Returns the sitemap info for the given base path.

* * @param basePath the base path * * @return the sitemap info * * @throws CmsException if something goes wrong reading the resources */ private CmsSitemapInfo getSitemapInfo(String basePath) throws CmsException { CmsObject cms = getCmsObject(); CmsResource baseFolder = null; if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(basePath)) { baseFolder = cms.readResource( cms.getRequestContext().removeSiteRoot(basePath), CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); } else { // in case of an empty base path, use base folder of the current site basePath = "/"; baseFolder = cms.readResource("/"); } CmsResource defaultFile = cms.readDefaultFile(baseFolder, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); String title = cms.readPropertyObject(baseFolder, CmsPropertyDefinition.PROPERTY_TITLE, false).getValue(); if (CmsStringUtil.isEmptyOrWhitespaceOnly(title) && (defaultFile != null)) { title = cms.readPropertyObject(defaultFile, CmsPropertyDefinition.PROPERTY_TITLE, false).getValue(); } String description = cms.readPropertyObject( baseFolder, CmsPropertyDefinition.PROPERTY_DESCRIPTION, false).getValue(); if (CmsStringUtil.isEmptyOrWhitespaceOnly(description) && (defaultFile != null)) { description = cms.readPropertyObject( defaultFile, CmsPropertyDefinition.PROPERTY_DESCRIPTION, false).getValue(); } return new CmsSitemapInfo( cms.getRequestContext().getCurrentProject().getName(), description, OpenCms.getLocaleManager().getDefaultLocale(cms, baseFolder).toString(), OpenCms.getSiteManager().getCurrentSite(cms).getUrl() + OpenCms.getLinkManager().substituteLinkForUnknownTarget(cms, basePath), title); } /** * Gets the default type id for subsitemap folders.

* * @return the default type id for subsitemap folders * * @throws CmsRpcException in case of an error */ @SuppressWarnings("deprecation") private int getSubsitemapType() throws CmsRpcException { try { return OpenCms.getResourceManager().getResourceType( CmsResourceTypeFolderSubSitemap.TYPE_SUBSITEMAP).getTypeId(); } catch (CmsLoaderException e) { error(e); } return CmsResourceTypeUnknownFolder.getStaticTypeId(); } /** * Returns the workplace locale for the current user.

* * @return the workplace locale */ private Locale getWorkplaceLocale() { Locale result = OpenCms.getWorkplaceManager().getWorkplaceLocale(getCmsObject()); if (result == null) { result = CmsLocaleManager.getDefaultLocale(); } if (result == null) { result = Locale.getDefault(); } return result; } /** * Checks whether the sitemap change has default file changes.

* * @param change a sitemap change * @return true if the change would change the default file */ private boolean hasDefaultFileChanges(CmsSitemapChange change) { return (change.getDefaultFileId() != null) && !change.isNew(); } /** * Checks whether the sitemap change has changes for the sitemap entry resource.

* * @param change the sitemap change * @return true if the change would change the original sitemap entry resource */ private boolean hasOwnChanges(CmsSitemapChange change) { return !change.isNew(); } /** * Checks whether a resource is a default file of a folder.

* * @param resource the resource to check * * @return true if the resource is the default file of a folder * * @throws CmsException if something goes wrong */ private boolean isDefaultFile(CmsResource resource) throws CmsException { CmsObject cms = getCmsObject(); if (resource.isFolder()) { return false; } CmsResource parent = cms.readResource( CmsResource.getParentFolder(cms.getSitePath(resource)), CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); CmsResource defaultFile = cms.readDefaultFile(parent, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); return resource.equals(defaultFile); } /** * Checks if the toolbar should be displayed.

* * @param request the current request to get the default locale from * * @return true if the toolbar should be displayed */ private boolean isDisplayToolbar(HttpServletRequest request) { // display the toolbar by default boolean displayToolbar = true; if (CmsHistoryResourceHandler.isHistoryRequest(request)) { // we do not want to display the toolbar in case of an historical request displayToolbar = false; } return displayToolbar; } /** * Returns if the given path is located below one of the given sub site paths.

* * @param subSitePaths the sub site root paths * @param path the root path to check * * @return true if the given path is located below one of the given sub site paths */ private boolean isInSubsite(List subSitePaths, String path) { boolean result = false; for (String subSite : subSitePaths) { if (path.startsWith(subSite)) { result = true; break; } } return result; } /** * Returns if the given type id matches the xml-redirect resource type.

* * @param typeId the resource type id * * @return true if the given type id matches the xml-redirect resource type */ @SuppressWarnings("deprecation") private boolean isRedirectType(int typeId) { try { return typeId == OpenCms.getResourceManager().getResourceType(RECOURCE_TYPE_NAME_REDIRECT).getTypeId(); } catch (Exception e) { return false; } } /** * Returns if the given nav-element resembles a sub-sitemap entry-point.

* * @param navElement the nav-element * * @return true if the given nav-element resembles a sub-sitemap entry-point.

*/ private boolean isSubSitemap(CmsJspNavElement navElement) { return CmsResourceTypeFolderSubSitemap.isSubSitemap(navElement.getResource()); } /** * Checks if the given open path is valid.

* * @param cms the cms context * @param openPath the open path * * @return true if the given open path is valid */ private boolean isValidOpenPath(CmsObject cms, String openPath) { if (CmsStringUtil.isEmptyOrWhitespaceOnly(openPath)) { return false; } if (!cms.existsResource(openPath)) { // in case of a detail-page check the parent folder String parent = CmsResource.getParentFolder(openPath); if (CmsStringUtil.isEmptyOrWhitespaceOnly(parent) || !cms.existsResource(parent)) { return false; } } return true; } /** * Returns if the given return code is valid.

* * @param returnCode the return code to check * * @return true if the return code is valid */ private boolean isValidReturnCode(String returnCode) { if (CmsStringUtil.isEmptyOrWhitespaceOnly(returnCode)) { return false; } int pos = returnCode.indexOf(":"); if (pos > 0) { return CmsUUID.isValidUUID(returnCode.substring(0, pos)) && CmsUUID.isValidUUID(returnCode.substring(pos + 1)); } else { return CmsUUID.isValidUUID(returnCode); } } /** * Applys the given changes to the entry.

* * @param change the change to apply * * @throws CmsException if something goes wrong */ private void modifyEntry(CmsSitemapChange change) throws CmsException { CmsObject cms = getCmsObject(); CmsResource entryPage = null; CmsResource entryFolder = null; CmsResource ownRes = null; CmsResource defaultFileRes = null; try { // lock all resources necessary first to avoid doing changes only half way through if (hasOwnChanges(change)) { ownRes = cms.readResource(change.getEntryId(), CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); ensureLock(ownRes); } if (hasDefaultFileChanges(change)) { defaultFileRes = cms.readResource(change.getDefaultFileId(), CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); ensureLock(defaultFileRes); } if ((ownRes != null) && ownRes.isFolder()) { entryFolder = ownRes; } if ((ownRes != null) && ownRes.isFile()) { entryPage = ownRes; } if (defaultFileRes != null) { entryPage = defaultFileRes; } if (change.isLeafType()) { entryFolder = entryPage; } updateProperties(cms, ownRes, defaultFileRes, change.getPropertyChanges()); if (change.hasChangedPosition()) { updateNavPos(ownRes, change); } if (entryFolder != null) { if (change.hasNewParent() || change.hasChangedName()) { String destinationPath; if (change.hasNewParent()) { CmsResource futureParent = cms.readResource( change.getParentId(), CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); destinationPath = CmsStringUtil.joinPaths(cms.getSitePath(futureParent), change.getName()); } else { destinationPath = CmsStringUtil.joinPaths( CmsResource.getParentFolder(cms.getSitePath(entryFolder)), change.getName()); } if (change.isLeafType() && destinationPath.endsWith("/")) { destinationPath = destinationPath.substring(0, destinationPath.length() - 1); } // only if the site-path has really changed if (!cms.getSitePath(entryFolder).equals(destinationPath)) { cms.moveResource(cms.getSitePath(entryFolder), destinationPath); } entryFolder = cms.readResource( entryFolder.getStructureId(), CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); } } } finally { if (entryPage != null) { tryUnlock(entryPage); } if (entryFolder != null) { tryUnlock(entryFolder); } } } /** * Reads the gallery folder properties.

* * @param folder the folder resource * @param typeName the resource type name * * @return the folder entry data * * @throws CmsException if the folder properties can not be read */ private CmsGalleryFolderEntry readGalleryFolderEntry(CmsResource folder, String typeName) throws CmsException { CmsObject cms = getCmsObject(); CmsGalleryFolderEntry folderEntry = new CmsGalleryFolderEntry(); folderEntry.setResourceType(typeName); folderEntry.setSitePath(cms.getSitePath(folder)); folderEntry.setStructureId(folder.getStructureId()); folderEntry.setOwnProperties(getClientProperties(cms, folder, false)); return folderEntry; } /** * Helper method for removing all locales except one from a container page.

* * @param page the container page to proces * @param localeToKeep the locale which should be kept * * @throws CmsXmlException if something goes wrong */ private void removeAllLocalesExcept(CmsXmlContainerPage page, Locale localeToKeep) throws CmsXmlException { List locales = page.getLocales(); for (Locale locale : locales) { if (!locale.equals(localeToKeep)) { page.removeLocale(locale); } } } /** * Applys the given remove change.

* * @param change the change to apply * * @return the changed client sitemap entry or null * * @throws CmsException if something goes wrong */ private CmsSitemapChange removeEntryFromNavigation(CmsSitemapChange change) throws CmsException { CmsObject cms = getCmsObject(); CmsResource entryFolder = cms.readResource(change.getEntryId(), CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); ensureLock(entryFolder); List properties = new ArrayList(); properties.add( new CmsProperty( CmsPropertyDefinition.PROPERTY_NAVTEXT, CmsProperty.DELETE_VALUE, CmsProperty.DELETE_VALUE)); properties.add( new CmsProperty(CmsPropertyDefinition.PROPERTY_NAVPOS, CmsProperty.DELETE_VALUE, CmsProperty.DELETE_VALUE)); cms.writePropertyObjects(cms.getSitePath(entryFolder), properties); tryUnlock(entryFolder); return change; } /** * Saves the detail page information of a sitemap to the sitemap's configuration file.

* * @param detailPages saves the detailpage configuration * @param resource the configuration file resource * @param newId the structure id to use for new detail page entries * @param updateEntry the new detail page entry * * @throws CmsException if something goes wrong */ private void saveDetailPages( List detailPages, CmsResource resource, CmsUUID newId, CmsClientSitemapEntry updateEntry) throws CmsException { CmsObject cms = getCmsObject(); if (updateEntry != null) { for (CmsDetailPageInfo info : detailPages) { if (info.getId() == null) { updateEntry.setDetailpageTypeName(info.getType()); break; } } } CmsDetailPageConfigurationWriter writer = new CmsDetailPageConfigurationWriter(cms, resource); writer.updateAndSave(detailPages, newId); } /** * Saves the given clipboard data to the session.

* * @param clipboardData the clipboard data to save * * @throws CmsException if something goes wrong writing the user */ private void setClipboardData(CmsSitemapClipboardData clipboardData) throws CmsException { CmsObject cms = getCmsObject(); CmsUser user = cms.getRequestContext().getCurrentUser(); if (clipboardData != null) { JSONArray modified = new JSONArray(); if (clipboardData.getModifications() != null) { for (CmsUUID id : clipboardData.getModifications().keySet()) { if (id != null) { modified.put(id.toString()); } } } user.setAdditionalInfo(ADDINFO_ADE_MODIFIED_LIST, modified.toString()); JSONArray deleted = new JSONArray(); if (clipboardData.getDeletions() != null) { for (CmsUUID id : clipboardData.getDeletions().keySet()) { if (id != null) { deleted.put(id.toString()); } } } user.setAdditionalInfo(ADDINFO_ADE_DELETED_LIST, deleted.toString()); cms.writeUser(user); } } /** * Determines if the title property of the default file should be changed.

* * @param properties the current default file properties * @param folderNavtext the 'NavText' property of the folder * * @return true if the title property should be changed */ private boolean shouldChangeDefaultFileTitle(Map properties, CmsProperty folderNavtext) { return (properties == null) || (properties.get(CmsPropertyDefinition.PROPERTY_TITLE) == null) || (properties.get(CmsPropertyDefinition.PROPERTY_TITLE).getValue() == null) || ((folderNavtext != null) && properties.get(CmsPropertyDefinition.PROPERTY_TITLE).getValue().equals(folderNavtext.getValue())); } /** * Determines if the title property should be changed in case of a 'NavText' change.

* * @param properties the current resource properties * * @return true if the title property should be changed in case of a 'NavText' change */ private boolean shouldChangeTitle(Map properties) { return (properties == null) || (properties.get(CmsPropertyDefinition.PROPERTY_TITLE) == null) || (properties.get(CmsPropertyDefinition.PROPERTY_TITLE).getValue() == null) || ((properties.get(CmsPropertyDefinition.PROPERTY_NAVTEXT) != null) && properties.get(CmsPropertyDefinition.PROPERTY_TITLE).getValue().equals( properties.get(CmsPropertyDefinition.PROPERTY_NAVTEXT).getValue())); } /** * Converts a jsp navigation element into a client sitemap entry.

* * @param navElement the jsp navigation element * @param isRoot true if the entry is a root entry * * @return the client sitemap entry * * @throws CmsException if something goes wrong */ private CmsClientSitemapEntry toClientEntry(CmsJspNavElement navElement, boolean isRoot) throws CmsException { CmsResource entryPage = null; CmsObject cms = getCmsObject(); CmsClientSitemapEntry clientEntry = new CmsClientSitemapEntry(); CmsResource entryFolder = null; CmsResource ownResource = navElement.getResource(); clientEntry.setResourceState(ownResource.getState()); CmsResource defaultFileResource = null; if (ownResource.isFolder() && !navElement.isNavigationLevel()) { defaultFileResource = cms.readDefaultFile(ownResource, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); } Map ownProps = getClientProperties(cms, ownResource, false); Map defaultFileProps = null; if (defaultFileResource != null) { defaultFileProps = getClientProperties(cms, defaultFileResource, false); clientEntry.setDefaultFileId(defaultFileResource.getStructureId()); clientEntry.setDefaultFileType( OpenCms.getResourceManager().getResourceType(defaultFileResource.getTypeId()).getTypeName()); clientEntry.setDefaultFileReleased(defaultFileResource.isReleasedAndNotExpired(System.currentTimeMillis())); } else { defaultFileProps = new HashMap(); } boolean isDefault = isDefaultFile(ownResource); clientEntry.setId(ownResource.getStructureId()); clientEntry.setResourceTypeId(ownResource.getTypeId()); clientEntry.setFolderDefaultPage(isDefault); if (navElement.getResource().isFolder()) { entryFolder = navElement.getResource(); entryPage = defaultFileResource; clientEntry.setName(entryFolder.getName()); if (entryPage == null) { entryPage = entryFolder; } if (!isRoot && isSubSitemap(navElement)) { clientEntry.setEntryType(EntryType.subSitemap); clientEntry.setDefaultFileType(null); } else if (navElement.isNavigationLevel()) { clientEntry.setEntryType(EntryType.navigationLevel); } CmsLock folderLock = cms.getLock(entryFolder); clientEntry.setHasForeignFolderLock( !folderLock.isUnlocked() && !folderLock.isOwnedBy(cms.getRequestContext().getCurrentUser())); if (!cms.getRequestContext().getCurrentProject().isOnlineProject()) { List blockingChildren = cms.getBlockingLockedResources(entryFolder); clientEntry.setBlockingLockedChildren((blockingChildren != null) && !blockingChildren.isEmpty()); } } else { entryPage = navElement.getResource(); clientEntry.setName(entryPage.getName()); if (isRedirectType(entryPage.getTypeId())) { clientEntry.setEntryType(EntryType.redirect); CmsFile file = getCmsObject().readFile(entryPage); I_CmsXmlDocument content = CmsXmlContentFactory.unmarshal(getCmsObject(), file); I_CmsXmlContentValue linkValue = content.getValue( REDIRECT_LINK_TARGET_XPATH, getCmsObject().getRequestContext().getLocale()); String link = linkValue != null ? linkValue.getStringValue(getCmsObject()) : Messages.get().getBundle(getWorkplaceLocale()).key(Messages.GUI_REDIRECT_SUB_LEVEL_0); clientEntry.setRedirectTarget(link); } else { clientEntry.setEntryType(EntryType.leaf); } } if (entryPage.isFile()) { List aliases = OpenCms.getAliasManager().getAliasesForStructureId( getCmsObject(), entryPage.getStructureId()); if (!aliases.isEmpty()) { List aliasList = new ArrayList(); for (CmsAlias alias : aliases) { String aliasPath = alias.getAliasPath(); aliasList.add(aliasPath); } clientEntry.setAliases(aliasList); } } long dateExpired = navElement.getResource().getDateExpired(); if (dateExpired != CmsResource.DATE_EXPIRED_DEFAULT) { clientEntry.setDateExpired( CmsDateUtil.getDate(new Date(dateExpired), DateFormat.SHORT, getWorkplaceLocale())); } long dateReleased = navElement.getResource().getDateReleased(); if (dateReleased != CmsResource.DATE_RELEASED_DEFAULT) { clientEntry.setDateReleased( CmsDateUtil.getDate(new Date(dateReleased), DateFormat.SHORT, getWorkplaceLocale())); } clientEntry.setResleasedAndNotExpired( navElement.getResource().isReleasedAndNotExpired(System.currentTimeMillis())); String path = cms.getSitePath(entryPage); clientEntry.setVfsPath(path); clientEntry.setOwnProperties(ownProps); clientEntry.setDefaultFileProperties(defaultFileProps); clientEntry.setSitePath(entryFolder != null ? cms.getSitePath(entryFolder) : path); clientEntry.setLock(generateClientLock(entryPage)); clientEntry.setInNavigation(isRoot || navElement.isInNavigation()); String type = OpenCms.getResourceManager().getResourceType(ownResource).getTypeName(); clientEntry.setResourceTypeName(type); clientEntry.setPermissionInfo(OpenCms.getADEManager().getPermissionInfo(cms, ownResource, null)); return clientEntry; } /** * Un-deletes a resource according to the change data.

* * @param change the change data * * @return the changed entry or null * * @throws CmsException if something goes wrong */ private CmsSitemapChange undelete(CmsSitemapChange change) throws CmsException { CmsObject cms = getCmsObject(); CmsResource deleted = cms.readResource(change.getEntryId(), CmsResourceFilter.ALL); if (deleted.getState().isDeleted()) { ensureLock(deleted); cms.undeleteResource(getCmsObject().getSitePath(deleted), true); tryUnlock(deleted); } String parentPath = CmsResource.getParentFolder(cms.getSitePath(deleted)); CmsJspNavElement navElement = getNavBuilder().getNavigationForResource( parentPath, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); CmsClientSitemapEntry entry = toClientEntry(navElement, navElement.isInNavigation()); entry.setSubEntries(getChildren(parentPath, 2, null), null); change.setUpdatedEntry(entry); change.setParentId(cms.readParentFolder(deleted.getStructureId()).getStructureId()); return change; } /** * Updates the navigation position for a resource.

* * @param res the resource for which to update the navigation position * @param change the sitemap change * * @throws CmsException if something goes wrong */ private void updateNavPos(CmsResource res, CmsSitemapChange change) throws CmsException { if (change.hasChangedPosition()) { applyNavigationChanges(change, res); } } /** * Updates properties for a resource and possibly its detail page.

* * @param cms the CMS context * @param ownRes the resource * @param defaultFileRes the default file resource (possibly null) * @param propertyModifications the property modifications * * @throws CmsException if something goes wrong */ private void updateProperties( CmsObject cms, CmsResource ownRes, CmsResource defaultFileRes, List propertyModifications) throws CmsException { Map ownProps = getPropertiesByName(cms.readPropertyObjects(ownRes, false)); // determine if the title property should be changed in case of a 'NavText' change boolean changeOwnTitle = shouldChangeTitle(ownProps); boolean changeDefaultFileTitle = false; Map defaultFileProps = Maps.newHashMap(); if (defaultFileRes != null) { defaultFileProps = getPropertiesByName(cms.readPropertyObjects(defaultFileRes, false)); // determine if the title property of the default file should be changed changeDefaultFileTitle = shouldChangeDefaultFileTitle( defaultFileProps, ownProps.get(CmsPropertyDefinition.PROPERTY_NAVTEXT)); } String hasNavTextChange = null; List ownPropertyChanges = new ArrayList(); List defaultFilePropertyChanges = new ArrayList(); for (CmsPropertyModification propMod : propertyModifications) { CmsProperty propToModify = null; if (ownRes.getStructureId().equals(propMod.getId())) { if (CmsPropertyDefinition.PROPERTY_NAVTEXT.equals(propMod.getName())) { hasNavTextChange = propMod.getValue(); } else if (CmsPropertyDefinition.PROPERTY_TITLE.equals(propMod.getName())) { changeOwnTitle = false; } propToModify = ownProps.get(propMod.getName()); if (propToModify == null) { propToModify = new CmsProperty(propMod.getName(), null, null); } ownPropertyChanges.add(propToModify); } else { if (CmsPropertyDefinition.PROPERTY_TITLE.equals(propMod.getName())) { changeDefaultFileTitle = false; } propToModify = defaultFileProps.get(propMod.getName()); if (propToModify == null) { propToModify = new CmsProperty(propMod.getName(), null, null); } defaultFilePropertyChanges.add(propToModify); } String newValue = propMod.getValue(); if (newValue == null) { newValue = ""; } if (propMod.isStructureValue()) { propToModify.setStructureValue(newValue); } else { propToModify.setResourceValue(newValue); } } if (hasNavTextChange != null) { if (changeOwnTitle) { CmsProperty titleProp = ownProps.get(CmsPropertyDefinition.PROPERTY_TITLE); if (titleProp == null) { titleProp = new CmsProperty(CmsPropertyDefinition.PROPERTY_TITLE, null, null); } titleProp.setStructureValue(hasNavTextChange); ownPropertyChanges.add(titleProp); } if (changeDefaultFileTitle) { CmsProperty titleProp = defaultFileProps.get(CmsPropertyDefinition.PROPERTY_TITLE); if (titleProp == null) { titleProp = new CmsProperty(CmsPropertyDefinition.PROPERTY_TITLE, null, null); } titleProp.setStructureValue(hasNavTextChange); defaultFilePropertyChanges.add(titleProp); } } if (!ownPropertyChanges.isEmpty()) { cms.writePropertyObjects(ownRes, ownPropertyChanges); } if (!defaultFilePropertyChanges.isEmpty() && (defaultFileRes != null)) { cms.writePropertyObjects(defaultFileRes, defaultFilePropertyChanges); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy