org.opencms.ade.publish.A_CmsPublishGroupHelper Maven / Gradle / Ivy
Show all versions of opencms-test Show documentation
/*
* This library is part of OpenCms -
* the Open Source Content Management System
*
* Copyright (c) Alkacon Software GmbH & Co. KG (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.publish;
import org.opencms.main.CmsLog;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.apache.commons.logging.Log;
/**
* Helper class for splitting a publish list into publish groups.
*
* @param the resource class type
* @param the resource group class type
*
* @since 8.0.0
*/
public abstract class A_CmsPublishGroupHelper {
/** An enum representing the age of a publish list resource. */
public enum GroupAge {
/** group age constant. */
medium, /** group age constant. */
old, /** group age constant. */
young
}
/**
* Comparator used for sorting publish resources.
*/
public class SortingComparator implements Comparator {
/**
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
public int compare(RESOURCE r1, RESOURCE r2) {
if (r1 == r2) {
return 0;
}
long date1 = getDateLastModified(r1);
long date2 = getDateLastModified(r2);
return (date1 > date2) ? -1 : (date1 < date2) ? 1 : 0;
}
}
/** The gap between session groups. */
protected static final int GROUP_SESSIONS_GAP = 8 * 60 * 60 * 1000;
/** The log instance for this class. */
private static final Log LOG = CmsLog.getLog(A_CmsPublishGroupHelper.class);
/** The current locale. */
private Locale m_locale;
/**
* Creates a new publish group helper for a given locale.
*
* @param locale the locale to use
*/
public A_CmsPublishGroupHelper(Locale locale) {
m_locale = locale;
}
/**
* Given a descending list of dates represented as longs, this method computes a map from the dates
* to their age in (local) days.
*
* @param sortedDates a descending list of dates represented as longs
*
* @return a map from dates to ages (measured in days)
*/
public Map computeDays(List sortedDates) {
if (sortedDates.isEmpty()) {
return Collections. emptyMap();
}
Map days = new HashMap();
long lastDate = System.currentTimeMillis();
int dayCounter = 0;
for (Long dateObj : sortedDates) {
long date = dateObj.longValue();
long dayDifference = getDayDifference(lastDate, date);
dayCounter += dayDifference;
lastDate = date;
days.put(dateObj, new Integer(dayCounter));
}
return days;
}
/**
* Computes a map from modification date to number of (local) days since the modification date.
*
* @param resources a list of resources
*
* @return a map from modification dates to the number of days since the modification date
*/
public Map computeDaysForResources(List resources) {
Map result = computeDays(getModificationDates(resources));
if (LOG.isDebugEnabled()) {
for (RESOURCE res : resources) {
LOG.debug(
"Resource "
+ getRootPath(res)
+ " is "
+ result.get(new Long(getDateLastModified(res)))
+ " days old.");
}
}
return result;
}
/**
* Gets the difference in days between to dates given as longs.
*
* The first date must be later than the second date.
*
* @param first the first date
* @param second the second date
*
* @return the difference between the two dates in days
*/
public int getDayDifference(long first, long second) {
Calendar firstDay = getStartOfDay(first);
Calendar secondDay = getStartOfDay(second);
int result = 0;
if (first >= second) {
while (firstDay.after(secondDay)) {
firstDay.add(Calendar.DAY_OF_MONTH, -1);
result += 1;
}
} else {
while (secondDay.after(firstDay)) {
secondDay.add(Calendar.DAY_OF_MONTH, -1);
result -= 1;
}
}
return result;
}
/**
* Splits a list of resources into groups.
*
* @param resources the list of resources
*
* @return the list of groups
*/
public List getGroups(List resources) {
List sortedResources = new ArrayList(resources);
Collections.sort(sortedResources, new SortingComparator());
Map daysMap = computeDaysForResources(sortedResources);
Map> resourcesByAge = partitionPublishResourcesByAge(sortedResources, daysMap);
List> youngGroups = partitionYoungResources(resourcesByAge.get(GroupAge.young));
List> mediumGroups = partitionMediumResources(resourcesByAge.get(GroupAge.medium), daysMap);
List oldGroup = resourcesByAge.get(GroupAge.old);
List resultGroups = new ArrayList();
for (List groupRes : youngGroups) {
String name = getPublishGroupName(groupRes, GroupAge.young);
resultGroups.add(createGroup(name, groupRes));
}
for (List groupRes : mediumGroups) {
String name = getPublishGroupName(groupRes, GroupAge.medium);
resultGroups.add(createGroup(name, groupRes));
}
if (!oldGroup.isEmpty()) {
String oldName = getPublishGroupName(oldGroup, GroupAge.old);
resultGroups.add(createGroup(oldName, oldGroup));
}
return resultGroups;
}
/**
* Given a list of resources, this method returns a list of their modification dates.
*
* @param resources a list of resources
*
* @return the modification dates of the resources, in the same order as the resources
*/
public List getModificationDates(List resources) {
List result = new ArrayList();
for (RESOURCE res : resources) {
result.add(new Long(getDateLastModified(res)));
}
return result;
}
/**
* Returns the localized name for a given publish group based on its age.
*
* @param resources the resources of the publish group
* @param age the age of the publish group
*
* @return the localized name of the publish group
*/
public String getPublishGroupName(List resources, GroupAge age) {
long groupDate = getDateLastModified(resources.get(0));
String groupName;
switch (age) {
case young:
groupName = Messages.get().getBundle(m_locale).key(
Messages.GUI_GROUPNAME_SESSION_1,
new Date(groupDate));
break;
case medium:
groupName = Messages.get().getBundle(m_locale).key(Messages.GUI_GROUPNAME_DAY_1, new Date(groupDate));
break;
case old:
default:
groupName = Messages.get().getBundle(m_locale).key(Messages.GUI_GROUPNAME_EVERYTHING_ELSE_0);
break;
}
return groupName;
}
/**
* Returns a calendar object representing the start of the day in which a given time lies.
*
* @param time a long representing a time
*
* @return a calendar object which represents the day in which the time lies
*/
public Calendar getStartOfDay(long time) {
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(time);
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH);
int day = cal.get(Calendar.DAY_OF_MONTH);
Calendar result = Calendar.getInstance();
result.set(Calendar.YEAR, year);
result.set(Calendar.MONTH, month);
result.set(Calendar.DAY_OF_MONTH, day);
return result;
}
/**
* Computes publish groups for a list of resources with age "medium".
*
* @param resources the list of resources
* @param days a map from modification dates to the number of days since the modification
*
* @return a list of publish groups
*/
public List> partitionMediumResources(List resources, Map days) {
if (resources.isEmpty()) {
return Collections.> emptyList();
}
RESOURCE firstRes = resources.get(0);
int lastDay = days.get(new Long(getDateLastModified(firstRes))).intValue();
List> result = new ArrayList>();
List currentGroup = new ArrayList();
result.add(currentGroup);
for (RESOURCE res : resources) {
LOG.debug("Processing medium-aged resource " + getRootPath(res));
int day = days.get(new Long(getDateLastModified(res))).intValue();
if (day != lastDay) {
LOG.debug("=== new group ===");
currentGroup = new ArrayList();
result.add(currentGroup);
}
lastDay = day;
currentGroup.add(res);
}
return result;
}
/**
* Partitions a list of resources by their age in (local) days since the last modification.
*
* @param resources the list of resources to partition
* @param days the map from modification dates to the number of (local) days since the modification
*
* @return a map from age enum values to the list of resources which fall into the corresponding age group
*/
public Map> partitionPublishResourcesByAge(
List resources,
Map days) {
List youngRes = new ArrayList();
List mediumRes = new ArrayList();
List oldRes = new ArrayList();
for (RESOURCE res : resources) {
int day = days.get(new Long(getDateLastModified(res))).intValue();
List listToAddTo = null;
if (day < 7) {
listToAddTo = youngRes;
LOG.debug("Classifying publish resource " + getRootPath(res) + " as young");
} else if (day < 28) {
listToAddTo = mediumRes;
LOG.debug("Classifying publish resource " + getRootPath(res) + " as medium-aged");
} else {
listToAddTo = oldRes;
LOG.debug("Classifying publish resource " + getRootPath(res) + " as old");
}
listToAddTo.add(res);
}
Map> result = new HashMap>();
result.put(GroupAge.young, youngRes);
result.put(GroupAge.medium, mediumRes);
result.put(GroupAge.old, oldRes);
return result;
}
/**
* Partitions the list of young resources into publish groups.
*
* @param resources the list of resources to partition
*
* @return a partition of the resources into publish groups
*/
public List> partitionYoungResources(List resources) {
if (resources.isEmpty()) {
return Collections.> emptyList();
}
List> result = new ArrayList>();
List currentGroup = new ArrayList();
result.add(currentGroup);
long lastDate = getDateLastModified(resources.get(0));
for (RESOURCE res : resources) {
LOG.debug("Processing young resource " + getRootPath(res));
long resDate = getDateLastModified(res);
if ((lastDate - resDate) > GROUP_SESSIONS_GAP) {
LOG.debug("=== new group ===");
currentGroup = new ArrayList();
result.add(currentGroup);
}
lastDate = resDate;
currentGroup.add(res);
}
return result;
}
/**
* Creates a named group of resources.
*
* @param name the name of the group
* @param resources the resources which should be put in the group
*
* @return the named group
*/
protected abstract GROUP createGroup(String name, List resources);
/**
* Gets the last modification date of a resource.
*
* @param res the resource
*
* @return the last modification date of res
*/
protected abstract long getDateLastModified(RESOURCE res);
/**
* Gets the root path of a resource.
*
* @param res the resource
*
* @return the root path of res
*/
protected abstract String getRootPath(RESOURCE res);
}