com.alkacon.opencms.documentcenter.NewDocumentsTree.java Source code

Java tutorial

Introduction

Here is the source code for com.alkacon.opencms.documentcenter.NewDocumentsTree.java

Source

/*
 * File   : $Source: /alkacon/cvs/alkacon/com.alkacon.opencms.documentcenter/src/com/alkacon/opencms/documentcenter/NewDocumentsTree.java,v $
 * Date   : $Date: 2010/03/19 15:31:13 $
 * Version: $Revision: 1.3 $
 *
 * This file is part of the Alkacon OpenCms Add-On Module Package
 *
 * Copyright (c) 2010 Alkacon Software GmbH (http://www.alkacon.com)
 *
 * The Alkacon OpenCms Add-On Module Package is free software: 
 * you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * The Alkacon OpenCms Add-On Module Package 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 General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with the Alkacon OpenCms Add-On Module Package.  
 * If not, see http://www.gnu.org/licenses/.
 *
 * 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.
 */

package com.alkacon.opencms.documentcenter;

import org.opencms.file.CmsObject;
import org.opencms.file.CmsResource;
import org.opencms.file.CmsResourceFilter;
import org.opencms.main.CmsException;
import org.opencms.main.CmsLog;
import org.opencms.util.CmsUUID;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.StringTokenizer;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.logging.Log;

/**
 * Helper class which provides static methods for the new documents functions of the document management.<p>
 *
 * @author  Andreas Zahner 
 * @author  Michael Emmerich 
 * 
 * @version $Revision: 1.3 $ 
 * 
 * @since 6.0.0 
 */
public final class NewDocumentsTree {

    /** Session key prefix. */
    protected static final String C_SESSION_KEY_PARAMS = NewDocumentsTree.class.getName() + ".param.";

    /** Session key for search all. */
    public static final String C_DOCUMENT_SEARCH_PARAM_ALL = C_SESSION_KEY_PARAMS + "all";

    /** Session key for categorylist. */
    public static final String C_DOCUMENT_SEARCH_PARAM_CATEGORYLIST = C_SESSION_KEY_PARAMS + "categoryList";

    /** Session key for enddate. */
    public static final String C_DOCUMENT_SEARCH_PARAM_ENDDATE = C_SESSION_KEY_PARAMS + "endDate";

    /** Session key for site. */
    public static final String C_DOCUMENT_SEARCH_PARAM_SITE = C_SESSION_KEY_PARAMS + "site";

    /** Session key for startdate. */
    public static final String C_DOCUMENT_SEARCH_PARAM_STARTDATE = C_SESSION_KEY_PARAMS + "startDate";

    /** The log object for this class. */
    private static final Log LOG = CmsLog.getLog(NewDocumentsTree.class);

    /**
     * Hide public constructor.<p> 
     */
    private NewDocumentsTree() {

        //noop
    }

    /**
     * Creates an HTML list with checkboxes for all given categories.<p>
     * 
     * @param categories list with the categories (LgtCategory)
     * @param attributes optional attributes for the input tags
     * @return the HTML code for a category input list
     */
    public static String buildCategoryList(List categories, String attributes) {

        StringBuffer retValue = new StringBuffer(128);
        Iterator i = categories.iterator();
        int counter = 0;
        while (i.hasNext()) {
            CmsCategory curCat = (CmsCategory) i.next();
            if (!"".equals(curCat.getCmsResource())) {
                retValue.append("<input type=\"checkbox\" name=\"cat" + counter + "\" id=\"cat" + counter
                        + "\" value=\"" + curCat.getCmsResource() + "\"");
                if (attributes != null) {
                    retValue.append(" " + attributes);
                }
                retValue.append(">&nbsp;");
                retValue.append(curCat.getTitle() + "<br>\n");
                counter++;
            }
        }

        // clear objects to release memory
        i = null;

        return retValue.toString();
    }

    /**
     * Builds the HTML code for a select box of days.<p>
     * 
     * @param timeMillis the time in milliseconds which should be preselected
     * @param fieldName the prefix of the name attribute
     * @param attributes optional additional attributes of the select tag
     * @param localeString the current locale String
     * @return the HTML code for a select box of days
     */
    public static String buildSelectDay(long timeMillis, String fieldName, String attributes, String localeString) {

        StringBuffer retValue = new StringBuffer(512);
        Locale locale = new Locale(localeString);
        Calendar cal = new GregorianCalendar(locale);
        cal.setTimeInMillis(timeMillis);

        retValue.append("<select name=\"" + fieldName + "day\"");
        if (attributes != null) {
            retValue.append(" " + attributes);
        }
        retValue.append(">\n");
        for (int i = 1; i < 32; i++) {
            retValue.append("\t<option value=\"" + i + "\"");
            if (cal.get(Calendar.DAY_OF_MONTH) == i) {
                retValue.append(" selected=\"selected\"");
            }
            retValue.append(">" + i + "</option>\n");
        }
        retValue.append("</select>\n");

        return retValue.toString();
    }

