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

org.opencms.ade.sitemap.client.control.CmsSitemapController 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 (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.client.control;

import org.opencms.ade.detailpage.CmsDetailPageInfo;
import org.opencms.ade.sitemap.client.CmsSitemapTreeItem;
import org.opencms.ade.sitemap.client.CmsSitemapView;
import org.opencms.ade.sitemap.client.Messages;
import org.opencms.ade.sitemap.shared.CmsClientSitemapEntry;
import org.opencms.ade.sitemap.shared.CmsDetailPageTable;
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.I_CmsSitemapController;
import org.opencms.ade.sitemap.shared.rpc.I_CmsSitemapService;
import org.opencms.ade.sitemap.shared.rpc.I_CmsSitemapServiceAsync;
import org.opencms.file.CmsResource;
import org.opencms.gwt.client.CmsCoreProvider;
import org.opencms.gwt.client.property.CmsReloadMode;
import org.opencms.gwt.client.rpc.CmsRpcAction;
import org.opencms.gwt.client.rpc.CmsRpcPrefetcher;
import org.opencms.gwt.client.ui.CmsErrorDialog;
import org.opencms.gwt.client.ui.tree.CmsLazyTreeItem.LoadState;
import org.opencms.gwt.client.util.CmsDebugLog;
import org.opencms.gwt.client.util.CmsDomUtil;
import org.opencms.gwt.client.util.CmsDomUtil.Method;
import org.opencms.gwt.client.util.CmsDomUtil.Target;
import org.opencms.gwt.shared.CmsCoreData;
import org.opencms.gwt.shared.property.CmsClientProperty;
import org.opencms.gwt.shared.property.CmsPropertyModification;
import org.opencms.gwt.shared.rpc.I_CmsVfsServiceAsync;
import org.opencms.util.CmsStringUtil;
import org.opencms.util.CmsUUID;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.common.collect.Maps;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.FormElement;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.event.shared.SimpleEventBus;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.SerializationException;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.RootPanel;

/**
 * Sitemap editor controller.

* * @since 8.0.0 */ public class CmsSitemapController implements I_CmsSitemapController { /** The name to use for new entries. */ public static final String NEW_ENTRY_NAME = "page"; /** A map of *all* detail page info beans, indexed by page id. */ protected Map m_allDetailPageInfos = new HashMap(); /** The sitemap data. */ protected CmsSitemapData m_data; /** The detail page table. */ protected CmsDetailPageTable m_detailPageTable; /** The event bus. */ protected SimpleEventBus m_eventBus; /** The entry data model. */ private Map m_entriesById; /** The sitemap entries by path. */ private Map m_entriesByPath; /** The set of names of hidden properties. */ private Set m_hiddenProperties; /** The map of property maps by structure id. */ private Map> m_propertyMaps = Maps.newHashMap(); /** The list of property update handlers. */ private List m_propertyUpdateHandlers = new ArrayList(); /** The sitemap service instance. */ private I_CmsSitemapServiceAsync m_service; /** The vfs service. */ private I_CmsVfsServiceAsync m_vfsService; /** * Constructor.

*/ public CmsSitemapController() { m_entriesById = new HashMap(); m_entriesByPath = new HashMap(); try { m_data = (CmsSitemapData)CmsRpcPrefetcher.getSerializedObjectFromDictionary( getService(), CmsSitemapData.DICT_NAME); } catch (SerializationException e) { CmsErrorDialog.handleException(new Exception( "Deserialization of sitemap data failed. This may be caused by expired java-script resources, please clear your browser cache and try again.", e)); } m_hiddenProperties = new HashSet(); if (m_data != null) { m_detailPageTable = m_data.getDetailPageTable(); m_data.getRoot().initializeAll(this); m_eventBus = new SimpleEventBus(); initDetailPageInfos(); } } /** * Helper method for looking up a value in a map which may be null.

* * @param the key type * @param the value type * @param map the map (which may be null) * @param key the map key * * @return the value of the map at the given key, or null if the map is null */ public static B safeLookup(Map map, A key) { if (map == null) { return null; } return map.get(key); } /** * Adds a new change event handler.

* * @param handler the handler to add * * @return the handler registration */ public HandlerRegistration addChangeHandler(I_CmsSitemapChangeHandler handler) { return m_eventBus.addHandlerToSource(CmsSitemapChangeEvent.getType(), this, handler); } /** * Adds a new detail page information bean.

* * @param info the detail page information bean to add */ public void addDetailPageInfo(CmsDetailPageInfo info) { m_detailPageTable.add(info); m_allDetailPageInfos.put(info.getId(), info); } /** * Adds a new load event handler.

* * @param handler the handler to add * * @return the handler registration */ public HandlerRegistration addLoadHandler(I_CmsSitemapLoadHandler handler) { return m_eventBus.addHandlerToSource(CmsSitemapLoadEvent.getType(), this, handler); } /** * Adds a handler for property changes caused by user edits.

* * @param handler a new handler for property updates caused by the user */ public void addPropertyUpdateHandler(I_CmsPropertyUpdateHandler handler) { m_propertyUpdateHandlers.add(handler); } /** * Adds the entry to the navigation.

* * @param entry the entry */ public void addToNavigation(CmsClientSitemapEntry entry) { entry.setInNavigation(true); CmsSitemapChange change = new CmsSitemapChange(entry.getId(), entry.getSitePath(), ChangeType.modify); CmsPropertyModification mod = new CmsPropertyModification( entry.getId(), CmsClientProperty.PROPERTY_NAVTEXT, entry.getTitle(), true); change.setPropertyChanges(Collections.singletonList(mod)); change.setPosition(entry.getPosition()); commitChange(change, null); } /** * Makes the given sitemap entry the default detail page for its detail page type.

* * @param entry an entry representing a detail page */ public void bump(CmsClientSitemapEntry entry) { CmsDetailPageTable table = getDetailPageTable().copy(); table.bump(entry.getId()); CmsSitemapChange change = new CmsSitemapChange(entry.getId(), entry.getSitePath(), ChangeType.bumpDetailPage); change.setDetailPageInfos(table.toList()); commitChange(change, null); } /** * Clears the deleted clip-board list and commits the change.

*/ public void clearDeletedList() { CmsSitemapClipboardData clipboardData = getData().getClipboardData().copy(); clipboardData.getDeletions().clear(); CmsSitemapChange change = new CmsSitemapChange(null, null, ChangeType.clipboardOnly); change.setClipBoardData(clipboardData); commitChange(change, null); } /** * Clears the modified clip-board list and commits the change.

*/ public void clearModifiedList() { CmsSitemapClipboardData clipboardData = getData().getClipboardData().copy(); clipboardData.getModifications().clear(); CmsSitemapChange change = new CmsSitemapChange(null, null, ChangeType.clipboardOnly); change.setClipBoardData(clipboardData); commitChange(change, null); } /** * Registers a new sitemap entry.

* * @param newEntry the new entry * @param parentId the parent entry id * @param resourceTypeId the resource type id * @param copyResourceId the copy resource id * @param parameter an additional parameter which may contain more information needed to create the new resource * @param isNewSitemap a flag controlling whether a new sitemap should be created */ public void create( CmsClientSitemapEntry newEntry, CmsUUID parentId, int resourceTypeId, CmsUUID copyResourceId, String parameter, boolean isNewSitemap) { assert (getEntry(newEntry.getSitePath()) == null); CmsSitemapChange change = new CmsSitemapChange(null, newEntry.getSitePath(), ChangeType.create); change.setDefaultFileId(newEntry.getDefaultFileId()); change.setParentId(parentId); change.setName(newEntry.getName()); change.setPosition(newEntry.getPosition()); change.setOwnInternalProperties(newEntry.getOwnProperties()); change.setDefaultFileInternalProperties(newEntry.getDefaultFileProperties()); change.setTitle(newEntry.getTitle()); change.setCreateParameter(parameter); change.setNewResourceTypeId(resourceTypeId); if (isNewSitemap) { change.setCreateSitemapFolderType(newEntry.getResourceTypeName()); } change.setNewCopyResourceId(copyResourceId); if (isDetailPage(newEntry)) { CmsDetailPageTable table = getDetailPageTable().copy(); if (!table.contains(newEntry.getId())) { CmsDetailPageInfo info = new CmsDetailPageInfo( newEntry.getId(), newEntry.getSitePath(), newEntry.getDetailpageTypeName()); table.add(info); } change.setDetailPageInfos(table.toList()); } CmsSitemapClipboardData data = getData().getClipboardData().copy(); data.addModified(newEntry); change.setClipBoardData(data); commitChange(change, null); } /** * Creates a sitemap folder.

* * @param newEntry the new entry * @param parentId the entry parent id * @param sitemapType the resource type for the subsitemap folder */ public void createSitemapSubEntry(final CmsClientSitemapEntry newEntry, CmsUUID parentId, String sitemapType) { CmsUUID structureId = m_data.getDefaultNewElementInfo().getCopyResourceId(); newEntry.setResourceTypeName(sitemapType); create(newEntry, parentId, m_data.getDefaultNewElementInfo().getId(), structureId, null, true); } /** * Creates a new sub-entry which is a subsitemap.

* * @param parent the parent entry * @param sitemapFolderType the sitemap folder type */ public void createSitemapSubEntry(final CmsClientSitemapEntry parent, final String sitemapFolderType) { CmsSitemapTreeItem item = CmsSitemapTreeItem.getItemById(parent.getId()); AsyncCallback callback = new AsyncCallback() { public void onFailure(Throwable caught) { // do nothing } public void onSuccess(CmsClientSitemapEntry result) { final CmsClientSitemapEntry newEntry = makeNewEntry(parent); newEntry.setResourceTypeName(sitemapFolderType); createSitemapSubEntry(newEntry, parent.getId(), sitemapFolderType); } }; if (item.getLoadState().equals(LoadState.UNLOADED)) { getChildren(parent.getId(), true, callback); } else { callback.onSuccess(parent); } } /** * Creates a new sub-entry of an existing sitemap entry.

* * @param parent the entry to which a new sub-entry should be added */ public void createSubEntry(final CmsClientSitemapEntry parent) { createSubEntry(parent, null); } /** * Creates a new sub-entry of an existing sitemap entry.

* * @param parent the entry to which a new sub-entry should be added * @param structureId the structure id of the model page (if null, uses default model page) */ public void createSubEntry(final CmsClientSitemapEntry parent, final CmsUUID structureId) { CmsSitemapTreeItem item = CmsSitemapTreeItem.getItemById(parent.getId()); AsyncCallback callback = new AsyncCallback() { public void onFailure(Throwable caught) { // nothing to do } public void onSuccess(CmsClientSitemapEntry result) { final CmsClientSitemapEntry newEntry = makeNewEntry(parent); createSubEntry(newEntry, parent.getId(), structureId); } }; if (item.getLoadState().equals(LoadState.UNLOADED)) { getChildren(parent.getId(), true, callback); } else { callback.onSuccess(parent); } } /** * Registers a new sitemap entry.

* * @param newEntry the new entry * @param parentId the parent entry id * @param structureId the structure id of the model page (if null, uses default model page) */ public void createSubEntry(final CmsClientSitemapEntry newEntry, CmsUUID parentId, CmsUUID structureId) { if (structureId == null) { structureId = m_data.getDefaultNewElementInfo().getCopyResourceId(); } create(newEntry, parentId, m_data.getDefaultNewElementInfo().getId(), structureId, null, false); } /** * Creates a sub-sitemap from the subtree of the current sitemap starting at the given entry.

* * @param entryId the id of the entry */ public void createSubSitemap(final CmsUUID entryId) { CmsRpcAction subSitemapAction = new CmsRpcAction() { /** * @see org.opencms.gwt.client.rpc.CmsRpcAction#execute() */ @Override public void execute() { start(0, true); getService().createSubSitemap(entryId, this); } /** * @see org.opencms.gwt.client.rpc.CmsRpcAction#onResponse(java.lang.Object) */ @Override protected void onResponse(CmsSitemapChange result) { stop(false); applyChange(result); } }; subSitemapAction.execute(); } /** * Deletes the given entry and all its descendants.

* * @param sitePath the site path of the entry to delete */ public void delete(String sitePath) { CmsClientSitemapEntry entry = getEntry(sitePath); CmsClientSitemapEntry parent = getEntry(CmsResource.getParentFolder(entry.getSitePath())); CmsSitemapChange change = new CmsSitemapChange(entry.getId(), entry.getSitePath(), ChangeType.delete); change.setParentId(parent.getId()); change.setDefaultFileId(entry.getDefaultFileId()); CmsSitemapClipboardData data = CmsSitemapView.getInstance().getController().getData().getClipboardData().copy(); if (!entry.isNew()) { data.addDeleted(entry); removeDeletedFromModified(entry, data); } change.setClipBoardData(data); CmsDetailPageTable detailPageTable = CmsSitemapView.getInstance().getController().getData().getDetailPageTable(); CmsUUID id = entry.getId(); if (detailPageTable.contains(id)) { CmsDetailPageTable copyTable = detailPageTable.copy(); copyTable.remove(id); change.setDetailPageInfos(copyTable.toList()); } commitChange(change, null); } /** * Edits the given sitemap entry.

* * @param entry the sitemap entry to update * @param propertyChanges the property changes * @param reloadStatus a value indicating which entries need to be reloaded after the change */ public void edit( CmsClientSitemapEntry entry, List propertyChanges, final CmsReloadMode reloadStatus) { CmsSitemapChange change = getChangeForEdit(entry, propertyChanges); final String updateTarget = ((reloadStatus == CmsReloadMode.reloadParent)) ? getParentEntry(entry).getSitePath() : entry.getSitePath(); Command callback = new Command() { public void execute() { if ((reloadStatus == CmsReloadMode.reloadParent) || (reloadStatus == CmsReloadMode.reloadEntry)) { updateEntry(updateTarget); } } }; if (change != null) { commitChange(change, callback); } } /** * Edits an entry and changes its URL name.

* * @param entry the entry which is being edited * @param newUrlName the new URL name of the entry * @param propertyChanges the property changes * @param keepNewStatus true if the entry should keep it's new status * @param reloadStatus a value indicating which entries need to be reloaded after the change */ public void editAndChangeName( final CmsClientSitemapEntry entry, String newUrlName, List propertyChanges, final boolean keepNewStatus, final CmsReloadMode reloadStatus) { CmsSitemapChange change = getChangeForEdit(entry, propertyChanges); change.setName(newUrlName); final CmsUUID entryId = entry.getId(); final boolean newStatus = keepNewStatus && entry.isNew(); final CmsUUID updateTarget = ((reloadStatus == CmsReloadMode.reloadParent)) ? getParentEntry(entry).getId() : entryId; Command callback = new Command() { public void execute() { if ((reloadStatus == CmsReloadMode.reloadParent) || (reloadStatus == CmsReloadMode.reloadEntry)) { updateEntry(updateTarget); } getEntryById(entryId).setNew(newStatus); } }; commitChange(change, callback); } /** * Ensure the uniqueness of a given URL-name within the children of the given parent site-map entry.

* * @param parent the parent entry * @param newName the proposed name * * @return the unique name */ public String ensureUniqueName(CmsClientSitemapEntry parent, String newName) { return ensureUniqueName(parent.getSitePath(), newName); } /** * Ensure the uniqueness of a given URL-name within the children of the given parent folder.

* * @param parentFolder the parent folder * @param newName the proposed name * * @return the unique name */ public String ensureUniqueName(final String parentFolder, String newName) { // using lower case folder names final String lowerCaseName = newName.toLowerCase(); CmsRpcAction action = new CmsRpcAction() { /** * @see org.opencms.gwt.client.rpc.CmsRpcAction#execute() */ @Override public void execute() { start(0, false); CmsCoreProvider.getService().getUniqueFileName(parentFolder, lowerCaseName, this); } /** * @see org.opencms.gwt.client.rpc.CmsRpcAction#onResponse(java.lang.Object) */ @Override protected void onResponse(String result) { stop(false); } }; return action.executeSync(); } /** * Applies the given property modification.

* * @param propMod the property modification to apply */ public void executePropertyModification(CmsPropertyModification propMod) { CmsClientSitemapEntry entry = getEntryById(propMod.getId()); if (entry != null) { Map props = getPropertiesForId(propMod.getId()); if (props != null) { propMod.updatePropertyInMap(props); entry.setOwnProperties(props); } } } /** * Retrieves the child entries of the given node from the server.

* * @param entryId the entry id * @param setOpen if the entry should be opened * @param callback the callback to execute after the children have been loaded */ public void getChildren( final CmsUUID entryId, final boolean setOpen, final AsyncCallback callback) { CmsRpcAction getChildrenAction = new CmsRpcAction() { /** * @see org.opencms.gwt.client.rpc.CmsRpcAction#execute() */ @Override public void execute() { // Make the call to the sitemap service start(500, false); // loading grand children as well getService().getChildren(getEntryPoint(), entryId, 2, this); } /** * @see org.opencms.gwt.client.rpc.CmsRpcAction#onResponse(java.lang.Object) */ @Override public void onResponse(CmsClientSitemapEntry result) { CmsClientSitemapEntry target = getEntryById(entryId); if (target == null) { // this might happen after an automated deletion stop(false); return; } target.setSubEntries(result.getSubEntries(), CmsSitemapController.this); CmsSitemapTreeItem item = CmsSitemapTreeItem.getItemById(target.getId()); target.update(result); target.initializeAll(CmsSitemapController.this); item.updateEntry(target); m_eventBus.fireEventFromSource(new CmsSitemapLoadEvent(target, setOpen), CmsSitemapController.this); stop(false); if (callback != null) { callback.onSuccess(result); } } }; getChildrenAction.execute(); } /** * Returns the sitemap data.

* * @return the sitemap data */ public CmsSitemapData getData() { return m_data; } /** * Returns the detail page info for a given entry id.

* * @param id a sitemap entry id * * @return the detail page info for that id */ public CmsDetailPageInfo getDetailPageInfo(CmsUUID id) { return m_allDetailPageInfos.get(id); } /** * Returns the detail page table.

* * @return the detail page table */ public CmsDetailPageTable getDetailPageTable() { return m_detailPageTable; } /** * Gets the effective value of a property value for a sitemap entry.

* * @param entry the sitemap entry * @param name the name of the property * * @return the effective value */ public String getEffectiveProperty(CmsClientSitemapEntry entry, String name) { CmsClientProperty prop = getEffectivePropertyObject(entry, name); if (prop == null) { return null; } return prop.getEffectiveValue(); } /** * Gets the value of a property which is effective at a given sitemap entry.

* * @param entry the sitemap entry * @param name the name of the property * @return the effective property value */ public CmsClientProperty getEffectivePropertyObject(CmsClientSitemapEntry entry, String name) { Map dfProps = entry.getDefaultFileProperties(); CmsClientProperty result = safeLookup(dfProps, name); if (!CmsClientProperty.isPropertyEmpty(result)) { return result.withOrigin(entry.getSitePath()); } result = safeLookup(entry.getOwnProperties(), name); if (!CmsClientProperty.isPropertyEmpty(result)) { return result.withOrigin(entry.getSitePath()); } return getInheritedPropertyObject(entry, name); } /** * Returns all entries with an id from a given list.

* * @param ids a list of sitemap entry ids * * @return all entries whose id is contained in the id list */ public Map getEntriesById(Collection ids) { // TODO: use some map of id -> entry instead List entriesToProcess = new ArrayList(); Map result = new HashMap(); entriesToProcess.add(m_data.getRoot()); while (!entriesToProcess.isEmpty()) { CmsClientSitemapEntry entry = entriesToProcess.remove(entriesToProcess.size() - 1); if (ids.contains(entry.getId())) { result.put(entry.getId(), entry); if (result.size() == ids.size()) { return result; } } entriesToProcess.addAll(entry.getSubEntries()); } return result; } /** * Returns the tree entry with the given path.

* * @param entryPath the path to look for * * @return the tree entry with the given path, or null if not found */ public CmsClientSitemapEntry getEntry(String entryPath) { return m_entriesByPath.get(entryPath); } /** * Finds an entry by id.

* * @param id the id of the entry to find * * @return the found entry, or null if the entry wasn't found */ public CmsClientSitemapEntry getEntryById(CmsUUID id) { return m_entriesById.get(id); } /** * Gets the value for a property which a sitemap entry would inherit if it didn't have its own properties.

* * @param entry the sitemap entry * @param name the property name * @return the inherited property value */ public String getInheritedProperty(CmsClientSitemapEntry entry, String name) { CmsClientProperty prop = getInheritedPropertyObject(entry, name); if (prop == null) { return null; } return prop.getEffectiveValue(); } /** * Gets the property object which would be inherited by a sitemap entry.

* * @param entry the sitemap entry * @param name the name of the property * @return the property object which would be inherited */ public CmsClientProperty getInheritedPropertyObject(CmsClientSitemapEntry entry, String name) { CmsClientSitemapEntry currentEntry = entry; while (currentEntry != null) { currentEntry = getParentEntry(currentEntry); if (currentEntry != null) { CmsClientProperty folderProp = currentEntry.getOwnProperties().get(name); if (!CmsClientProperty.isPropertyEmpty(folderProp)) { return folderProp.withOrigin(currentEntry.getSitePath()); } } } CmsClientProperty parentProp = getParentProperties().get(name); if (!CmsClientProperty.isPropertyEmpty(parentProp)) { String origin = parentProp.getOrigin(); String siteRoot = CmsCoreProvider.get().getSiteRoot(); if (origin.startsWith(siteRoot)) { origin = origin.substring(siteRoot.length()); } return parentProp.withOrigin(origin); } return null; } /** * Returns a list of all descendant sitemap entries of a given path which have already been loaded on the client.

* * @param path the path for which the descendants should be collected * * @return the list of descendant sitemap entries */ public List getLoadedDescendants(String path) { LinkedList remainingEntries = new LinkedList(); List result = new ArrayList(); CmsClientSitemapEntry entry = getEntry(path); remainingEntries.add(entry); while (remainingEntries.size() > 0) { CmsClientSitemapEntry currentEntry = remainingEntries.removeFirst(); result.add(currentEntry); for (CmsClientSitemapEntry subEntry : currentEntry.getSubEntries()) { remainingEntries.add(subEntry); } } return result; } /** * Returns the no edit reason or null if editing is allowed.

* * @param entry the entry to get the no edit reason for * * @return the no edit reason */ public String getNoEditReason(CmsClientSitemapEntry entry) { String reason = entry.getNoEditReason(); if (CmsStringUtil.isEmptyOrWhitespaceOnly(reason)) { reason = null; if ((entry.getLock() != null) && (entry.getLock().getLockOwner() != null) && !entry.getLock().isOwnedByUser()) { reason = Messages.get().key(Messages.GUI_DISABLED_LOCKED_BY_1, entry.getLock().getLockOwner()); } if (entry.hasBlockingLockedChildren()) { reason = Messages.get().key(Messages.GUI_DISABLED_BLOCKING_LOCKED_CHILDREN_0); } } return reason; } /** * Returns the parent entry of a sitemap entry, or null if it is the root entry.

* * @param entry a sitemap entry * * @return the parent entry or null */ public CmsClientSitemapEntry getParentEntry(CmsClientSitemapEntry entry) { String path = entry.getSitePath(); String parentPath = CmsResource.getParentFolder(path); if (parentPath == null) { return null; } return getEntry(parentPath); } /** * Gets the properties for a given structure id.

* * @param id the structure id of a sitemap entry * * @return the properties for that structure id */ public Map getPropertiesForId(CmsUUID id) { return m_propertyMaps.get(id); } /** * Returns the sitemap service instance.

* * @return the sitemap service instance */ public I_CmsSitemapServiceAsync getService() { if (m_service == null) { m_service = GWT.create(I_CmsSitemapService.class); String serviceUrl = CmsCoreProvider.get().link("org.opencms.ade.sitemap.CmsVfsSitemapService.gwt"); ((ServiceDefTarget)m_service).setServiceEntryPoint(serviceUrl); } return m_service; } /** * Leaves the current sitemap to open the parent sitemap.

*/ public void gotoParentSitemap() { openSiteMap(getData().getParentSitemap()); } /** * Hides the entry within the site navigation.

* * Hidden entries will still be visible in the navigation mode of the sitemap editor. * They will also have a NavText and a NavPos. Only when using the NavBuilder get navigation for folder method, * they will not be included.

* * @param entryId the entry id */ public void hideInNavigation(CmsUUID entryId) { CmsClientSitemapEntry entry = getEntryById(entryId); CmsSitemapChange change = getChangeForEdit( entry, Collections.singletonList(new CmsPropertyModification(entryId.toString() + "/" + CmsClientProperty.PROPERTY_NAVINFO + "/" + CmsClientProperty.PATH_STRUCTURE_VALUE, CmsClientSitemapEntry.HIDDEN_NAVIGATION_ENTRY))); commitChange(change, null); } /** * Checks whether this entry belongs to a detail page.

* * @param entry the entry to check * * @return true if this entry belongs to a detail page */ public boolean isDetailPage(CmsClientSitemapEntry entry) { return (entry.getDetailpageTypeName() != null) || isDetailPage(entry.getId()); } /** * Returns true if the id is the id of a detail page.

* * @param id the sitemap entry id * @return true if the id is the id of a detail page entry */ public boolean isDetailPage(CmsUUID id) { return m_allDetailPageInfos.containsKey(id); } /** * Checks if the current sitemap is editable.

* * @return true if the current sitemap is editable */ public boolean isEditable() { return CmsStringUtil.isEmptyOrWhitespaceOnly(m_data.getNoEditReason()); } /** * Checks whether a string is the name of a hidden property.

* * A hidden property is a property which should not appear in the property editor * because it requires special treatment.

* * @param propertyName the property name which should be checked * * @return true if the argument is the name of a hidden property */ public boolean isHiddenProperty(String propertyName) { if (propertyName.equals("secure") && !m_data.isSecure()) { // "secure" property should not be editable in a site for which no secure server is configured return true; } return m_hiddenProperties.contains(propertyName); } /** * Checks if the given site path is the sitemap root.

* * @param sitePath the site path to check * * @return true if the given site path is the sitemap root */ public boolean isRoot(String sitePath) { return m_data.getRoot().getSitePath().equals(sitePath); } /** * Ask to save the page before leaving, if necessary.

* * @param target the leaving target */ public void leaveEditor(String target) { Window.Location.assign(CmsCoreProvider.get().link(target)); } /** * Merges a subsitemap at the given id back into this sitemap.

* * @param entryId the id of the sub sitemap entry */ public void mergeSubSitemap(final CmsUUID entryId) { CmsRpcAction mergeAction = new CmsRpcAction() { /** * @see org.opencms.gwt.client.rpc.CmsRpcAction#execute() */ @Override public void execute() { start(0, true); getService().mergeSubSitemap(getEntryPoint(), entryId, this); } /** * @see org.opencms.gwt.client.rpc.CmsRpcAction#onResponse(java.lang.Object) */ @Override protected void onResponse(CmsSitemapChange result) { stop(false); applyChange(result); } }; mergeAction.execute(); } /** * Moves the given sitemap entry with all its descendants to the new position.

* * @param entry the sitemap entry to move * @param toPath the destination path * @param position the new position between its siblings */ public void move(CmsClientSitemapEntry entry, String toPath, int position) { // check for valid data if (!isValidEntryAndPath(entry, toPath)) { // invalid data, do nothing CmsDebugLog.getInstance().printLine("invalid data, doing nothing"); return; } // check for relevance if (isChangedPosition(entry, toPath, position)) { // only register real changes CmsSitemapChange change = new CmsSitemapChange(entry.getId(), entry.getSitePath(), ChangeType.modify); change.setDefaultFileId(entry.getDefaultFileId()); if (!toPath.equals(entry.getSitePath())) { change.setParentId(getEntry(CmsResource.getParentFolder(toPath)).getId()); change.setName(CmsResource.getName(toPath)); } if (CmsSitemapView.getInstance().isNavigationMode()) { change.setPosition(position); } change.setLeafType(entry.isLeafType()); CmsSitemapClipboardData data = getData().getClipboardData().copy(); data.addModified(entry); change.setClipBoardData(data); commitChange(change, null); } } /** * Opens the site-map specified.

* * @param sitePath the site path to the site-map folder */ public void openSiteMap(String sitePath) { Map parameter = new HashMap(); parameter.put(CmsCoreData.PARAM_PATH, sitePath); parameter.put(CmsCoreData.PARAM_RETURNCODE, getData().getReturnCode()); FormElement form = CmsDomUtil.generateHiddenForm( CmsCoreProvider.get().link(CmsCoreProvider.get().getUri()), Method.post, Target.TOP, parameter); RootPanel.getBodyElement().appendChild(form); form.submit(); } /** * Recomputes properties for all sitemap entries.

*/ public void recomputeProperties() { CmsClientSitemapEntry root = getData().getRoot(); recomputeProperties(root); } /** * @see org.opencms.ade.sitemap.shared.I_CmsSitemapController#registerEntry(org.opencms.ade.sitemap.shared.CmsClientSitemapEntry) */ public void registerEntry(CmsClientSitemapEntry entry) { if (m_entriesById.containsKey(entry.getId())) { CmsClientSitemapEntry oldEntry = m_entriesById.get(entry.getId()); oldEntry.update(entry); if (oldEntry != m_entriesByPath.get(oldEntry.getSitePath())) { m_entriesByPath.put(oldEntry.getSitePath(), oldEntry); } } else { m_entriesById.put(entry.getId(), entry); m_entriesByPath.put(entry.getSitePath(), entry); } } /** * @see org.opencms.ade.sitemap.shared.I_CmsSitemapController#registerPathChange(org.opencms.ade.sitemap.shared.CmsClientSitemapEntry, java.lang.String) */ public void registerPathChange(CmsClientSitemapEntry entry, String oldPath) { m_entriesById.put(entry.getId(), entry); m_entriesByPath.remove(oldPath); m_entriesByPath.put(entry.getSitePath(), entry); } /** * Removes the entry with the given site-path from navigation.

* * @param entryId the entry id */ public void removeFromNavigation(CmsUUID entryId) { CmsClientSitemapEntry entry = getEntryById(entryId); CmsClientSitemapEntry parent = getEntry(CmsResource.getParentFolder(entry.getSitePath())); CmsSitemapChange change = new CmsSitemapChange(entry.getId(), entry.getSitePath(), ChangeType.remove); change.setParentId(parent.getId()); change.setDefaultFileId(entry.getDefaultFileId()); CmsSitemapClipboardData data = CmsSitemapView.getInstance().getController().getData().getClipboardData().copy(); data.addModified(entry); change.setClipBoardData(data); //TODO: handle detail page delete commitChange(change, null); } /** * @see org.opencms.ade.sitemap.shared.I_CmsSitemapController#replaceProperties(org.opencms.util.CmsUUID, java.util.Map) */ public Map replaceProperties(CmsUUID id, Map properties) { if ((id == null) || (properties == null)) { return null; } Map props = m_propertyMaps.get(id); if (props == null) { props = properties; m_propertyMaps.put(id, props); } else { props.clear(); props.putAll(properties); } return props; } /** * Shows a formerly hidden entry in the navigation.

* * @see #hideInNavigation(CmsUUID) * * @param entryId the entry id */ public void showInNavigation(CmsUUID entryId) { CmsClientSitemapEntry entry = getEntryById(entryId); CmsSitemapChange change = getChangeForEdit( entry, Collections.singletonList(new CmsPropertyModification(entryId.toString() + "/" + CmsClientProperty.PROPERTY_NAVINFO + "/" + CmsClientProperty.PATH_STRUCTURE_VALUE, ""))); commitChange(change, null); } /** * Undeletes the resource with the given structure id.

* * @param entryId the entry id * @param sitePath the site-path */ public void undelete(CmsUUID entryId, String sitePath) { CmsSitemapChange change = new CmsSitemapChange(entryId, sitePath, ChangeType.undelete); CmsSitemapClipboardData data = CmsSitemapView.getInstance().getController().getData().getClipboardData().copy(); data.getDeletions().remove(entryId); change.setClipBoardData(data); commitChange(change, null); } /** * Updates the given entry.

* * @param entryId the entry id */ public void updateEntry(CmsUUID entryId) { getChildren(entryId, CmsSitemapTreeItem.getItemById(entryId).isOpen(), null); } /** * Updates the given entry.

* * @param sitePath the entry sitepath */ public void updateEntry(String sitePath) { CmsClientSitemapEntry entry = getEntry(sitePath); getChildren(entry.getId(), CmsSitemapTreeItem.getItemById(entry.getId()).isOpen(), null); } /** * Updates the given entry only, not evaluating any child changes.

* * @param entryId the entry id */ public void updateSingleEntry(final CmsUUID entryId) { CmsRpcAction getChildrenAction = new CmsRpcAction() { /** * @see org.opencms.gwt.client.rpc.CmsRpcAction#execute() */ @Override public void execute() { getService().getChildren(getEntryPoint(), entryId, 0, this); } /** * @see org.opencms.gwt.client.rpc.CmsRpcAction#onResponse(java.lang.Object) */ @Override public void onResponse(CmsClientSitemapEntry result) { CmsClientSitemapEntry target = getEntryById(entryId); if (target == null) { // this might happen after an automated deletion stop(false); return; } target.update(result); CmsSitemapTreeItem item = CmsSitemapTreeItem.getItemById(target.getId()); item.updateEntry(target); } }; getChildrenAction.execute(); } /** * Fires a sitemap change event.

* * @param change the change event to fire */ protected void applyChange(CmsSitemapChange change) { // update the clip board data if (change.getClipBoardData() != null) { getData().getClipboardData().setDeletions(change.getClipBoardData().getDeletions()); getData().getClipboardData().setModifications(change.getClipBoardData().getModifications()); } switch (change.getChangeType()) { case bumpDetailPage: CmsDetailPageTable detailPageTable = getData().getDetailPageTable(); if (detailPageTable.contains(change.getEntryId())) { detailPageTable.bump(change.getEntryId()); } break; case clipboardOnly: // nothing to do break; case remove: CmsClientSitemapEntry entry = getEntryById(change.getEntryId()); entry.setInNavigation(false); CmsPropertyModification propMod = new CmsPropertyModification( entry.getId(), CmsClientProperty.PROPERTY_NAVTEXT, null, true); executePropertyModification(propMod); propMod = new CmsPropertyModification(entry.getId(), CmsClientProperty.PROPERTY_NAVTEXT, null, true); executePropertyModification(propMod); entry.normalizeProperties(); break; case undelete: case create: CmsClientSitemapEntry newEntry = change.getUpdatedEntry(); getEntryById(change.getParentId()).insertSubEntry(newEntry, change.getPosition(), this); newEntry.initializeAll(this); if (isDetailPage(newEntry)) { CmsDetailPageInfo info = getDetailPageInfo(newEntry.getId()); if (info == null) { info = new CmsDetailPageInfo( newEntry.getId(), newEntry.getSitePath(), newEntry.getDetailpageTypeName()); } addDetailPageInfo(info); } break; case delete: removeEntry(change.getEntryId(), change.getParentId()); break; case modify: if (change.hasNewParent() || change.hasChangedPosition()) { CmsClientSitemapEntry moved = getEntryById(change.getEntryId()); String oldSitepath = moved.getSitePath(); CmsClientSitemapEntry sourceParent = getEntry(CmsResource.getParentFolder(oldSitepath)); sourceParent.removeSubEntry(moved.getId()); CmsClientSitemapEntry destParent = change.hasNewParent() ? getEntryById(change.getParentId()) : sourceParent; if (change.getPosition() < destParent.getSubEntries().size()) { destParent.insertSubEntry(moved, change.getPosition(), this); } else { // inserting as last entry of the parent list destParent.addSubEntry(moved, this); } if (change.hasNewParent()) { cleanupOldPaths(oldSitepath, destParent.getSitePath()); } } if (change.hasChangedName()) { CmsClientSitemapEntry changed = getEntryById(change.getEntryId()); String oldSitepath = changed.getSitePath(); String parentPath = CmsResource.getParentFolder(oldSitepath); String newSitepath = CmsStringUtil.joinPaths(parentPath, change.getName()); changed.updateSitePath(newSitepath, this); cleanupOldPaths(oldSitepath, newSitepath); } if (change.hasChangedProperties()) { for (CmsPropertyModification modification : change.getPropertyChanges()) { executePropertyModification(modification); } getEntryById(change.getEntryId()).normalizeProperties(); } if (change.getUpdatedEntry() != null) { CmsClientSitemapEntry oldEntry = getEntryById(change.getEntryId()); CmsClientSitemapEntry parent = getEntry(CmsResource.getParentFolder(oldEntry.getSitePath())); removeEntry(change.getEntryId(), parent.getId()); parent.insertSubEntry(change.getUpdatedEntry(), oldEntry.getPosition(), this); change.getUpdatedEntry().initializeAll(this); } break; default: } if (change.getChangeType() != ChangeType.delete) { recomputeProperties(); } m_eventBus.fireEventFromSource(new CmsSitemapChangeEvent(change), this); } /** * Adds a change to the queue.

* * @param change the change to commit * @param callback the callback to execute after the change has been applied */ protected void commitChange(final CmsSitemapChange change, final Command callback) { if (change != null) { // save the sitemap CmsRpcAction saveAction = new CmsRpcAction() { /** * @see org.opencms.gwt.client.rpc.CmsRpcAction#execute() */ @Override public void execute() { setLoadingMessage(Messages.get().key(Messages.GUI_SAVING_0)); start(0, true); getService().saveSync(getEntryPoint(), change, this); } /** * @see org.opencms.gwt.client.rpc.CmsRpcAction#onResponse(java.lang.Object) */ @Override public void onResponse(CmsSitemapChange result) { stop(true); applyChange(result); if (callback != null) { callback.execute(); } } }; saveAction.execute(); } } /** * Creates a change object for an edit operation.

* * @param entry the edited sitemap entry * @param propertyChanges the list of property changes * * @return the change object */ protected CmsSitemapChange getChangeForEdit( CmsClientSitemapEntry entry, List propertyChanges) { CmsSitemapChange change = new CmsSitemapChange(entry.getId(), entry.getSitePath(), ChangeType.modify); change.setDefaultFileId(entry.getDefaultFileId()); change.setLeafType(entry.isLeafType()); List propertyChangeData = new ArrayList(); for (CmsPropertyModification propChange : propertyChanges) { propertyChangeData.add(propChange); } change.setPropertyChanges(propertyChangeData); CmsSitemapClipboardData data = getData().getClipboardData().copy(); data.addModified(entry); change.setClipBoardData(data); return change; } /** * Returns the URI of the current sitemap.

* * @return the URI of the current sitemap */ protected String getEntryPoint() { return m_data.getRoot().getSitePath(); } /** * Helper method for getting the full path of a sitemap entry whose URL name is being edited.

* * @param entry the sitemap entry * @param newUrlName the new url name of the sitemap entry * * @return the new full site path of the sitemap entry */ protected String getPath(CmsClientSitemapEntry entry, String newUrlName) { if (newUrlName.equals("")) { return entry.getSitePath(); } return CmsResource.getParentFolder(entry.getSitePath()) + newUrlName + "/"; } /** * Returns the sitemap service instance.

* * @return the sitemap service instance */ protected I_CmsVfsServiceAsync getVfsService() { if (m_vfsService == null) { m_vfsService = CmsCoreProvider.getVfsService(); } return m_vfsService; } /** * Initializes the detail page information.

*/ protected void initDetailPageInfos() { for (CmsUUID id : m_data.getDetailPageTable().getAllIds()) { CmsDetailPageInfo info = m_data.getDetailPageTable().get(id); m_allDetailPageInfos.put(id, info); } } /** * Creates a new client sitemap entry bean to use for the RPC call which actually creates the entry on the server side.

* * @param parent the parent entry * * @return the initialized client sitemap entry */ protected CmsClientSitemapEntry makeNewEntry(final CmsClientSitemapEntry parent) { String urlName = ensureUniqueName(parent, NEW_ENTRY_NAME); final CmsClientSitemapEntry newEntry = new CmsClientSitemapEntry(); //newEntry.setTitle(urlName); newEntry.setName(urlName); String sitePath = parent.getSitePath() + urlName + "/"; newEntry.setSitePath(sitePath); newEntry.setVfsPath(null); newEntry.setPosition(0); newEntry.setNew(true); newEntry.setInNavigation(true); newEntry.setResourceTypeName("folder"); newEntry.getOwnProperties().put( CmsClientProperty.PROPERTY_TITLE, new CmsClientProperty(CmsClientProperty.PROPERTY_TITLE, NEW_ENTRY_NAME, NEW_ENTRY_NAME)); return newEntry; } /** * Recomputes the properties for a client sitemap entry.

* * @param entry the entry for whose descendants the properties should be recomputed */ protected void recomputeProperties(CmsClientSitemapEntry entry) { for (I_CmsPropertyUpdateHandler handler : m_propertyUpdateHandlers) { handler.handlePropertyUpdate(entry); } for (CmsClientSitemapEntry child : entry.getSubEntries()) { recomputeProperties(child); } } /** * Cleans up wrong path references.

* * @param oldSitepath the old sitepath * @param newSitepath the new sitepath */ private void cleanupOldPaths(String oldSitepath, String newSitepath) { // use a separate list to avoid concurrent changes List entries = new ArrayList(m_entriesById.values()); for (CmsClientSitemapEntry entry : entries) { if (entry.getSitePath().startsWith(oldSitepath)) { String currentPath = entry.getSitePath(); String updatedSitePath = CmsStringUtil.joinPaths( newSitepath, currentPath.substring(oldSitepath.length())); entry.updateSitePath(updatedSitePath, this); } } } /** * Returns the properties above the sitemap root.

* * @return the map of properties of the root's parent */ private Map getParentProperties() { return m_data.getParentProperties(); } /** * Checks if the given path and position indicate a changed position for the entry.

* * @param entry the sitemap entry to move * @param toPath the destination path * @param position the new position between its siblings * * @return true if this is a position change */ private boolean isChangedPosition(CmsClientSitemapEntry entry, String toPath, int position) { return (!entry.getSitePath().equals(toPath) || (entry.getPosition() != position)); } /** * Validates the entry and the given path.

* * @param entry the entry * @param toPath the path * * @return true if entry and path are valid */ private boolean isValidEntryAndPath(CmsClientSitemapEntry entry, String toPath) { return ((toPath != null) && (CmsResource.getParentFolder(toPath) != null) && (entry != null) && (getEntry(CmsResource.getParentFolder(toPath)) != null) && (getEntry(entry.getSitePath()) != null)); } /** * Removes all children of the given entry recursively from the data model.

* * @param entry the entry */ private void removeAllChildren(CmsClientSitemapEntry entry) { for (CmsClientSitemapEntry child : entry.getSubEntries()) { removeAllChildren(child); m_entriesById.remove(child.getId()); m_entriesByPath.remove(child.getSitePath()); // apply to detailpage table CmsDetailPageTable detailPageTable = getData().getDetailPageTable(); if (detailPageTable.contains(child.getId())) { detailPageTable.remove(child.getId()); } } entry.getSubEntries().clear(); } /** * Removes the given entry and it's descendants from the modified list.

* * @param entry the entry * @param data the clip board data */ private void removeDeletedFromModified(CmsClientSitemapEntry entry, CmsSitemapClipboardData data) { data.removeModified(entry); for (CmsClientSitemapEntry child : entry.getSubEntries()) { removeDeletedFromModified(child, data); } } /** * Removes the given entry from the data model.

* * @param entryId the id of the entry to remove * @param parentId the parent entry id */ private void removeEntry(CmsUUID entryId, CmsUUID parentId) { CmsClientSitemapEntry entry = getEntryById(entryId); CmsClientSitemapEntry deleteParent = getEntryById(parentId); removeAllChildren(entry); deleteParent.removeSubEntry(entry.getPosition()); m_entriesById.remove(entryId); m_entriesByPath.remove(entry.getSitePath()); // apply to detailpage table CmsDetailPageTable detailPageTable = getData().getDetailPageTable(); if (detailPageTable.contains(entryId)) { detailPageTable.remove(entryId); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy