/*
* 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 GmbH, 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.workplace.commons;
import org.opencms.configuration.CmsParameterConfiguration;
import org.opencms.file.CmsObject;
import org.opencms.file.CmsResource;
import org.opencms.file.CmsResourceFilter;
import org.opencms.jsp.CmsJspActionElement;
import org.opencms.lock.CmsLockFilter;
import org.opencms.main.CmsException;
import org.opencms.main.CmsLog;
import org.opencms.relations.CmsRelation;
import org.opencms.relations.CmsRelationFilter;
import org.opencms.security.CmsPermissionSet;
import org.opencms.util.CmsStringUtil;
import org.opencms.workplace.CmsDialog;
import org.opencms.workplace.CmsDialogSelector;
import org.opencms.workplace.CmsMultiDialog;
import org.opencms.workplace.CmsWorkplace;
import org.opencms.workplace.CmsWorkplaceSettings;
import org.opencms.workplace.I_CmsDialogHandler;
import org.opencms.workplace.list.CmsListExplorerColumn;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import org.apache.commons.logging.Log;
/**
* Creates the dialogs for locking, unlocking or steal lock operations on a resource.<p>
*
* The following files use this class:
* <ul>
* <li>/commons/lock_standard.jsp
* <li>/commons/lockchange_standard.jsp
* <li>/commons/unlock_standard.jsp
* <li>/commons/locks.jsp
* </ul>
* <p>
*
* @since 6.0.0
*/
public class CmsLock extends CmsMultiDialog implements I_CmsDialogHandler {
/** Value for the action: confirmed. */
public static final int ACTION_SUBMIT_NOCONFIRMATION = 200;
/** Request parameter value for the action: submit form without user interaction. */
public static final String DIALOG_SUBMIT_NOCONFIRMATION = "submitnoconfirmation";
/** The dialog type: lock a resource. */
public static final String DIALOG_TYPE_LOCK = "lock";
/** The dialog type: Steal a lock. */
public static final String DIALOG_TYPE_LOCKCHANGE = "lockchange";
/** The dialog type: locked subresources. */
public static final String DIALOG_TYPE_LOCKS = "locks";
/** The dialog type: unlock a resource. */
public static final String DIALOG_TYPE_UNLOCK = "unlock";
/** Request parameter name for the 'include unpublished related resources' flag. */
public static final String PARAM_INCLUDERELATED = "includerelated";
/** Request parameter name for the project id. */
public static final String PARAM_PROJECT_ID = "projectid";
/** Request parameter name for the publishsiblings parameter. */
public static final String PARAM_PUBLISHSIBLINGS = "publishsiblings";
/** Request parameter name for the 'show own locked resources' flag. */
public static final String PARAM_SHOWOWNLOCKS = "showownlocks";
/** Request parameter name for the source dialog uri. */
public static final String PARAM_SOURCE_DIALOG = "sourcedialog";
/** Request parameter name for the subresources parameter. */
public static final String PARAM_SUBRESOURCES = "subresources";
/** Type of the operation which is performed: lock resource. */
public static final int TYPE_LOCK = 1;
/** Type of the operation which is performed: steal a lock. */
public static final int TYPE_LOCKCHANGE = 2;
/** Type of the operation which is performed: locked subresources. */
public static final int TYPE_LOCKS = 4;
/** Type of the operation which is performed: unlock resource. */
public static final int TYPE_UNLOCK = 3;
/** The lock dialog URI. */
public static final String URI_LOCK_DIALOG = PATH_DIALOGS + "lock_standard.jsp";
/** The steal lock dialog URI. */
public static final String URI_LOCKCHANGE_DIALOG = PATH_DIALOGS + "lockchange_standard.jsp";
/** The locks dialog URI. */
public static final String URI_LOCKS_DIALOG = PATH_DIALOGS + "locks.jsp";
/** The unlock dialog URI. */
public static final String URI_UNLOCK_DIALOG = PATH_DIALOGS + "unlock_standard.jsp";
/** The log object for this class. */
private static final Log LOG = CmsLog.getLog(CmsLock.class);
/** the filter to get all blocking locks. */
private CmsLockFilter m_blockingFilter;
/** the nunmber of blocking locked resources. */
private int m_blockingLocks = -1;
/** The list of locked resources. */
private List m_lockedResources;
/** the filter to get all non blocking locks. */
private CmsLockFilter m_nonBlockingFilter;
/** The 'include unpublished related resources' parameter value. */
private String m_paramIncluderelated;
/** The project id parameter value. */
private String m_paramProjectid;
/** The 'show own locked resources' parameter value. */
private String m_paramShowownlocks;
/**
* Default constructor needed for dialog handler implementation.<p>
*/
public CmsLock() {
super(null);
}
/**
* Public constructor.<p>
*
* @param jsp an initialized JSP action element
*/
public CmsLock(CmsJspActionElement jsp) {
super(jsp);
}
/**
* Public constructor with JSP variables.<p>
*
* @param context the JSP page context
* @param req the JSP request
* @param res the JSP response
*/
public CmsLock(PageContext context, HttpServletRequest req, HttpServletResponse res) {
this(new CmsJspActionElement(context, req, res));
}
/**
* Determines if the resource should be locked, unlocked or if the lock should be stolen.<p>
*
* @param cms the CmsObject
* @return the dialog action: lock, change lock (steal) or unlock
*/
public static int getDialogAction(CmsObject cms) {
String fileName = CmsResource.getName(cms.getRequestContext().getUri());
if (fileName == null) {
// file name could not be determined, return "see locked subresources" action
return TYPE_LOCKS;
} else if (fileName.equalsIgnoreCase("lock.jsp")) {
// a "lock" action is requested
return TYPE_LOCK;
} else if (fileName.indexOf("change") != -1) {
// a "steal lock" action is requested
return TYPE_LOCKCHANGE;
} else if (fileName.indexOf("unlock") != -1) {
// an "unlock" action is requested
return TYPE_UNLOCK;
} else {
// an "see locked subresources" action is requested
return TYPE_LOCKS;
}
}
/**
* Performs the lock/unlock operation, will be called by the JSP page.<p>
*
* @throws JspException if problems including sub-elements occur
*/
public void actionToggleLock() throws JspException {
// save initialized instance of this class in request attribute for included sub-elements
getJsp().getRequest().setAttribute(SESSION_WORKPLACE_CLASS, this);
try {
if (performDialogOperation()) {
// if no exception is caused and "true" is returned the lock/unlock operation was successful
actionCloseDialog();
} else {
// "false" returned, display "please wait" screen
getJsp().include(FILE_DIALOG_SCREEN_WAIT);
}
} catch (Throwable e) {
// exception occurred, show error dialog
includeErrorpage(this, e);
}
}
/**
* @see org.opencms.configuration.I_CmsConfigurationParameterHandler#addConfigurationParameter(java.lang.String, java.lang.String)
*/
public void addConfigurationParameter(String paramName, String paramValue) {
// not implemented yet
}
/**
* Returns the html code to build the dialogs default confirmation message js.<p>
*
* @return html code
*/
public String buildDefaultConfirmationJS() {
StringBuffer html = new StringBuffer(512);
html.append("<script type='text/javascript'><!--\n");
html.append("function setConfirmationMessage(locks, blockinglocks) {\n");
html.append("\tvar confMsg = document.getElementById('conf-msg');\n");
html.append("\tif (locks > -1) {\n");
if (!getSettings().getUserSettings().getDialogShowLock()
&& (CmsLock.getDialogAction(getCms()) != CmsLock.TYPE_LOCKS)) {
// auto commit if lock dialog disabled
html.append("\t\tif (blockinglocks == 0) {\n");
html.append("\t\t\tsubmitAction('");
html.append(CmsDialog.DIALOG_OK);
html.append("', null, 'main');\n");
html.append("\t\t\tdocument.forms['main'].submit();\n");
html.append("\t\t\treturn;\n");
html.append("\t\t}\n");
}
html.append("\t\tdocument.getElementById('lock-body-id').className = '';\n");
html.append("\t\tif (locks > '0') {\n");
html.append("\t\t\tshowAjaxReportContent();\n");
html.append("\t\t\tconfMsg.innerHTML = '");
html.append(getConfirmationMessage(false));
html.append("';\n");
html.append("\t\t} else {\n");
html.append("\t\t\tshowAjaxOk();\n");
html.append("\t\t\tconfMsg.innerHTML = '");
html.append(getConfirmationMessage(true));
html.append("';\n");
html.append("\t\t}\n");
html.append("\t} else {\n");
html.append("\t\tconfMsg.innerHTML = '");
html.append(key(org.opencms.workplace.Messages.GUI_AJAX_REPORT_WAIT_0));
html.append("';\n");
html.append("\t}\n");
html.append("}\n");
html.append("// -->\n");
html.append("</script>\n");
return html.toString();
}
/**
* Returns the html code to include the needed js code.<p>
*
* @return html code
*/
public String buildIncludeJs() {
StringBuffer html = new StringBuffer(512);
html.append("<script type='text/javascript' src='");
html.append(CmsWorkplace.getSkinUri());
html.append("commons/ajax.js'></script>\n");
html.append("<script type='text/javascript' src='");
html.append(CmsWorkplace.getSkinUri());
html.append("editors/xmlcontent/help.js'></script>\n");
html.append("<script type='text/javascript' src='");
html.append(CmsWorkplace.getSkinUri());
html.append("admin/javascript/general.js'></script>\n");
html.append("<script type='text/javascript' src='");
html.append(CmsWorkplace.getSkinUri());
html.append("admin/javascript/list.js'></script>\n");
html.append("<script type='text/javascript'><!--\n");
html.append("function showAjaxOk() {\n");
html.append("\tdocument.getElementById('ajaxreport-img').src = '");
html.append(CmsWorkplace.getSkinUri());
html.append("commons/ok.png';\n");
html.append("\tdocument.getElementById('ajaxreport-txt').innerHTML = '");
html.append(key(Messages.GUI_OPERATION_NO_LOCKS_0));
html.append("';\n");
html.append("}\n");
html.append("var ajaxReportContent = '';\n");
html.append("var ajaxWaitMessage = '");
html.append(CmsStringUtil.escapeJavaScript(buildAjaxWaitMessage()));
html.append("';\n");
html.append("function showAjaxReportContent() {\n");
html.append("\tif (ajaxReportContent != '') {\n");
html.append("\t\tdocument.getElementById('ajaxreport').innerHTML = ajaxReportContent;\n");
html.append("\t}\n");
html.append("}\n");
html.append("function doReportUpdate(msg, state) {\n");
html.append("\tvar img = state + '.png';\n");
html.append("\tvar txt = '';\n");
html.append("\tvar locks = -1;\n");
html.append("\tvar blockinglocks = -1;\n");
html.append("\tvar elem = document.getElementById('ajaxreport');\n");
html.append("\tif (state != 'ok') {\n");
html.append("\t\tif (state != 'wait') {\n");
html.append("\t\t\tdocument.getElementById('lock-body-id').className = '';\n");
html.append("\t\t}\n");
html.append("\t\tvar img = state + '.png';\n");
html.append("\t\tvar txt = msg;\n");
html.append("\t\tif (state == 'fatal') {\n");
html.append("\t\t\timg = 'error.png';\n");
html.append("\t\t\ttxt = '");
html.append(key(org.opencms.workplace.Messages.GUI_AJAX_REPORT_GIVEUP_0));
html.append("';\n");
html.append("\t\t} else if (state == 'wait') {\n");
html.append("\t\t\timg = 'wait.gif';\n");
html.append("\t\t\ttxt = '");
html.append(key(org.opencms.workplace.Messages.GUI_AJAX_REPORT_WAIT_0));
html.append("'\n");
html.append("\t\t} else if (state == 'error') {\n");
html.append("\t\t\ttxt = '");
html.append(key(org.opencms.workplace.Messages.GUI_AJAX_REPORT_ERROR_0));
html.append("' + msg;\n");
html.append("\t\t}\n");
html.append("\t\tdocument.getElementById('ajaxreport-img').src = '");
html.append(CmsWorkplace.getSkinUri());
html.append("commons/' + img;\n");
html.append("\t\tdocument.getElementById('ajaxreport-txt').innerHTML = txt;\n");
html.append("\t} else {\n");
html.append("\t\telem.innerHTML = elem.innerHTML + msg.substring(0, 120);\n");
html.append("\t\tajaxReportContent = msg;\n");
html.append("\t}\n");
html.append("\tif (txt != '') {\n");
html.append("\t}\n");
html.append("\tif (state == 'ok') {\n");
html.append("\t\tlocks = document.forms['main'].locks.value;\n");
html.append("\t\tblockinglocks = document.forms['main'].blockinglocks.value;\n");
html.append("\t}\n");
html.append("\tsetConfirmationMessage(locks, blockinglocks);\n");
html.append("}\n");
html.append("// -->\n");
html.append("</script>\n");
return html.toString();
}
/**
* Returns the html code to build the lock request.<p>
*
* @return html code
*/
public String buildLockRequest() {
return buildLockRequest(0, false);
}
/**
* Returns the html code to build the lock request.<p>
*
* @param hiddenTimeout the maximal number of millis the dialog will be hidden
* @param includeRelated indicates if the report should include related resources
*
* @return html code
*/
public String buildLockRequest(int hiddenTimeout, boolean includeRelated) {
StringBuffer html = new StringBuffer(512);
html.append("<script type='text/javascript'><!--\n");
html.append("makeRequest('");
html.append(getJsp().link("/system/workplace/commons/report-locks.jsp"));
html.append("', '");
html.append(CmsMultiDialog.PARAM_RESOURCELIST);
html.append("=");
html.append(getParamResourcelist());
html.append("&");
html.append(CmsDialog.PARAM_RESOURCE);
html.append("=");
html.append(getParamResource());
html.append("&");
html.append(CmsLock.PARAM_INCLUDERELATED);
html.append("=");
html.append(includeRelated);
html.append("', 'doReportUpdate');\n");
html.append("function showLockDialog() {\n");
html.append("\tdocument.getElementById('lock-body-id').className = '';\n");
html.append("}\n");
html.append("setTimeout('showLockDialog()', " + hiddenTimeout + ");\n");
html.append("// -->\n");
html.append("</script>\n");
return html.toString();
}
/**
* Returns the report of all locked subresources.<p>
*
* @return the report of all locked subresources
*
* @throws JspException if dialog actions fail
* @throws IOException in case of errros forwarding to the required result page
* @throws ServletException in case of errros forwarding to the required result page
*/
public String buildReport() throws JspException, ServletException, IOException {
List lockedResources;
if (Boolean.valueOf(getParamShowownlocks()).booleanValue()) {
lockedResources = getLockedResources();
} else {
lockedResources = new ArrayList(getBlockingLockedResources());
}
Collections.sort(lockedResources);
Map lockParams = new HashMap();
if (getParamResource() != null) {
lockParams.put(PARAM_RESOURCE, getParamResource());
}
if (getParamResourcelist() != null) {
lockParams.put(PARAM_RESOURCELIST, getParamResourcelist());
}
if (getParamShowownlocks() != null) {
lockParams.put(PARAM_SHOWOWNLOCKS, getParamShowownlocks());
}
if (getParamIncluderelated() != null) {
lockParams.put(PARAM_INCLUDERELATED, getParamIncluderelated());
}
CmsLockedResourcesList list = new CmsLockedResourcesList(
getJsp(),
lockedResources,
CmsResource.getParentFolder((String)getResourceList().get(0)),
lockParams);
list.actionDialog();
list.getList().setBoxed(false);
StringBuffer result = new StringBuffer(512);
result.append("<input type='hidden' name='locks' value='");
result.append(getLockedResources().size()).append("'>\n");
result.append("<input type='hidden' name='blockinglocks' value='");
result.append(getBlockingLockedResources().size()).append("'>\n");
result.append(CmsStringUtil.padLeft("", 120 - result.length()));
result.append(CmsListExplorerColumn.getExplorerStyleDef());
result.append("<div style='height:150px; overflow: auto;'>\n");
result.append(list.getList().listHtml());
result.append("</div>\n");
return result.toString();
}
/**
* Builds the necessary button row.<p>
*
* @return the button row
*/
public String dialogButtons() {
if (CmsLock.getDialogAction(getCms()) != CmsLock.TYPE_LOCKS) {
return dialogButtonsOkCancel();
} else {
return dialogButtonsClose();
}
}
/**
* Returns the filter to get all blocking locks.<p>
*
* @return the filter to get all blocking locks
*/
public CmsLockFilter getBlockingFilter() {
if (m_blockingFilter == null) {
m_blockingFilter = CmsLockFilter.FILTER_ALL;
m_blockingFilter = m_blockingFilter.filterNotLockableByUser(getCms().getRequestContext().getCurrentUser());
}
return m_blockingFilter;
}
/**
* Returns locked resources that do not belong to the current user.<p>
*
* @return the locked Resources
*/
public Set getBlockingLockedResources() {
Set blockingResources = new HashSet();
Iterator i = getResourceList().iterator();
while (i.hasNext()) {
String resName = (String)i.next();
try {
blockingResources.addAll(getCms().getLockedResources(resName, getBlockingFilter()));
} catch (CmsException e) {
// error reading a resource, should usually never happen
if (LOG.isErrorEnabled()) {
LOG.error(e.getLocalizedMessage(), e);
}
}
if (Boolean.valueOf(getParamIncluderelated()).booleanValue()) {
addLockedRelatedResources(resName, getBlockingFilter(), blockingResources);
}
}
m_blockingLocks = blockingResources.size();
return blockingResources;
}
/**
* Returns the number of blocking locks.<p>
*
* @return the number of blocking locks
*/
public int getBlockingLocks() {
if (m_blockingLocks == -1) {
// to initialize the blocking locks flag
getLockedResources();
}
return m_blockingLocks;
}
/**
* @see org.opencms.configuration.I_CmsConfigurationParameterHandler#getConfiguration()
*/
public CmsParameterConfiguration getConfiguration() {
return CmsParameterConfiguration.EMPTY_PARAMETERS;
}
/**
* Returns the confirmation message.<p>
*
* @param state if <code>true</code> everything is ok
*
* @return the confirmation message
*/
public String getConfirmationMessage(boolean state) {
if (getDialogAction(getCms()) == TYPE_LOCKS) {
return "";
}
if (state) {
if (isMultiOperation()) {
return key(Messages.GUI_LOCK_MULTI_LOCK_CONFIRMATION_0);
} else {
return key(Messages.GUI_LOCK_CONFIRMATION_0);
}
}
switch (getDialogAction(getCms())) {
case TYPE_LOCK:
if (isMultiOperation()) {
return key(Messages.GUI_LOCK_MULTI_INFO_LOCKEDSUBRESOURCES_0);
} else {
return key(Messages.GUI_LOCK_INFO_LOCKEDSUBRESOURCES_0);
}
case TYPE_LOCKCHANGE:
return key(Messages.GUI_LOCK_CHANGE_CONFIRMATION_0);
case TYPE_UNLOCK:
if (isMultiOperation()) {
return key(Messages.GUI_LOCK_MULTI_UNLOCK_CONFIRMATION_0);
} else {
return key(Messages.GUI_LOCK_UNLOCK_CONFIRMATION_0);
}
case TYPE_LOCKS:
default:
return "";
}
}
/**
* @see org.opencms.workplace.I_CmsDialogHandler#getDialogHandler()
*/
public String getDialogHandler() {
return CmsDialogSelector.DIALOG_LOCK;
}
/**
* @see org.opencms.workplace.I_CmsDialogHandler#getDialogUri(java.lang.String, CmsJspActionElement)
*/
public String getDialogUri(String resource, CmsJspActionElement jsp) {
switch (getDialogAction(jsp.getCmsObject())) {
case TYPE_LOCK:
return URI_LOCK_DIALOG;
case TYPE_LOCKCHANGE:
return URI_LOCKCHANGE_DIALOG;
case TYPE_UNLOCK:
return URI_UNLOCK_DIALOG;
case TYPE_LOCKS:
default:
return URI_LOCKS_DIALOG;
}
}
/**
* Returns all the locked Resources.<p>
*
* @return all the locked Resources
*/
public List getLockedResources() {
if (m_lockedResources == null) {
// collect my locked resources
Set lockedResources = new HashSet();
Iterator i = getResourceList().iterator();
while (i.hasNext()) {
String resName = (String)i.next();
try {
lockedResources.addAll(getCms().getLockedResources(resName, getNonBlockingFilter()));
} catch (CmsException e) {
// error reading a resource, should usually never happen
if (LOG.isErrorEnabled()) {
LOG.error(e.getLocalizedMessage(getLocale()), e);
}
}
if (Boolean.valueOf(getParamIncluderelated()).booleanValue()) {
addLockedRelatedResources(resName, getNonBlockingFilter(), lockedResources);
}
}
// get blocking resources needs the locked resources
m_lockedResources = new ArrayList(lockedResources);
lockedResources.addAll(getBlockingLockedResources());
// create the locked resources list again, with the blocking locked resources
m_lockedResources = new ArrayList(lockedResources);
Collections.sort(m_lockedResources);
}
return m_lockedResources;
}
/**
* Returns the filter to get all non blocking locks.<p>
*
* @return the filter to get all non blocking locks
*/
public CmsLockFilter getNonBlockingFilter() {
if (m_nonBlockingFilter == null) {
m_nonBlockingFilter = CmsLockFilter.FILTER_ALL;
m_nonBlockingFilter = m_nonBlockingFilter.filterLockableByUser(getCms().getRequestContext().getCurrentUser());
m_nonBlockingFilter = m_nonBlockingFilter.filterSharedExclusive();
}
return m_nonBlockingFilter;
}
/**
* Returns the 'include unpublished related resources' parameter value.<p>
*
* @return the 'include unpublished related resources' parameter value
*/
public String getParamIncluderelated() {
return m_paramIncluderelated;
}
/**
* Returns the project id parameter value.<p>
*
* @return the project id parameter value
*/
public String getParamProjectid() {
return m_paramProjectid;
}
/**
* Returns the 'show own locked resources' parameter value.<p>
*
* @return the 'show own locked resources' parameter value
*/
public String getParamShowownlocks() {
return m_paramShowownlocks;
}
/**
* @see org.opencms.configuration.I_CmsConfigurationParameterHandler#initConfiguration()
*/
public void initConfiguration() {
// not implemented yet
}
/**
* Sets the filter to get all blocking locks.<p>
*
* @param blockingFilter the filter to set
*/
public void setBlockingFilter(CmsLockFilter blockingFilter) {
m_blockingFilter = blockingFilter;
// reset blocking locks count
m_blockingLocks = -1;
// reset locked resources
m_lockedResources = null;
}
/**
* Sets the filter to get all non blocking locks.<p>
*
* @param nonBlockingFilter the filter to set
*/
public void setNonBlockingFilter(CmsLockFilter nonBlockingFilter) {
m_nonBlockingFilter = nonBlockingFilter;
// reset locked resources
m_lockedResources = null;
}
/**
* Sets the 'include unpublished related resources' parameter value.<p>
*
* @param paramIncluderelated the 'include unpublished related resources' parameter value to set
*/
public void setParamIncluderelated(String paramIncluderelated) {
m_paramIncluderelated = paramIncluderelated;
}
/**
* Sets the project id parameter value.<p>
*
* @param projectid the project id parameter value to set
*/
public void setParamProjectid(String projectid) {
m_paramProjectid = projectid;
}
/**
* Sets the 'show own locked resources' parameter value.<p>
*
* @param paramShowownlocks the 'show own locked resources' parameter value to set
*/
public void setParamShowownlocks(String paramShowownlocks) {
m_paramShowownlocks = paramShowownlocks;
}
/**
* Determines whether to show the lock dialog depending on the users settings and the dilaog type.<p>
*
* In case of locking a folder, a confirmation dialog is needed if any sub resources are already locked.<p>
*
* @return true if dialogs should be shown, otherwise false
*/
public boolean showConfirmation() {
boolean showConfirmation = getSettings().getUserSettings().getDialogShowLock();
if (DIALOG_TYPE_LOCK.equals(getParamDialogtype())) {
// in case of locking resources, check if there are locked sub resources in the selected folder(s)
showConfirmation = showConfirmation || (getLockedResources().size() > 0);
}
return showConfirmation;
}
/**
* @see org.opencms.workplace.CmsWorkplace#initWorkplaceRequestValues(org.opencms.workplace.CmsWorkplaceSettings, javax.servlet.http.HttpServletRequest)
*/
protected void initWorkplaceRequestValues(CmsWorkplaceSettings settings, HttpServletRequest request) {
// fill the parameter values in the get/set methods
fillParamValues(request);
// set the action for the JSP switch
if (DIALOG_CONFIRMED.equals(getParamAction())) {
setAction(ACTION_CONFIRMED);
} else if (DIALOG_CANCEL.equals(getParamAction())) {
setAction(ACTION_CANCEL);
} else if (DIALOG_WAIT.equals(getParamAction())) {
setAction(ACTION_WAIT);
} else {
switch (getDialogAction(getCms())) {
case TYPE_LOCK:
setDialogTitle(Messages.GUI_LOCK_RESOURCE_1, Messages.GUI_LOCK_MULTI_LOCK_2);
setParamDialogtype(DIALOG_TYPE_LOCK);
// check the required permissions to lock/unlock
if (!checkResourcePermissions(CmsPermissionSet.ACCESS_WRITE, false)) {
// no write permissions for the resource, set cancel action to close dialog
setAction(ACTION_CANCEL);
return;
}
break;
case TYPE_LOCKCHANGE:
setDialogTitle(Messages.GUI_LOCK_STEAL_1, Messages.GUI_LOCK_MULTI_STEAL_2);
setParamDialogtype(DIALOG_TYPE_UNLOCK);
break;
case TYPE_UNLOCK:
setDialogTitle(Messages.GUI_LOCK_UNLOCK_1, Messages.GUI_LOCK_MULTI_UNLOCK_2);
setParamDialogtype(DIALOG_TYPE_UNLOCK);
break;
case TYPE_LOCKS:
default:
setDialogTitle(Messages.GUI_LOCK_LOCKS_1, Messages.GUI_LOCK_MULTI_LOCKS_2);
setParamDialogtype(DIALOG_TYPE_LOCKS);
}
// set action depending on user settings
if ((getDialogAction(getCms()) == TYPE_LOCKS) || showConfirmation()) {
// show confirmation dialog
setAction(ACTION_DEFAULT);
} else {
// lock/unlock resource without confirmation
setAction(ACTION_SUBMIT_NOCONFIRMATION);
}
}
if ((getParamResource() == null) && (getParamResourcelist() == null)) {
// this if in case of publish project
setParamResource("/");
}
}
/**
* Performs the lock/unlock/steal lock operation.<p>
*
* @return true, if the operation was performed, otherwise false
* @throws CmsException if operation is not successful
*/
protected boolean performDialogOperation() throws CmsException {
//on multi resource operation display "please wait" screen
if (isMultiOperation() && !DIALOG_WAIT.equals(getParamAction())) {
return false;
}
// determine action to perform (lock, unlock, change lock)
int dialogAction = getDialogAction(getCms());
// now perform the operation on the resource(s)
Iterator i = getResourceList().iterator();
while (i.hasNext()) {
String resName = (String)i.next();
try {
performSingleResourceOperation(resName, dialogAction);
} catch (CmsException e) {
// collect exceptions to create a detailed output
addMultiOperationException(e);
}
}
// generate the error message for exception
String message;
if (dialogAction == TYPE_LOCK) {
message = Messages.ERR_LOCK_MULTI_0;
} else {
message = Messages.ERR_UNLOCK_MULTI_0;
}
checkMultiOperationException(Messages.get(), message);
return true;
}
/**
* Performs the lock state operation on a single resource.<p>
*
* @param resourceName the resource name to perform the operation on
* @param dialogAction the lock action: lock, unlock or change lock
* @throws CmsException if the operation fails
*/
protected void performSingleResourceOperation(String resourceName, int dialogAction) throws CmsException {
// store original name to use for lock action
String originalResourceName = resourceName;
CmsResource res = getCms().readResource(resourceName, CmsResourceFilter.ALL);
if (res.isFolder() && !resourceName.endsWith("/")) {
resourceName += "/";
}
org.opencms.lock.CmsLock lock = getCms().getLock(res);
// perform action depending on dialog uri
switch (dialogAction) {
case TYPE_LOCKCHANGE:
case TYPE_LOCK:
if (lock.isNullLock()) {
getCms().lockResource(originalResourceName);
} else if (!lock.isDirectlyOwnedInProjectBy(getCms())) {
getCms().changeLock(resourceName);
}
break;
case TYPE_UNLOCK:
default:
if (lock.isNullLock()) {
break;
}
if (lock.isOwnedBy(getCms().getRequestContext().getCurrentUser())) {
getCms().unlockResource(resourceName);
}
}
}
/**
* Returns a set of locked unpublished related resources.<p>
*
* @param resName the resource to check the related resources for
* @param filter the lock filter to use
* @param lockedResources a set of site relative paths, of locked resources to exclude
*/
private void addLockedRelatedResources(String resName, CmsLockFilter filter, Set lockedResources) {
try {
// get and iterate over all related resources
Iterator itRelations = getCms().getRelationsForResource(
resName,
CmsRelationFilter.TARGETS.filterStrong().filterIncludeChildren()).iterator();
while (itRelations.hasNext()) {
CmsRelation relation = (CmsRelation)itRelations.next();
CmsResource target = null;
try {
target = relation.getTarget(getCms(), CmsResourceFilter.ALL);
} catch (CmsException e) {
// error reading a resource, should usually never happen
if (LOG.isDebugEnabled()) {
LOG.debug(e.getLocalizedMessage(getLocale()), e);
}
continue;
}
// we are interested just in unpublished resources
if (target.getState().isUnchanged()) {
continue;
}
String targetName = getCms().getSitePath(target);
// if already selected
if (lockedResources.contains(targetName) || lockedResources.contains(targetName + "*")) {
continue;
}
if (m_lockedResources != null) {
if (m_lockedResources.contains(targetName) || m_lockedResources.contains(targetName + "*")) {
continue;
}
}
try {
org.opencms.lock.CmsLock lock = getCms().getLock(targetName);
if (!lock.isUnlocked() && filter.match("/", lock)) {
// just add resources that may come in question
lockedResources.add(targetName + "*");
}
} catch (CmsException e) {
// error reading a lock, should usually never happen
if (LOG.isErrorEnabled()) {
LOG.error(e.getLocalizedMessage(getLocale()), e);
}
continue;
}
}
} catch (CmsException e) {
// error reading the relations, should usually never happen
if (LOG.isErrorEnabled()) {
LOG.error(e.getLocalizedMessage(getLocale()), e);
}
}
}
}