    /**
     * Builds the HTML code for a select box of months.<p>
     * 
     * @param timeMillis the time in milliseconds which should be preselected
     * @param fieldName the prefix of the name attribute
     * @param attributes optional additional attributes of the select tag
     * @param localeString the current locale String
     * @return the HTML code for a select box of months
     */
    public static String buildSelectMonth(long timeMillis, String fieldName, String attributes,
            String localeString) {

        StringBuffer retValue = new StringBuffer(512);
        Locale locale = new Locale(localeString);
        Calendar cal = new GregorianCalendar(locale);
        cal.setTimeInMillis(timeMillis);
        Calendar calTemp = new GregorianCalendar(locale);
        calTemp.setTimeInMillis(timeMillis);
        // set day to 2 to avoid display errors for days 29, 30 and 31
        calTemp.set(Calendar.DAY_OF_MONTH, 2);
        DateFormat df = new SimpleDateFormat("MMMM", locale);

        retValue.append("<select name=\"" + fieldName + "month\"");
        if (attributes != null) {
            retValue.append(" " + attributes);
        }
        retValue.append(">\n");
        for (int i = 0; i < 12; i++) {
            calTemp.set(Calendar.MONTH, i);
            retValue.append("\t<option value=\"" + (i + 1) + "\"");
            if (cal.get(Calendar.MONTH) == i) {
                retValue.append(" selected=\"selected\"");
            }
            retValue.append(">" + df.format(calTemp.getTime()) + "</option>\n");
        }
        retValue.append("</select>\n");

        return retValue.toString();
    }

    /**
     * Builds the HTML code for a select box of years.<p>
     * 
     * @param timeMillis the time in milliseconds which should be preselected
     * @param fieldName the prefix of the name attribute
     * @param attributes optional additional attributes of the select tag
     * @param localeString the current locale String
     * @param startyear the year to start with
     * @param endyear the last year to display in the selection
     * @return the HTML code for a select box of years
     */
    public static String buildSelectYear(long timeMillis, String fieldName, String attributes, String localeString,
            int startyear, int endyear) {

        StringBuffer retValue = new StringBuffer(512);
        Locale locale = new Locale(localeString);
        Calendar cal = new GregorianCalendar(locale);
        cal.setTimeInMillis(timeMillis);

        if (startyear > endyear) {
            startyear = endyear;
        }

        retValue.append("<select name=\"" + fieldName + "year\"");
        if (attributes != null) {
            retValue.append(" " + attributes);
        }
        retValue.append(">\n");
        for (int i = startyear; i <= endyear; i++) {
            retValue.append("\t<option value=\"" + i + "\"");
            if (cal.get(Calendar.YEAR) == i) {
                retValue.append(" selected=\"selected\"");
            }
            retValue.append(">" + i + "</option>\n");
        }
        retValue.append("</select>\n");

        return retValue.toString();
    }

    /**
     * Returns a list of resources which contains no linked entries.<p>
     * 
     * Links on the same resource entry are deleted from the list of resources.
     * This method has to be used after calling the method CmsObject.getResourcesInTimeRange(String, long, long);
     * 
     * @param resources the list of resources which may contain links
     * @return a filtered list of resources
     */
    public static List filterLinkedResources(List resources) {

        List filteredResources = new ArrayList();
        Set addedResources = new HashSet();
        long currentTime = System.currentTimeMillis();
        Iterator i = resources.iterator();

        while (i.hasNext()) {

            CmsResource currentResource = (CmsResource) i.next();

            // filter those documents that are folders or outside the release and expire window
            if (currentResource.isFolder() || (currentResource.getDateReleased() > currentTime)
                    || (currentResource.getDateExpired() < currentTime)) {
                // skip folders and resources outside time range
                continue;
            }

            if (CmsDocumentFactory.isIgnoredDocument(currentResource.getRootPath(), true)) {
                // this resource is ignored, skip it before checking the resource id
                continue;
            }

            CmsUUID resId = currentResource.getResourceId();

            if (!addedResources.contains(resId)) {

                // add resource to return list and ID to set
                addedResources.add(resId);
                filteredResources.add(currentResource);
            }
        }

        // clear objects to release memory
        i = null;
        addedResources = null;
        resources = null;

        return filteredResources;
    }

