content: /*
   * This library is part of OpenCms -
   * the Open Source Content Management System
   *
   * Copyright (c) Alkacon Software GmbH & Co. KG (https://www.alkacon.com)
   *
   * This library is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
   * This library is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   * Lesser General Public License for more details.
   *
   * For further information about Alkacon Software GmbH & Co. KG, please see the
   * company website: https://www.alkacon.com
   *
   * For further information about OpenCms, please see the
   * project website: https://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.tools.content;
  
  import org.opencms.file.CmsProperty;
  import org.opencms.file.CmsPropertyDefinition;
  import org.opencms.file.CmsResource;
  import org.opencms.file.CmsVfsException;
  import org.opencms.i18n.CmsMessages;
  import org.opencms.jsp.CmsJspActionElement;
  import org.opencms.lock.CmsLock;
  import org.opencms.main.CmsException;
  import org.opencms.main.OpenCms;
  import org.opencms.workplace.CmsDialog;
  import org.opencms.workplace.CmsWorkplace;
  import org.opencms.workplace.CmsWorkplaceSettings;
  
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.Iterator;
  import java.util.List;
  
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  import javax.servlet.jsp.JspException;
  import javax.servlet.jsp.PageContext;
  
  /**
   * Provides methods for the delete property definition dialog.<p>
   *
   * @since 6.0.0
   */
  public class CmsPropertyDelete extends CmsDialog {
  
      /** Value for the action: delete cascade. */
      public static final int ACTION_DELETE_CASCADE = 100;
  
      /** Request parameter value for the action: delete cascade. */
      public static final String DIALOG_DELETE_CASCADE = "deletecascade";
  
      /** The dialog type. */
      public static final String DIALOG_TYPE = "propertydelete";
  
      /** Request parameter name for the property name. */
      public static final String PARAM_PROPERTYNAME = "propertyname";
  
      private String m_paramPropertyName;
  
      /**
       * Public constructor with JSP action element.<p>
       *
       * @param jsp an initialized JSP action element
       */
      public CmsPropertyDelete(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 CmsPropertyDelete(PageContext context, HttpServletRequest req, HttpServletResponse res) {
  
          this(new CmsJspActionElement(context, req, res));
      }
  
      /**
       * Deletes the property definition.<p>
       *
       * @throws JspException if problems including sub-elements occur
       */
      public void actionDelete() throws JspException {
  
          // save initialized instance of this class in request attribute for included sub-elements
          getJsp().getRequest().setAttribute(SESSION_WORKPLACE_CLASS, this);
          try {
              getCms().deletePropertyDefinition(getParamPropertyName());
              // close the dialog
              actionCloseDialog();
          } catch (Throwable e) {
              // error while deleting property definition, show error dialog
              includeErrorpage(this, e);
          }
      }
  
      /**
       * Deletes the property definition by cascading the properties on resources.<p>
       *
       * @throws JspException if problems including sub-elements occur
       */
      public void actionDeleteCascade() throws JspException {
  
          // save initialized instance of this class in request attribute for included sub-elements
          getJsp().getRequest().setAttribute(SESSION_WORKPLACE_CLASS, this);
          try {
              // list of all resources containing this propertydefinition
              List resourcesWithProperty = getCms().readResourcesWithProperty(getParamPropertyName());
              // list of all resources locked by another user, containing this propertydefinition
              List resourcesLockedByOtherUser = getResourcesLockedByOtherUser(resourcesWithProperty);
              // do the following operations only if all of the resources are not locked by another user
              if (resourcesLockedByOtherUser.isEmpty()) {
                  // save the site root
                  String storedSiteRoot = getCms().getRequestContext().getSiteRoot();
                  try {
                      // change to the root site
                      getCms().getRequestContext().setSiteRoot("/");
  
                      Iterator i = resourcesWithProperty.iterator();
                      while (i.hasNext()) {
                          CmsResource resource = (CmsResource)i.next();
                          // read the property object
                          CmsProperty property = getCms().readPropertyObject(
                              resource.getRootPath(),
                              getParamPropertyName(),
                              false);
                          // try to delete the property if it is not the NULL PROPERTY
                          // if the property is the NULL PROPERTY, it only had a shared
                          // value which was deleted at a sibling which was already processed
                          if (!property.isNullProperty()) {
                              CmsLock lock = getCms().getLock(resource);
                              if (lock.isUnlocked()) {
                                  // lock the resource for the current (Admin) user
                                  getCms().lockResource(resource.getRootPath());
                              }
                              property.setStructureValue(CmsProperty.DELETE_VALUE);
                              property.setResourceValue(CmsProperty.DELETE_VALUE);
                              // write the property with the null value to the resource and cascade it from the definition
                              getCms().writePropertyObject(resource.getRootPath(), property);
                              // unlock the resource
                              getCms().unlockResource(resource.getRootPath());
                          }
                      }
                      // delete the property definition at last
                      getCms().deletePropertyDefinition(getParamPropertyName());
                  } finally {
                      // restore the siteroot
                      getCms().getRequestContext().setSiteRoot(storedSiteRoot);
                      // close the dialog
                      actionCloseDialog();
                  }
              } else {
  
                  StringBuffer reason = new StringBuffer();
                  reason.append(dialogWhiteBoxStart());
                  reason.append(buildResourceList(resourcesLockedByOtherUser, true));
                  reason.append(dialogWhiteBoxEnd());
                  throw new CmsVfsException(
                      Messages.get().container(Messages.ERR_DEL_PROP_RESOURCES_LOCKED_1, reason.toString()));
              }
          } catch (Throwable e) {
              // error while deleting property definition, show error dialog
              includeErrorpage(this, e);
          }
      }
  
      /**
       * Builds a HTML list of Resources that use the specified property.<p>
       *
       * @throws CmsException if operation was not successful
       *
       * @return the HTML String for the Resource list
       */
      public String buildResourceList() throws CmsException {
  
          List resourcesWithProperty = getCms().readResourcesWithProperty(getParamPropertyName());
  
          return buildResourceList(resourcesWithProperty, false);
      }
  
      /**
       * Builds a HTML list of Resources.<p>
       *
       * Columns: Type, Name, Uri, Value of the property, locked by(optional).<p>
       *
       * @param resourceList a list of resources
       * @param lockInfo a boolean to decide if the locked info should be shown or not
       * @throws CmsException if operation was not successful
       *
       * @return the HTML String for the Resource list
       */
      public String buildResourceList(List resourceList, boolean lockInfo) throws CmsException {
  
          // reverse the resource list
          Collections.reverse(resourceList);
          CmsMessages messages = Messages.get().getBundle(getLocale());
          StringBuffer result = new StringBuffer();
          result.append("<table border=\"0\" width=\"100%\" cellpadding=\"1\" cellspacing=\"1\">\n");
          result.append("<tr>\n");
          // Type
          result.append("\t<td style=\"width:5%;\" class=\"textbold\">");
          result.append(messages.key(Messages.GUI_INPUT_TYPE_0));
          result.append("</td>\n");
          // Uri
          result.append("\t<td style=\"width:40%;\" class=\"textbold\">");
          result.append(messages.key(Messages.GUI_INPUT_ADRESS_0));
          result.append("</td>\n");
          // Name
          result.append("\t<td style=\"width:25%;\" class=\"textbold\">");
          result.append(messages.key(Messages.GUI_INPUT_TITLE_0));
          result.append("</td>\n");
          if (!lockInfo) {
              // Property value
              result.append("\t<td style=\"width:30%;\" class=\"textbold\">");
              result.append(messages.key(Messages.GUI_INPUT_PROPERTYVALUE_0));
              result.append("</td>\n");
          }
          if (lockInfo) {
              // Property value
              result.append("\t<td style=\"width:30%;\" class=\"textbold\">");
              result.append(messages.key(Messages.GUI_EXPLORER_LOCKEDBY_0));
              result.append("</td>\n");
              result.append("</tr>\n");
          }
          result.append("</tr>\n");
          result.append("<tr><td colspan=\"4\"><span style=\"height: 6px;\">&nbsp;</span></td></tr>\n");
  
          String storedSiteRoot = getCms().getRequestContext().getSiteRoot();
          try {
              getCms().getRequestContext().setSiteRoot("/");
              Iterator i = resourceList.iterator();
              while (i.hasNext()) {
                  CmsResource resource = (CmsResource)i.next();
                  String filetype = OpenCms.getResourceManager().getResourceType(resource.getTypeId()).getTypeName();
                  result.append("<tr>\n");
                  // file type
                  result.append("\t<td>");
                  result.append("<img src=\"");
                  result.append(getSkinUri());
                  result.append(CmsWorkplace.RES_PATH_FILETYPES);
                  result.append(filetype);
                  result.append(".gif\">");
                  result.append("</td>\n");
                  // file address
                  result.append("\t<td>");
                  result.append(resource.getRootPath());
                  result.append("</td>\n");
                  // title
                  result.append("\t<td>");
                  result.append(getJsp().property(CmsPropertyDefinition.PROPERTY_TITLE, resource.getRootPath(), ""));
                  result.append("</td>\n");
                  // current value of the property
                  if (!lockInfo) {
                      result.append("\t<td>");
                      result.append(getJsp().property(getParamPropertyName(), resource.getRootPath()));
                      result.append("</td>\n");
                  }
                  // locked by user
                  if (lockInfo) {
                      CmsLock lock = getCms().getLock(resource);
                      result.append("\t<td>");
                      result.append(getCms().readUser(lock.getUserId()).getName());
                      result.append("</td>\n");
                  }
                  result.append("</tr>\n");
              }
              result.append("</table>\n");
          } finally {
              getCms().getRequestContext().setSiteRoot(storedSiteRoot);
          }
  
          return result.toString();
      }
  
      /**
       * Builds the html for the property definition select box.<p>
       *
       * @param attributes optional attributes for the &lt;select&gt; tag
       * @return the html for the property definition select box
       */
      public String buildSelectProperty(String attributes) {
  
          return CmsPropertyChange.buildSelectProperty(
              getCms(),
              Messages.get().getBundle(getLocale()).key(Messages.GUI_PLEASE_SELECT_0),
              attributes,
              "");
      }
  
      /**
       * Returns the value of the propertyname parameter.<p>
       *
       * @return the value of the propertyname parameter
       */
      public String getParamPropertyName() {
  
          return m_paramPropertyName;
      }
  
      /**
       * Sets the value of the propertyname parameter.<p>
       *
       * @param paramPropertyName the value of the propertyname parameter
       */
      public void setParamPropertyName(String paramPropertyName) {
  
          m_paramPropertyName = paramPropertyName;
      }
  
      /**
       * @see org.opencms.workplace.CmsWorkplace#initWorkplaceRequestValues(org.opencms.workplace.CmsWorkplaceSettings, javax.servlet.http.HttpServletRequest)
       */
      @Override
      protected void initWorkplaceRequestValues(CmsWorkplaceSettings settings, HttpServletRequest request) {
  
          // fill the parameter values in the get/set methods
          fillParamValues(request);
          // set the dialog type
          setParamDialogtype(DIALOG_TYPE);
          // set the action for the JSP switch
          if (DIALOG_OK.equals(getParamAction())) {
              setAction(ACTION_OK);
              setParamTitle(Messages.get().getBundle(getLocale()).key(Messages.GUI_TITLE_PROPERTYDELETE_0)
                  + ": "
                  + getParamPropertyName());
          } else if (DIALOG_CANCEL.equals(getParamAction())) {
              setAction(ACTION_CANCEL);
          } else if (DIALOG_DELETE_CASCADE.equals(getParamAction())) {
              setAction(ACTION_DELETE_CASCADE);
          } else {
              setAction(ACTION_DEFAULT);
              // build title for change property value dialog
              setParamTitle(Messages.get().getBundle(getLocale()).key(Messages.GUI_TITLE_PROPERTYDELETE_0));
          }
      }
  
      /**
       * Returns a list of resources that are locked by another user as the current user.<p>
       *
       * @param resourceList the list of all (mixed) resources
       *
       * @return a list of resources that are locked by another user as the current user
       * @throws CmsException if the getLock operation fails
       */
      private List getResourcesLockedByOtherUser(List resourceList) throws CmsException {
  
          List lockedResourcesByOtherUser = new ArrayList();
          Iterator i = resourceList.iterator();
          while (i.hasNext()) {
              CmsResource resource = (CmsResource)i.next();
              // get the lock state for the resource
              CmsLock lock = getCms().getLock(resource);
              // add this resource to the list if this is locked by another user
              if (!lock.isUnlocked() && !lock.isOwnedBy(getCms().getRequestContext().getCurrentUser())) {
                  lockedResourcesByOtherUser.add(resource);
              }
          }
  
          return lockedResourcesByOtherUser;
      }
  }
  