All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opencms.notification.CmsNotificationCandidates Maven / Gradle / Ivy

Go to download

OpenCms is an enterprise-ready, easy to use website content management system based on Java and XML technology. Offering a complete set of features, OpenCms helps content managers worldwide to create and maintain beautiful websites fast and efficiently.

There is a newer version: 18.0
Show newest version
/*
 * 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.notification;

import org.opencms.db.CmsDbEntryNotFoundException;
import org.opencms.db.CmsUserSettings;
import org.opencms.file.CmsObject;
import org.opencms.file.CmsPropertyDefinition;
import org.opencms.file.CmsResource;
import org.opencms.file.CmsResourceFilter;
import org.opencms.file.CmsUser;
import org.opencms.i18n.CmsLocaleManager;
import org.opencms.main.CmsException;
import org.opencms.main.CmsLog;
import org.opencms.main.OpenCms;
import org.opencms.util.CmsStringUtil;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;

import org.apache.commons.logging.Log;
import org.apache.commons.mail.EmailException;

/**
 * The basic class for the content notification feature in OpenCms. Collects all resources that require a notification,
 * creates and sends notifications to their responsible users.

* */ public class CmsNotificationCandidates { /** The log object for this class. */ private static final Log LOG = CmsLog.getLog(CmsNotificationCandidates.class); /** the CmsObject. */ private CmsObject m_cms; /** The resources which come into question for notifications of responsible users. */ private List m_resources; /** * Collects all resources that will expire in short time, or will become valid, or are not modified since a long time.

* * @param cms the CmsObject * * @throws CmsException if something goes wrong */ public CmsNotificationCandidates(CmsObject cms) throws CmsException { m_resources = new ArrayList(); m_cms = cms; m_cms.getRequestContext().setCurrentProject( m_cms.readProject(OpenCms.getSystemInfo().getNotificationProject())); String folder = "/"; GregorianCalendar now = new GregorianCalendar(TimeZone.getDefault(), CmsLocaleManager.getDefaultLocale()); now.setTimeInMillis(System.currentTimeMillis()); GregorianCalendar inOneWeek = (GregorianCalendar)now.clone(); inOneWeek.add(Calendar.WEEK_OF_YEAR, 1); Iterator resources; CmsResource resource; // read all files with the 'notification-interval' property set try { resources = m_cms.readResourcesWithProperty( folder, CmsPropertyDefinition.PROPERTY_NOTIFICATION_INTERVAL).iterator(); while (resources.hasNext()) { resource = resources.next(); int notification_interval = Integer.parseInt( m_cms.readPropertyObject( resource, CmsPropertyDefinition.PROPERTY_NOTIFICATION_INTERVAL, true).getValue()); GregorianCalendar intervalBefore = new GregorianCalendar( TimeZone.getDefault(), CmsLocaleManager.getDefaultLocale()); intervalBefore.setTimeInMillis(resource.getDateLastModified()); intervalBefore.add(Calendar.DAY_OF_YEAR, notification_interval); GregorianCalendar intervalAfter = (GregorianCalendar)intervalBefore.clone(); intervalAfter.add(Calendar.WEEK_OF_YEAR, -1); for (int i = 0; (i < 100) && intervalAfter.getTime().before(now.getTime()); i++) { if (intervalBefore.getTime().after(now.getTime())) { m_resources.add( new CmsExtendedNotificationCause( resource, CmsExtendedNotificationCause.RESOURCE_UPDATE_REQUIRED, intervalBefore.getTime())); } intervalBefore.add(Calendar.DAY_OF_YEAR, notification_interval); intervalAfter.add(Calendar.DAY_OF_YEAR, notification_interval); } } } catch (CmsDbEntryNotFoundException e) { // no resources with property 'notification-interval', ignore } // read all files that were not modified longer than the max notification-time GregorianCalendar oneYearAgo = (GregorianCalendar)now.clone(); oneYearAgo.add(Calendar.DAY_OF_YEAR, -OpenCms.getSystemInfo().getNotificationTime()); // create a resource filter to get the resources with CmsResourceFilter filter = CmsResourceFilter.IGNORE_EXPIRATION.addRequireLastModifiedBefore( oneYearAgo.getTimeInMillis()); resources = m_cms.readResources(folder, filter).iterator(); while (resources.hasNext()) { resource = resources.next(); m_resources.add( new CmsExtendedNotificationCause( resource, CmsExtendedNotificationCause.RESOURCE_OUTDATED, new Date(resource.getDateLastModified()))); } // get all resources that will expire within the next week CmsResourceFilter resourceFilter = CmsResourceFilter.IGNORE_EXPIRATION.addRequireExpireBefore( inOneWeek.getTimeInMillis()); resourceFilter = resourceFilter.addRequireExpireAfter(now.getTimeInMillis()); resources = m_cms.readResources(folder, resourceFilter).iterator(); while (resources.hasNext()) { resource = resources.next(); m_resources.add( new CmsExtendedNotificationCause( resource, CmsExtendedNotificationCause.RESOURCE_EXPIRES, new Date(resource.getDateExpired()))); } // get all resources that will release within the next week resourceFilter = CmsResourceFilter.IGNORE_EXPIRATION.addRequireReleaseBefore(inOneWeek.getTimeInMillis()); resourceFilter = resourceFilter.addRequireReleaseAfter(now.getTimeInMillis()); resources = m_cms.readResources(folder, resourceFilter).iterator(); while (resources.hasNext()) { resource = resources.next(); m_resources.add( new CmsExtendedNotificationCause( resource, CmsExtendedNotificationCause.RESOURCE_RELEASE, new Date(resource.getDateReleased()))); } } /** * Sends all notifications to the responsible users.

* * @return a string listing all responsibles that a notification was sent to * * @throws CmsException if something goes wrong */ public String notifyResponsibles() throws CmsException { Iterator notifications = filterConfirmedResources(getContentNotifications()).iterator(); if (notifications.hasNext()) { StringBuffer result = new StringBuffer( Messages.get().getBundle().key(Messages.LOG_NOTIFICATIONS_SENT_TO_0)); result.append(' '); while (notifications.hasNext()) { CmsContentNotification contentNotification = notifications.next(); result.append(contentNotification.getResponsible().getName()); if (notifications.hasNext()) { result.append(", "); } try { contentNotification.send(); } catch (EmailException e) { LOG.error(e.getLocalizedMessage(), e); } } return result.toString(); } else { return Messages.get().getBundle().key(Messages.LOG_NO_NOTIFICATIONS_SENT_0); } } /** * Returns a collection of CmsContentNotifications, one for each responsible that receives a notification.

* * @return the list of CmsContentNotifications, one for each responsible that receives a notification * * @throws CmsException if something goes wrong */ protected Collection getContentNotifications() throws CmsException { // get all owners for the resource Iterator notificationCandidates = m_resources.iterator(); Map result = new HashMap(); while (notificationCandidates.hasNext()) { CmsExtendedNotificationCause resourceInfo = notificationCandidates.next(); CmsResource resource = resourceInfo.getResource(); // skip, if content notification is not enabled for this resource String enableNotification = m_cms.readPropertyObject( resource, CmsPropertyDefinition.PROPERTY_ENABLE_NOTIFICATION, true).getValue(); if (Boolean.valueOf(enableNotification).booleanValue()) { try { Iterator responsibles = m_cms.readResponsibleUsers(resource).iterator(); while (responsibles.hasNext()) { CmsUser responsible = responsibles.next(); if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(responsible.getEmail())) { // check, if resultset already contains a content notification for the user CmsContentNotification contentNotification = result.get(responsible); // if not add a new content notification if (contentNotification == null) { contentNotification = new CmsContentNotification(responsible, m_cms); result.put(responsible, contentNotification); } List resourcesForResponsible = contentNotification.getNotificationCauses(); if (resourcesForResponsible == null) { resourcesForResponsible = new ArrayList(); contentNotification.setNotificationCauses(resourcesForResponsible); } resourcesForResponsible.add(resourceInfo); } } } catch (CmsException e) { if (LOG.isInfoEnabled()) { LOG.error(e.getLocalizedMessage(), e); } } } } return result.values(); } /** * Updates the resources that were confirmed by the user. That means deletes the resources that need not a * notification any more. * removes all resources which do not occur in the candidate list.

* * @param contentNotifications the list of {@link CmsContentNotification} objects to remove from the set of confirmed resources * @return a new CmsConfirmedResources Object which all the resource removed */ private Collection filterConfirmedResources( Collection contentNotifications) { Iterator notifications = contentNotifications.iterator(); while (notifications.hasNext()) { CmsContentNotification contentNotification = notifications.next(); CmsUser responsible = contentNotification.getResponsible(); // check, if user was already notified List confirmedResourcesList = (List)responsible.getAdditionalInfo( CmsUserSettings.ADDITIONAL_INFO_CONFIRMED_RESOURCES); if (confirmedResourcesList == null) { confirmedResourcesList = new ArrayList(); responsible.setAdditionalInfo( CmsUserSettings.ADDITIONAL_INFO_CONFIRMED_RESOURCES, new ArrayList()); } List notificationCandidates = contentNotification.getNotificationCauses(); List notificationResources = new ArrayList( notificationCandidates); // remove already confirmed resources Iterator i = confirmedResourcesList.iterator(); while (i.hasNext()) { Object o = i.next(); if (notificationResources.contains(o)) { notificationResources.remove(o); } } // filter confirmed resources i = new ArrayList(confirmedResourcesList).iterator(); while (i.hasNext()) { Object o = i.next(); if (!notificationCandidates.contains(o)) { confirmedResourcesList.remove(o); } } if (notificationResources.isEmpty()) { // Remove notification, if resource list is empty contentNotifications.remove(contentNotification); } else { contentNotification.setNotificationCauses(notificationResources); } try { m_cms.writeUser(responsible); } catch (CmsException e) { LOG.error(e.getLocalizedMessage(), e); } } return contentNotifications; } }