    /**
     * Returns a String which holds the selected categories for the result page of the new documents query.<p>
     * 
     * @param cms the CmsObject
     * @param request the HttpServletRequest
     * @param messageAll the localized message String used when all categories were selected
     * @return String with comma separated selected categories or localized "all" message
     */
    public static String getCategories(CmsObject cms, HttpServletRequest request, String messageAll) {

        StringBuffer retValue = new StringBuffer(128);

        // get the current user's HHTP session
        //HttpSession session = ((HttpServletRequest)cms.getRequestContext().getRequest().getOriginalRequest()).getSession();
        HttpSession session = request.getSession();

        // get the required parameters
        String paramAll = (String) session.getAttribute(C_DOCUMENT_SEARCH_PARAM_ALL);

        if ("true".equals(paramAll)) {
            return messageAll;
        } else {
            List categories = getCategoryList((String) session.getAttribute(C_DOCUMENT_SEARCH_PARAM_CATEGORYLIST));
            Iterator i = categories.iterator();
            while (i.hasNext()) {
                String path = (String) i.next();
                try {
                    retValue.append(cms.readPropertyObject(path, CmsCategory.CATEGORY_TITLE, false).getValue());
                } catch (CmsException e) {
                    // noop
                }
                if (i.hasNext()) {
                    retValue.append(", ");
                }
            }

            // clear objects to release memory
            categories = null;
            i = null;
        }
        return retValue.toString();
    }

    /**
     * Builds a list of the categories which were selected in the form.<p>
     * 
     * @param allCategories String with all selected category paths
     * @return List with all selected categories (holds String objects with absolute paths)
     */
    public static List getCategoryList(String allCategories) {

        ArrayList categories = new ArrayList();

        // get the indiviadual category paths from the token
        StringTokenizer T = new StringTokenizer(allCategories, CategoryTree.C_LIST_SEPARATOR);
        while (T.hasMoreTokens()) {
            String curToken = T.nextToken();
            if (!"".equals(curToken.trim())) {
                // add the category to the list
                categories.add(curToken);
            }
        }
        return categories;
    }

    /**
     * Returns a list of new resources in the specified folder or category folder depending on the request parameters.<p>
     * 
     * @param cms the CmsObject to perform some operations
     * @param request the HttpServletRequest to get the needed request parameters
     * @return the list of new resources
     */
    public static List getNewResources(CmsObject cms, HttpServletRequest request) {

        // get the current user's HHTP session
        //HttpSession session = ((HttpServletRequest)cms.getRequestContext().getRequest().getOriginalRequest()).getSession();
        HttpSession session = request.getSession();

        String startFolder = cms.getRequestContext().getFolderUri();

        // get the required parameters
        String paramAll = (String) session.getAttribute(C_DOCUMENT_SEARCH_PARAM_ALL);
        String paramStartDate = (String) session.getAttribute(C_DOCUMENT_SEARCH_PARAM_STARTDATE);
        String paramEndDate = (String) session.getAttribute(C_DOCUMENT_SEARCH_PARAM_ENDDATE);

        // parse the date Strings to long
        long startDate = Long.parseLong(paramStartDate);
        long endDate = Long.parseLong(paramEndDate);

        // create list of categories if selected
        List selectedCategoryList = new ArrayList();
        paramAll = (paramAll == null) ? "false" : paramAll;
        if (!"true".equals(paramAll)) {
            // search individual categories
            selectedCategoryList = getCategoryList(
                    (String) session.getAttribute(C_DOCUMENT_SEARCH_PARAM_CATEGORYLIST));
            if (selectedCategoryList.size() == 0) {
                return new ArrayList(0);
            }
        }

        String openedCategories = CategoryTree.getTreeInfo(cms, CategoryTree.C_USER_INFO_OPENED_CATEGORIES,
                request);
        List openedCategoryList = CategoryTree.commaStringToList(openedCategories, CategoryTree.C_LIST_SEPARATOR);

        return getNewResourceList(cms, startFolder, startDate, endDate, selectedCategoryList, openedCategoryList);
    }

    /**
     * Creates a nice localized date String from the given String.<p>
     * 
     * @param dateLongString the date as String representation of a long value
     * @param localeString the current locale String
     * @return nice formatted date string in long mode (e.g. 15. April 2003)
     */
    public static String getNiceDate(String dateLongString, String localeString) {

        Locale locale = new Locale(localeString.toLowerCase());
        DateFormat df = DateFormat.getDateInstance(DateFormat.LONG, locale);
        Calendar cal = new GregorianCalendar(locale);
        try {
            cal.setTimeInMillis(Long.parseLong(dateLongString));
        } catch (Exception e) {
            //noop
        }
        return df.format(cal.getTime());
    }

    /**
     * Creates a nice localized date String from the given day, month and year Strings.<p>
     * 
     * @param day the number of the day as String
     * @param month the number of the month as String
     * @param year the number of the year as String
     * @param localeString the current locale String
     * @return nice formatted date string in long mode (e.g. 15. April 2003)
     */
    public static String getNiceDate(String day, String month, String year, String localeString) {

        Locale locale = new Locale(localeString.toLowerCase());
        DateFormat df = DateFormat.getDateInstance(DateFormat.LONG, locale);
        Calendar cal = new GregorianCalendar(locale);
        try {
            cal.set(Integer.parseInt(year), Integer.parseInt(month) - 1, Integer.parseInt(day));
        } catch (Exception e) {
            // noop
        }
        return df.format(cal.getTime());
    }

