/**
   * Returns a list item created from the resource information, differs between valid resources and
   * invalid resources.
   *
   * <p>
   *
   * @param resource the resource to create the list item from
   * @param list the list
   * @param showPermissions if to show permissions
   * @param showDateLastMod if to show the last modification date
   * @param showUserLastMod if to show the last modification user
   * @param showDateCreate if to show the creation date
   * @param showUserCreate if to show the creation date
   * @param showDateRel if to show the date released
   * @param showDateExp if to show the date expired
   * @param showState if to show the state
   * @param showLockedBy if to show the lock user
   * @param showSite if to show the site
   * @return a list item created from the resource information
   */
  protected CmsListItem createResourceListItem(
      CmsResource resource,
      CmsHtmlList list,
      boolean showPermissions,
      boolean showDateLastMod,
      boolean showUserLastMod,
      boolean showDateCreate,
      boolean showUserCreate,
      boolean showDateRel,
      boolean showDateExp,
      boolean showState,
      boolean showLockedBy,
      boolean showSite) {

    CmsListItem item = list.newItem(resource.getStructureId().toString());
    // get an initialized resource utility
    CmsResourceUtil resUtil = getWp().getResourceUtil();
    resUtil.setResource(resource);
    item.set(A_CmsListExplorerDialog.LIST_COLUMN_NAME, resUtil.getPath());
    item.set(A_CmsListExplorerDialog.LIST_COLUMN_ROOT_PATH, resUtil.getFullPath());
    item.set(A_CmsListExplorerDialog.LIST_COLUMN_TITLE, resUtil.getTitle());
    item.set(A_CmsListExplorerDialog.LIST_COLUMN_TYPE, resUtil.getResourceTypeName());
    item.set(A_CmsListExplorerDialog.LIST_COLUMN_SIZE, resUtil.getSizeString());
    if (showPermissions) {
      item.set(A_CmsListExplorerDialog.LIST_COLUMN_PERMISSIONS, resUtil.getPermissionString());
    }
    if (showDateLastMod) {
      item.set(
          A_CmsListExplorerDialog.LIST_COLUMN_DATELASTMOD,
          new Date(resource.getDateLastModified()));
    }
    if (showUserLastMod) {
      item.set(A_CmsListExplorerDialog.LIST_COLUMN_USERLASTMOD, resUtil.getUserLastModified());
    }
    if (showDateCreate) {
      item.set(A_CmsListExplorerDialog.LIST_COLUMN_DATECREATE, new Date(resource.getDateCreated()));
    }
    if (showUserCreate) {
      item.set(A_CmsListExplorerDialog.LIST_COLUMN_USERCREATE, resUtil.getUserCreated());
    }
    if (showDateRel) {
      item.set(A_CmsListExplorerDialog.LIST_COLUMN_DATEREL, new Date(resource.getDateReleased()));
    }
    if (showDateExp) {
      item.set(A_CmsListExplorerDialog.LIST_COLUMN_DATEEXP, new Date(resource.getDateExpired()));
    }
    if (showState) {
      item.set(A_CmsListExplorerDialog.LIST_COLUMN_STATE, resUtil.getStateName());
    }
    if (showLockedBy) {
      item.set(A_CmsListExplorerDialog.LIST_COLUMN_LOCKEDBY, resUtil.getLockedByName());
    }
    if (showSite) {
      item.set(A_CmsListExplorerDialog.LIST_COLUMN_SITE, resUtil.getSiteTitle());
    }
    setAdditionalColumns(item, resUtil);
    return item;
  }
  /** @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) */
  public int compare(CmsResource res0, CmsResource res1) {

    if (res0 == res1) {
      return 0;
    }

    CmsDateResourceComparator key0 = m_keys.get(res0.getStructureId());
    CmsDateResourceComparator key1 = m_keys.get(res1.getStructureId());

    if (key0 == null) {
      // initialize key if null
      key0 = CmsDateResourceComparator.create(m_cms, res0, m_dateIdentifiers);
      m_keys.put(res0.getStructureId(), key0);
    }
    if (key1 == null) {
      // initialize key if null
      key1 = CmsDateResourceComparator.create(m_cms, res1, m_dateIdentifiers);
      m_keys.put(res1.getStructureId(), key1);
    }

    if (m_asc) {
      // sort in ascending order
      if (key0.m_date > key1.m_date) {
        return 1;
      }
      if (key0.m_date < key1.m_date) {
        return -1;
      }
    } else {
      // sort in descending order
      if (key0.m_date > key1.m_date) {
        return -1;
      }
      if (key0.m_date < key1.m_date) {
        return 1;
      }
    }

    return 0;
  }
  /**
   * Wrapper method for caching the result of {@link #getResources(CmsObject, Map)}.
   *
   * <p>
   *
   * @param cms the cms object
   * @param params the parameter map
   * @return the result of {@link #getResources(CmsObject, Map)}
   * @throws CmsException if something goes wrong
   */
  protected List<CmsResource> getInternalResources(CmsObject cms, Map<String, String> params)
      throws CmsException {

    synchronized (this) {
      if (m_resources == null) {
        m_resources = getResources(cms, params);
        Iterator<CmsResource> it = m_resources.iterator();
        while (it.hasNext()) {
          CmsResource resource = it.next();
          m_resCache.put(resource.getStructureId().toString(), resource);
        }
      }
    }
    return m_resources;
  }
  /** @see java.lang.Object#toString() */
  @Override
  public String toString() {

    StringBuffer result = new StringBuffer();
    result.append(this.getClass().getName());
    result.append("[vfsName=");
    result.append(m_vfsName);
    result.append(", rfsName=");
    result.append(m_rfsName);
    if (m_resource != null) {
      result.append(", structureId=");
      result.append(m_resource.getStructureId());
    }
    result.append("]");
    return result.toString();
  }
  /**
   * Returns a list of list items from a list of resources.
   *
   * <p>
   *
   * @param parameter the collector parameter or <code>null</code> for default.
   *     <p>
   * @return a list of {@link CmsListItem} objects
   * @throws CmsException if something goes wrong
   */
  public List<CmsListItem> getListItems(String parameter) throws CmsException {

    synchronized (this) {
      if (parameter == null) {
        parameter = m_collectorParameter;
      }
      Map<String, String> params =
          CmsStringUtil.splitAsMap(
              parameter,
              I_CmsListResourceCollector.SEP_PARAM,
              I_CmsListResourceCollector.SEP_KEYVAL);
      CmsListState state = getState(params);
      List<CmsResource> resources = getInternalResources(getWp().getCms(), params);
      List<CmsListItem> ret = new ArrayList<CmsListItem>();
      if (LOG.isDebugEnabled()) {
        LOG.debug(
            Messages.get()
                .getBundle()
                .key(Messages.LOG_COLLECTOR_PROCESS_ITEMS_START_1, new Integer(resources.size())));
      }
      getWp().applyColumnVisibilities();
      CmsHtmlList list = getWp().getList();

      // check if progress should be set in the thread
      CmsProgressThread thread = null;
      int progressOffset = 0;
      if (Thread.currentThread() instanceof CmsProgressThread) {
        thread = (CmsProgressThread) Thread.currentThread();
        progressOffset = thread.getProgress();
      }

      CmsListColumnDefinition colPermissions =
          list.getMetadata().getColumnDefinition(A_CmsListExplorerDialog.LIST_COLUMN_PERMISSIONS);
      boolean showPermissions = (colPermissions.isVisible() || colPermissions.isPrintable());
      CmsListColumnDefinition colDateLastMod =
          list.getMetadata().getColumnDefinition(A_CmsListExplorerDialog.LIST_COLUMN_DATELASTMOD);
      boolean showDateLastMod = (colDateLastMod.isVisible() || colDateLastMod.isPrintable());
      CmsListColumnDefinition colUserLastMod =
          list.getMetadata().getColumnDefinition(A_CmsListExplorerDialog.LIST_COLUMN_USERLASTMOD);
      boolean showUserLastMod = (colUserLastMod.isVisible() || colUserLastMod.isPrintable());
      CmsListColumnDefinition colDateCreate =
          list.getMetadata().getColumnDefinition(A_CmsListExplorerDialog.LIST_COLUMN_DATECREATE);
      boolean showDateCreate = (colDateCreate.isVisible() || colDateCreate.isPrintable());
      CmsListColumnDefinition colUserCreate =
          list.getMetadata().getColumnDefinition(A_CmsListExplorerDialog.LIST_COLUMN_USERCREATE);
      boolean showUserCreate = (colUserCreate.isVisible() || colUserCreate.isPrintable());
      CmsListColumnDefinition colDateRel =
          list.getMetadata().getColumnDefinition(A_CmsListExplorerDialog.LIST_COLUMN_DATEREL);
      boolean showDateRel = (colDateRel.isVisible() || colDateRel.isPrintable());
      CmsListColumnDefinition colDateExp =
          list.getMetadata().getColumnDefinition(A_CmsListExplorerDialog.LIST_COLUMN_DATEEXP);
      boolean showDateExp = (colDateExp.isVisible() || colDateExp.isPrintable());
      CmsListColumnDefinition colState =
          list.getMetadata().getColumnDefinition(A_CmsListExplorerDialog.LIST_COLUMN_STATE);
      boolean showState = (colState.isVisible() || colState.isPrintable());
      CmsListColumnDefinition colLockedBy =
          list.getMetadata().getColumnDefinition(A_CmsListExplorerDialog.LIST_COLUMN_LOCKEDBY);
      boolean showLockedBy = (colLockedBy.isVisible() || colLockedBy.isPrintable());
      CmsListColumnDefinition colSite =
          list.getMetadata().getColumnDefinition(A_CmsListExplorerDialog.LIST_COLUMN_SITE);
      boolean showSite = (colSite.isVisible() || colSite.isPrintable());

      // get content
      Iterator<CmsResource> itRes = resources.iterator();
      int count = 0;
      while (itRes.hasNext()) {
        // set progress in thread
        if (thread != null) {
          count++;
          if (thread.isInterrupted()) {
            throw new CmsIllegalStateException(
                org.opencms.workplace.commons.Messages.get()
                    .container(org.opencms.workplace.commons.Messages.ERR_PROGRESS_INTERRUPTED_0));
          }
          thread.setProgress(((count * 40) / resources.size()) + progressOffset);
          thread.setDescription(
              org.opencms.workplace.commons.Messages.get()
                  .getBundle(thread.getLocale())
                  .key(
                      org.opencms.workplace.commons.Messages.GUI_PROGRESS_PUBLISH_STEP2_2,
                      new Integer(count),
                      new Integer(resources.size())));
        }

        Object obj = itRes.next();
        if (!(obj instanceof CmsResource)) {
          ret.add(getDummyListItem(list));
          continue;
        }
        CmsResource resource = (CmsResource) obj;
        CmsListItem item = m_liCache.get(resource.getStructureId().toString());
        if (item == null) {
          item =
              createResourceListItem(
                  resource,
                  list,
                  showPermissions,
                  showDateLastMod,
                  showUserLastMod,
                  showDateCreate,
                  showUserCreate,
                  showDateRel,
                  showDateExp,
                  showState,
                  showLockedBy,
                  showSite);
          m_liCache.put(resource.getStructureId().toString(), item);
        }
        ret.add(item);
      }
      CmsListMetadata metadata = list.getMetadata();
      if (metadata != null) {
        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(state.getFilter())) {
          // filter
          ret = metadata.getSearchAction().filter(ret, state.getFilter());
        }
        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(state.getColumn())) {
          if ((metadata.getColumnDefinition(state.getColumn()) != null)
              && metadata.getColumnDefinition(state.getColumn()).isSorteable()) {
            // sort
            I_CmsListItemComparator c =
                metadata.getColumnDefinition(state.getColumn()).getListItemComparator();
            Collections.sort(ret, c.getComparator(state.getColumn(), getWp().getLocale()));
            if (state.getOrder().equals(CmsListOrderEnum.ORDER_DESCENDING)) {
              Collections.reverse(ret);
            }
          }
        }
      }
      if (LOG.isDebugEnabled()) {
        LOG.debug(
            Messages.get()
                .getBundle()
                .key(Messages.LOG_COLLECTOR_PROCESS_ITEMS_END_1, new Integer(ret.size())));
      }
      return ret;
    }
  }