    /**
     * Creates a list of new resources of the specified folder and filters the unwanted resources.<p>
     * 
     * If the parameter categoryFolders is an empty list, all new resources are returned, otherwise
     * only those resources which are in a subfolder specified by the list.<p>
     * @param cms the CmsObject
     * @param startFolder the root folder
     * @param startDate the start date in milliseconds
     * @param endDate the end date in milliseconds
     * @param selectedCategories list with selected categories/folders
     * @param openedCategories list with opened categories/folders
     * @return list of new resources
     */
    private static List getNewResourceList(CmsObject cms, String startFolder, long startDate, long endDate,
            List selectedCategories, List openedCategories) {

        List searchResult = null;
        List foundResources = null;
        Set addedResources = null;

        if (LOG.isDebugEnabled()) {

            StringBuffer buf = new StringBuffer();
            for (int i = 0, n = selectedCategories.size(); i < n; i++) {
                buf.append((String) selectedCategories.get(i));

                if (i < (n - 1)) {
                    buf.append(", ");
                }
            }

            LOG.debug("################ INPUT VALUES FOR NEW DOCUMENTS SEARCH");
            LOG.debug("startDate : " + startDate + " " + new java.util.Date(startDate).toString());
            LOG.debug("endDate : " + endDate + " " + new java.util.Date(endDate).toString());
            LOG.debug("startFolder : " + startFolder);
            LOG.debug("categories : " + buf.toString());
        }

        try {

            // get all resources in the site root which are in the time range
            CmsResourceFilter filter = CmsResourceFilter.IGNORE_EXPIRATION;
            filter = filter.addRequireLastModifiedAfter(startDate);
            filter = filter.addRequireLastModifiedBefore(endDate);
            foundResources = cms.readResources(startFolder, filter);
        } catch (CmsException e) {

            if (LOG.isErrorEnabled()) {
                LOG.error("Error reading resources in time range " + new java.util.Date(startDate).toString()
                        + " - " + new java.util.Date(endDate).toString() + " below folder " + startFolder, e);
            }
            foundResources = Collections.EMPTY_LIST;
        }

        if (selectedCategories.size() == 0) {

            // return all found resources with filtered links
            searchResult = filterLinkedResources(foundResources);
        } else {

            addedResources = new HashSet();
            searchResult = new ArrayList();
            long currentTime = System.currentTimeMillis();

            for (int i = 0, n = foundResources.size(); i < n; i++) {

                // analyze each resource if it has to be included in the search result

                CmsResource resource = (CmsResource) foundResources.get(i);

                // filter those documents that are folders or outside the release and expire window
                if (resource.isFolder() || (resource.getDateReleased() > currentTime)
                        || (resource.getDateExpired() < currentTime)) {
                    // skip folders and resources outside time range
                    continue;
                }

                String resourceName = cms.getRequestContext().removeSiteRoot(resource.getRootPath());
                String parentFolder = CmsResource.getParentFolder(resourceName);
                boolean addToResult = false;

                if (!selectedCategories.contains(parentFolder) && openedCategories.contains(parentFolder)) {

                    // skip resources that are inside an opened, but un-selected category/folder
                    continue;
                }

                // check if the parent folder of the resource is one of the selected categories/folders
                addToResult = selectedCategories.contains(parentFolder);

                if (!addToResult) {

                    // check if the resource is inside a collapsed sub-tree 
                    // of a selected category

                    int openedCategoryCount = 0;

                    while (!"/".equals(parentFolder)) {

                        if (openedCategories.contains(parentFolder)) {
                            openedCategoryCount++;
                        }

                        if (selectedCategories.contains(parentFolder) && (openedCategoryCount == 0)) {

                            // we found a selected parent category, 
                            // and it's sub-tree is collapsed
                            addToResult = true;
                            break;
                        }

                        parentFolder = CmsResource.getParentFolder(parentFolder);
                    }
                }

                if (!addToResult) {

                    // continue with the next resource
                    continue;
                }

                if (CmsDocumentFactory.isIgnoredDocument(resourceName, true)) {
                    // this resource is ignored, skip it before checking the resource id
                    continue;
                }

                // check if the resource is a sibling that has already been added to the search result
                CmsUUID resourceId = resource.getResourceId();
                if (!addedResources.contains(resourceId)) {

                    // add resource to the result
                    addedResources.add(resourceId);
                    searchResult.add(resource);
                }
            }
        }

        return searchResult;
    }

}