/* * This library is part of OpenCms - * the Open Source Content Management System * * Copyright (c) Alkacon Software GmbH (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.db.jpa; import org.opencms.configuration.CmsConfigurationManager; import org.opencms.configuration.CmsParameterConfiguration; import org.opencms.db.CmsDbContext; import org.opencms.db.CmsDbSqlException; import org.opencms.db.CmsDriverManager; import org.opencms.db.CmsSubscriptionFilter; import org.opencms.db.CmsSubscriptionReadMode; import org.opencms.db.CmsVisitEntry; import org.opencms.db.CmsVisitEntryFilter; import org.opencms.db.CmsVisitedByFilter; import org.opencms.db.I_CmsDriver; import org.opencms.db.I_CmsSubscriptionDriver; import org.opencms.db.jpa.persistence.CmsDAOSubscription; import org.opencms.db.jpa.persistence.CmsDAOSubscriptionVisit; import org.opencms.db.jpa.utils.CmsQueryLongParameter; import org.opencms.db.jpa.utils.CmsQueryStringParameter; import org.opencms.db.jpa.utils.I_CmsQueryParameter; import org.opencms.file.CmsDataAccessException; import org.opencms.file.CmsGroup; import org.opencms.file.CmsResource; import org.opencms.file.CmsUser; import org.opencms.file.history.I_CmsHistoryResource; import org.opencms.main.CmsException; import org.opencms.main.CmsLog; import org.opencms.main.OpenCms; import org.opencms.security.CmsPrincipal; import org.opencms.util.CmsFileUtil; import org.opencms.util.CmsPair; import org.opencms.util.CmsStringUtil; import org.opencms.util.CmsUUID; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import javax.persistence.PersistenceException; import javax.persistence.Query; import org.apache.commons.logging.Log; /** * JPA database server implementation of the subscription driver methods.<p> * * @since 8.0.0 */ public class CmsSubscriptionDriver implements I_CmsDriver, I_CmsSubscriptionDriver { /** Query key. */ private static final String C_RESOURCES_SELECT_BY_PARENT_UUID = "C_RESOURCES_SELECT_BY_PARENT_UUID"; /** Query key. */ private static final String C_RESOURCES_SELECT_BY_PATH_PREFIX = "C_RESOURCES_SELECT_BY_PATH_PREFIX"; /** Query key. */ private static final String C_SUBSCRIPTION_CHECK_2 = "C_SUBSCRIPTION_CHECK_2"; /** Query key. */ private static final String C_SUBSCRIPTION_DELETE = "C_SUBSCRIPTION_DELETE"; /** Query key. */ private static final String C_SUBSCRIPTION_DELETE_FILTER_DATE = "C_SUBSCRIPTION_DELETE_FILTER_DATE"; /** Query key. */ private static final String C_SUBSCRIPTION_DELETE_FILTER_PRINCIPAL = "C_SUBSCRIPTION_DELETE_FILTER_PRINCIPAL"; /** Query key. */ private static final String C_SUBSCRIPTION_DELETE_FILTER_STRUCTURE = "C_SUBSCRIPTION_DELETE_FILTER_STRUCTURE"; /** Query key. */ private static final String C_SUBSCRIPTION_DELETED = "C_SUBSCRIPTION_DELETED"; /** Query key. */ private static final String C_SUBSCRIPTION_DELETED_FILTER_PRINCIPAL_SINGLE = "C_SUBSCRIPTION_DELETED_FILTER_PRINCIPAL_SINGLE"; /** Query key. */ private static final String C_SUBSCRIPTION_DELETED_FILTER_PRINCIPALS = "C_SUBSCRIPTION_DELETED_FILTER_PRINCIPALS"; /** Query key. */ private static final String C_SUBSCRIPTION_FILTER_PRINCIPAL_SINGLE = "C_SUBSCRIPTION_FILTER_PRINCIPAL_SINGLE"; /** Query key. */ private static final String C_SUBSCRIPTION_FILTER_PRINCIPALS = "C_SUBSCRIPTION_FILTER_PRINCIPALS"; /** Query key. */ private static final String C_SUBSCRIPTION_FILTER_PRINCIPALS_END = "C_SUBSCRIPTION_FILTER_PRINCIPALS_END"; /** Query key. */ private static final String C_SUBSCRIPTION_FILTER_READ = "C_SUBSCRIPTION_FILTER_READ"; /** Query key. */ private static final String C_SUBSCRIPTION_FILTER_RESOURCES_DATE_MODIFIED = "C_SUBSCRIPTION_FILTER_RESOURCES_DATE_MODIFIED"; /** Query key. */ private static final String C_SUBSCRIPTION_READ_ALL_1 = "C_SUBSCRIPTION_READ_ALL_1"; /** Query key. */ private static final String C_SUBSCRIPTION_UPDATE_DATE_2 = "C_SUBSCRIPTION_UPDATE_DATE_2"; /** Query key. */ private static final String C_VISIT_DELETE_ENTRIES = "C_VISIT_DELETE_ENTRIES"; /** Query key. */ private static final String C_VISIT_FILTER_DATE_FROM = "C_VISIT_FILTER_DATE_FROM"; /** Query key. */ private static final String C_VISIT_FILTER_DATE_TO = "C_VISIT_FILTER_DATE_TO"; /** Query key. */ private static final String C_VISIT_FILTER_STRUCTURE_ID = "C_VISIT_FILTER_STRUCTURE_ID"; /** Query key. */ private static final String C_VISIT_FILTER_USER_ID = "C_VISIT_FILTER_USER_ID"; /** Query key. */ private static final String C_VISIT_READ_ENTRIES = "C_VISIT_READ_ENTRIES"; /** Query key. */ private static final String C_VISITED_USER_COUNT_1 = "C_VISITED_USER_COUNT_1"; /** Query key. */ private static final String C_VISITED_USER_DELETE_GETDATE_2 = "C_VISITED_USER_DELETE_GETDATE_2"; /** Query key. */ private static final String C_VISITED_USER_READ_4 = "C_VISITED_USER_READ_4"; /** The log object for this class. */ private static final Log LOG = CmsLog.getLog(org.opencms.db.generic.CmsSubscriptionDriver.class); /** A reference to the driver manager used by this driver. */ protected CmsDriverManager m_driverManager; /** The SQL manager used by this driver. */ protected CmsSqlManager m_sqlManager; /** * @see org.opencms.db.I_CmsSubscriptionDriver#deleteVisits(org.opencms.db.CmsDbContext, java.lang.String, org.opencms.db.CmsVisitEntryFilter) */ public void deleteVisits(CmsDbContext dbc, String poolName, CmsVisitEntryFilter filter) throws CmsDataAccessException { try { // compose statement StringBuffer queryBuf = new StringBuffer(256); queryBuf.append(m_sqlManager.readQuery(C_VISIT_DELETE_ENTRIES)); CmsPair<String, List<I_CmsQueryParameter>> conditionsAndParams = prepareVisitConditions(filter); queryBuf.append(conditionsAndParams.getFirst()); if (LOG.isDebugEnabled()) { LOG.debug(queryBuf.toString()); } Query q = m_sqlManager.createQueryFromJPQL(dbc, queryBuf.toString()); List<I_CmsQueryParameter> params = conditionsAndParams.getSecond(); for (int i = 0; i < params.size(); i++) { I_CmsQueryParameter param = conditionsAndParams.getSecond().get(i); param.insertIntoQuery(q, i + 1); } // execute q.executeUpdate(); } catch (PersistenceException e) { throw new CmsDbSqlException(Messages.get().container(Messages.ERR_GENERIC_SQL_1, C_VISIT_DELETE_ENTRIES), e); } } /** * @see org.opencms.db.I_CmsSubscriptionDriver#getDateLastVisitedBy(org.opencms.db.CmsDbContext, java.lang.String, org.opencms.file.CmsUser, org.opencms.file.CmsResource) */ public long getDateLastVisitedBy(CmsDbContext dbc, String poolName, CmsUser user, CmsResource resource) throws CmsException { CmsVisitEntryFilter filter = CmsVisitEntryFilter.ALL.filterResource(resource.getStructureId()).filterUser( user.getId()); List<CmsVisitEntry> entries = readVisits(dbc, poolName, filter); if (!entries.isEmpty()) { return entries.get(0).getDate(); } return 0; } /** * @see org.opencms.db.I_CmsSubscriptionDriver#getSqlManager() */ public CmsSqlManager getSqlManager() { return m_sqlManager; } /** * @see org.opencms.db.I_CmsDriver#init(org.opencms.db.CmsDbContext, org.opencms.configuration.CmsConfigurationManager, java.util.List, org.opencms.db.CmsDriverManager) */ public void init( CmsDbContext dbc, CmsConfigurationManager configurationManager, List<String> successiveDrivers, CmsDriverManager driverManager) { // TODO: Auto-generated method stub CmsParameterConfiguration config = configurationManager.getConfiguration(); String poolUrl = config.get("db.subscription.pool"); String classname = config.get("db.subscription.sqlmanager"); m_sqlManager = this.initSqlManager(classname); m_driverManager = driverManager; if (CmsLog.INIT.isInfoEnabled()) { CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_ASSIGNED_POOL_1, poolUrl)); } if ((successiveDrivers != null) && !successiveDrivers.isEmpty()) { if (LOG.isWarnEnabled()) { LOG.warn(Messages.get().getBundle().key( Messages.LOG_SUCCESSIVE_DRIVERS_UNSUPPORTED_1, getClass().getName())); } } } /** * @see org.opencms.db.I_CmsSubscriptionDriver#initSqlManager(java.lang.String) */ public CmsSqlManager initSqlManager(String classname) { return CmsSqlManager.getInstance(classname); } /** * @see org.opencms.db.I_CmsSubscriptionDriver#markResourceAsVisitedBy(org.opencms.db.CmsDbContext, java.lang.String, org.opencms.file.CmsResource, org.opencms.file.CmsUser) */ public void markResourceAsVisitedBy(CmsDbContext dbc, String poolName, CmsResource resource, CmsUser user) throws CmsDataAccessException { boolean entryExists = false; CmsVisitEntryFilter filter = CmsVisitEntryFilter.ALL.filterResource(resource.getStructureId()).filterUser( user.getId()); // delete existing visited entry for the resource if (readVisits(dbc, OpenCms.getSubscriptionManager().getPoolName(), filter).size() > 0) { entryExists = true; deleteVisits(dbc, OpenCms.getSubscriptionManager().getPoolName(), filter); } CmsVisitEntry entry = new CmsVisitEntry(user.getId(), System.currentTimeMillis(), resource.getStructureId()); addVisit(dbc, poolName, entry); if (!entryExists) { // new entry, check if maximum number of stored visited resources is exceeded int count = 0; try { Query q = m_sqlManager.createQuery(dbc, dbc.currentProject(), C_VISITED_USER_COUNT_1); q.setParameter(1, user.getId().toString()); count = ((Number)q.getSingleResult()).intValue(); int maxCount = OpenCms.getSubscriptionManager().getMaxVisitedCount(); if (count > maxCount) { // delete old visited entries q = m_sqlManager.createQuery(dbc, dbc.currentProject(), C_VISITED_USER_DELETE_GETDATE_2); q.setParameter(1, user.getId().toString()); q.setMaxResults(count - maxCount); @SuppressWarnings("unchecked") List<Number> res = q.getResultList(); long deleteDate = 0; for (Number n : res) { // get last date of result set deleteDate = n.longValue(); } if (deleteDate > 0) { filter = CmsVisitEntryFilter.ALL.filterUser(user.getId()).filterTo(deleteDate); deleteVisits(dbc, OpenCms.getSubscriptionManager().getPoolName(), filter); } } } catch (PersistenceException e) { throw new CmsDbSqlException(Messages.get().container( Messages.ERR_GENERIC_SQL_1, C_VISITED_USER_DELETE_GETDATE_2), e); } } } /** * @see org.opencms.db.I_CmsSubscriptionDriver#readAllSubscribedResources(org.opencms.db.CmsDbContext, java.lang.String, org.opencms.security.CmsPrincipal) */ public List<CmsResource> readAllSubscribedResources(CmsDbContext dbc, String poolName, CmsPrincipal principal) throws CmsDataAccessException { CmsResource currentResource = null; List<CmsResource> resources = new ArrayList<CmsResource>(); try { Query q = m_sqlManager.createQuery(dbc, dbc.currentProject(), C_SUBSCRIPTION_READ_ALL_1); q.setParameter(1, principal.getId().toString()); @SuppressWarnings("unchecked") List<Object[]> res = q.getResultList(); for (Object[] obj : res) { currentResource = ((CmsVfsDriver)m_driverManager.getVfsDriver(dbc)).createFile( obj, dbc.currentProject().getUuid(), false); resources.add(currentResource); } } catch (PersistenceException e) { throw new CmsDbSqlException( Messages.get().container(Messages.ERR_GENERIC_SQL_1, C_SUBSCRIPTION_READ_ALL_1), e); } return resources; } /** * @see org.opencms.db.I_CmsSubscriptionDriver#readResourcesVisitedBy(org.opencms.db.CmsDbContext, java.lang.String, org.opencms.db.CmsVisitedByFilter) */ public List<CmsResource> readResourcesVisitedBy(CmsDbContext dbc, String poolName, CmsVisitedByFilter filter) throws CmsDataAccessException { CmsResource currentResource = null; StringBuffer conditions = new StringBuffer(256); List<String> params = new ArrayList<String>(1); List<CmsResource> resources = new ArrayList<CmsResource>(); try { // path filter if (CmsStringUtil.isNotEmpty(filter.getParentPath())) { CmsResource parent = m_driverManager.getVfsDriver(dbc).readResource( dbc, dbc.currentProject().getUuid(), filter.getParentPath(), false); conditions.append(BEGIN_INCLUDE_CONDITION); if (filter.isIncludeSubFolders()) { conditions.append(m_sqlManager.readQuery(dbc.currentProject(), C_RESOURCES_SELECT_BY_PATH_PREFIX)); params.add(CmsFileUtil.addTrailingSeparator(CmsVfsDriver.escapeDbWildcard(filter.getParentPath())) + "%"); } else { conditions.append(m_sqlManager.readQuery(dbc.currentProject(), C_RESOURCES_SELECT_BY_PARENT_UUID)); params.add(parent.getStructureId().toString()); } conditions.append(END_CONDITION); } String query = m_sqlManager.readQuery(dbc.currentProject(), C_VISITED_USER_READ_4); query = CmsStringUtil.substitute(query, "%(CONDITIONS)", conditions.toString()); Query q = m_sqlManager.createQueryFromJPQL(dbc, query); q.setParameter(1, filter.getUser().getId().toString()); q.setParameter(2, Long.valueOf(filter.getFromDate())); q.setParameter(3, Long.valueOf(filter.getToDate())); for (int i = 0; i < params.size(); i++) { q.setParameter(i + 4, params.get(i)); } @SuppressWarnings("unchecked") List<Object[]> res = q.getResultList(); for (Object[] obj : res) { currentResource = ((CmsVfsDriver)m_driverManager.getVfsDriver(dbc)).createFile( obj, dbc.currentProject().getUuid(), false); resources.add(currentResource); } } catch (PersistenceException e) { throw new CmsDbSqlException(Messages.get().container(Messages.ERR_GENERIC_SQL_1, C_VISITED_USER_READ_4), e); } return resources; } /** * @see org.opencms.db.I_CmsSubscriptionDriver#readSubscribedDeletedResources(org.opencms.db.CmsDbContext, java.lang.String, org.opencms.file.CmsUser, java.util.List, org.opencms.file.CmsResource, boolean, long) */ public List<I_CmsHistoryResource> readSubscribedDeletedResources( CmsDbContext dbc, String poolName, CmsUser user, List<CmsGroup> groups, CmsResource parent, boolean includeSubFolders, long deletedFrom) throws CmsDataAccessException { List<I_CmsHistoryResource> resources = new ArrayList<I_CmsHistoryResource>(); Set<CmsUUID> historyIDs = new HashSet<CmsUUID>(); List<String> principalIds = new ArrayList<String>(); // add user ID principalIds.add(user.getId().toString()); // add group IDs if ((groups != null) && !groups.isEmpty()) { Iterator<CmsGroup> it = groups.iterator(); while (it.hasNext()) { principalIds.add(it.next().getId().toString()); } } StringBuffer conditions = new StringBuffer(256); List<String> params = new ArrayList<String>(); conditions.append(m_sqlManager.readQuery(C_SUBSCRIPTION_DELETED)); if (principalIds.size() == 1) { // single principal filter conditions.append(BEGIN_INCLUDE_CONDITION); conditions.append(m_sqlManager.readQuery(C_SUBSCRIPTION_DELETED_FILTER_PRINCIPAL_SINGLE)); params.add(principalIds.get(0)); conditions.append(END_CONDITION); } else { // multiple principals filter conditions.append(BEGIN_INCLUDE_CONDITION); conditions.append(m_sqlManager.readQuery(C_SUBSCRIPTION_DELETED_FILTER_PRINCIPALS)); conditions.append(BEGIN_CONDITION); Iterator<String> it = principalIds.iterator(); while (it.hasNext()) { params.add(it.next()); conditions.append("?"); if (it.hasNext()) { conditions.append(", "); } } conditions.append(END_CONDITION); conditions.append(END_CONDITION); } try { Query q = m_sqlManager.createQueryFromJPQL(dbc, conditions.toString()); // set parameters q.setParameter(1, Long.valueOf(deletedFrom)); for (int i = 0; i < params.size(); i++) { q.setParameter(i + 2, params.get(i)); } @SuppressWarnings("unchecked") List<String> result = q.getResultList(); for (String id : result) { historyIDs.add(new CmsUUID(id)); } } catch (PersistenceException e) { throw new CmsDbSqlException(Messages.get().container(Messages.ERR_GENERIC_SQL_1, C_SUBSCRIPTION_DELETED), e); } // get the matching history resources from the found structure IDs String parentFolderPath = ""; if (parent != null) { parentFolderPath = CmsResource.getFolderPath(parent.getRootPath()); } for (Iterator<CmsUUID> i = historyIDs.iterator(); i.hasNext();) { CmsUUID id = i.next(); int version = m_driverManager.getHistoryDriver(dbc).readLastVersion(dbc, id); if (version > 0) { I_CmsHistoryResource histRes = m_driverManager.getHistoryDriver(dbc).readResource(dbc, id, version); if (parent != null) { if (!includeSubFolders && !parentFolderPath.equals(CmsResource.getFolderPath(histRes.getRootPath()))) { // deleted history resource is not in the specified parent folder, skip it continue; } else if (includeSubFolders && !histRes.getRootPath().startsWith(parentFolderPath)) { // deleted history resource is not in the specified parent folder or sub folder, skip it continue; } } resources.add(histRes); } } return resources; } /** * @see org.opencms.db.I_CmsSubscriptionDriver#readSubscribedResources(org.opencms.db.CmsDbContext, java.lang.String, org.opencms.db.CmsSubscriptionFilter) */ public List<CmsResource> readSubscribedResources(CmsDbContext dbc, String poolName, CmsSubscriptionFilter filter) throws CmsDataAccessException { CmsResource currentResource = null; List<CmsResource> resources = new ArrayList<CmsResource>(); String queryBuf = m_sqlManager.readQuery(dbc.currentProject(), C_SUBSCRIPTION_FILTER_READ); StringBuffer conditions = new StringBuffer(256); List<I_CmsQueryParameter> params = new ArrayList<I_CmsQueryParameter>(); boolean userDefined = filter.getUser() != null; boolean groupsDefined = !filter.getGroups().isEmpty(); if (!groupsDefined && !userDefined) { filter.setUser(dbc.currentUser()); userDefined = true; } // check if a user has been set for the "visited" and "unvisited" mode if (!filter.getMode().isAll() && (filter.getUser() == null)) { // change the mode, without user the other modes are not applicable filter.setMode(CmsSubscriptionReadMode.ALL); } List<String> principalIds = new ArrayList<String>(); // add user ID if (userDefined) { principalIds.add(filter.getUser().getId().toString()); } // add group IDs if (groupsDefined) { Iterator<CmsGroup> it = filter.getGroups().iterator(); while (it.hasNext()) { principalIds.add(it.next().getId().toString()); } } if (principalIds.size() == 1) { // single principal filter conditions.append(BEGIN_CONDITION); conditions.append(m_sqlManager.readQuery(dbc.currentProject(), C_SUBSCRIPTION_FILTER_PRINCIPAL_SINGLE)); params.add(new CmsQueryStringParameter(principalIds.get(0))); conditions.append(END_CONDITION); } else { // multiple principals filter conditions.append(BEGIN_CONDITION); conditions.append(m_sqlManager.readQuery(C_SUBSCRIPTION_FILTER_PRINCIPALS)); conditions.append(BEGIN_CONDITION); Iterator<String> it = principalIds.iterator(); while (it.hasNext()) { params.add(new CmsQueryStringParameter(it.next())); conditions.append("?"); if (it.hasNext()) { conditions.append(", "); } } conditions.append(END_CONDITION); conditions.append(m_sqlManager.readQuery(dbc.currentProject(), C_SUBSCRIPTION_FILTER_PRINCIPALS_END)); conditions.append(END_CONDITION); } // path filter if (CmsStringUtil.isNotEmpty(filter.getParentPath())) { CmsResource parent = m_driverManager.getVfsDriver(dbc).readResource( dbc, dbc.currentProject().getUuid(), filter.getParentPath(), false); conditions.append(BEGIN_INCLUDE_CONDITION); if (filter.isIncludeSubFolders()) { conditions.append(m_sqlManager.readQuery(dbc.currentProject(), C_RESOURCES_SELECT_BY_PATH_PREFIX)); params.add(new CmsQueryStringParameter( CmsFileUtil.addTrailingSeparator(CmsVfsDriver.escapeDbWildcard(filter.getParentPath())) + "%")); } else { conditions.append(m_sqlManager.readQuery(dbc.currentProject(), C_RESOURCES_SELECT_BY_PARENT_UUID)); params.add(new CmsQueryStringParameter(parent.getStructureId().toString())); } conditions.append(END_CONDITION); } // check from and to date if ((filter.getFromDate() > 0) || (filter.getToDate() < Long.MAX_VALUE)) { conditions.append(BEGIN_INCLUDE_CONDITION); conditions.append(m_sqlManager.readQuery( dbc.currentProject(), C_SUBSCRIPTION_FILTER_RESOURCES_DATE_MODIFIED)); params.add(new CmsQueryLongParameter(filter.getFromDate())); params.add(new CmsQueryLongParameter(filter.getToDate())); conditions.append(END_CONDITION); } try { queryBuf = CmsStringUtil.substitute(queryBuf, "%(CONDITIONS)", conditions.toString()); if (LOG.isDebugEnabled()) { LOG.debug(queryBuf.toString()); } Query q = m_sqlManager.createQueryFromJPQL(dbc, queryBuf); // set parameters for (int i = 0; i < params.size(); i++) { I_CmsQueryParameter param = params.get(i); param.insertIntoQuery(q, i + 1); } @SuppressWarnings("unchecked") List<Object[]> res = q.getResultList(); for (Object[] obj : res) { currentResource = ((CmsVfsDriver)m_driverManager.getVfsDriver(dbc)).createFile( obj, dbc.currentProject().getUuid(), false); resources.add(currentResource); } // filter the result if in visited/unvisited mode (faster as creating a query with even more joined tables) if (!filter.getMode().isAll()) { List<CmsResource> result = new ArrayList<CmsResource>(resources.size()); for (Iterator<CmsResource> i = resources.iterator(); i.hasNext();) { CmsResource resource = i.next(); long visitedDate = 0; try { visitedDate = m_driverManager.getDateLastVisitedBy(dbc, poolName, filter.getUser(), resource); } catch (CmsException e) { throw new CmsDbSqlException(Messages.get().container(Messages.ERR_GENERIC_SQL_0), e); } if (filter.getMode().isUnVisited() && (visitedDate >= resource.getDateLastModified())) { // unvisited mode: resource was visited after the last modification, skip it continue; } if (filter.getMode().isVisited() && (resource.getDateLastModified() > visitedDate)) { // visited mode: resource was not visited after last modification, skip it continue; } // add the current resource to the result result.add(resource); } resources = result; } } catch (PersistenceException e) { throw new CmsDbSqlException( Messages.get().container(Messages.ERR_GENERIC_SQL_1, C_SUBSCRIPTION_FILTER_READ), e); } return resources; } /** * Reads {@link CmsVisitEntry} objects from the database.<p> * * @param dbc the database context to use * @param poolName the name of the pool which should be used for the database operation * @param filter a filter for constraining the list of results * * @return a list of visit entries * * @throws CmsDataAccessException if the database operation fails */ public List<CmsVisitEntry> readVisits(CmsDbContext dbc, String poolName, CmsVisitEntryFilter filter) throws CmsDataAccessException { List<CmsVisitEntry> entries = new ArrayList<CmsVisitEntry>(); try { // compose statement StringBuffer queryBuf = new StringBuffer(256); queryBuf.append(m_sqlManager.readQuery(C_VISIT_READ_ENTRIES)); CmsPair<String, List<I_CmsQueryParameter>> conditionsAndParameters = prepareVisitConditions(filter); List<I_CmsQueryParameter> params = conditionsAndParameters.getSecond(); queryBuf.append(conditionsAndParameters.getFirst()); if (LOG.isDebugEnabled()) { LOG.debug(queryBuf.toString()); } Query q = m_sqlManager.createQueryFromJPQL(dbc, queryBuf.toString()); for (int i = 0; i < params.size(); i++) { I_CmsQueryParameter param = params.get(i); param.insertIntoQuery(q, i + 1); } // execute @SuppressWarnings("unchecked") List<CmsDAOSubscriptionVisit> res = q.getResultList(); for (CmsDAOSubscriptionVisit sv : res) { // get results entries.add(internalReadVisitEntry(sv)); } } catch (PersistenceException e) { throw new CmsDbSqlException(Messages.get().container(Messages.ERR_GENERIC_SQL_1, C_VISIT_READ_ENTRIES), e); } return entries; } /** * @see org.opencms.db.I_CmsSubscriptionDriver#setSubscribedResourceAsDeleted(org.opencms.db.CmsDbContext, java.lang.String, org.opencms.file.CmsResource) */ public void setSubscribedResourceAsDeleted(CmsDbContext dbc, String poolName, CmsResource resource) throws CmsDataAccessException { long deletedTime = System.currentTimeMillis(); try { // set resource as deleted for all users and groups Query q = m_sqlManager.createQuery(dbc, C_SUBSCRIPTION_UPDATE_DATE_2); q.setParameter(1, resource.getStructureId().toString()); @SuppressWarnings("unchecked") List<CmsDAOSubscription> res = q.getResultList(); for (CmsDAOSubscription s : res) { s.setDateDeleted(deletedTime); } } catch (PersistenceException e) { throw new CmsDbSqlException(Messages.get().container( Messages.ERR_GENERIC_SQL_1, C_SUBSCRIPTION_UPDATE_DATE_2), e); } } /** * @see org.opencms.db.I_CmsSubscriptionDriver#subscribeResourceFor(org.opencms.db.CmsDbContext, java.lang.String, org.opencms.security.CmsPrincipal, org.opencms.file.CmsResource) */ public void subscribeResourceFor(CmsDbContext dbc, String poolName, CmsPrincipal principal, CmsResource resource) throws CmsDataAccessException { try { Query q = m_sqlManager.createQuery(dbc, C_SUBSCRIPTION_CHECK_2); q.setParameter(1, principal.getId().toString()); q.setParameter(2, resource.getStructureId().toString()); @SuppressWarnings("unchecked") List<CmsDAOSubscription> res = q.getResultList(); // only create subscription entry if principal is not subscribed to resource if (res.size() > 0) { // do nothing } else { // subscribe principal CmsDAOSubscription sb = new CmsDAOSubscription(); sb.setPrincipalId(principal.getId().toString()); sb.setStructureId(resource.getStructureId().toString()); sb.setDateDeleted(0); m_sqlManager.persist(dbc, sb); } } catch (PersistenceException e) { throw new CmsDbSqlException(Messages.get().container(Messages.ERR_GENERIC_SQL_1, C_SUBSCRIPTION_CHECK_2), e); } } /** * @see org.opencms.db.I_CmsSubscriptionDriver#unsubscribeAllDeletedResources(org.opencms.db.CmsDbContext, java.lang.String, long) */ public void unsubscribeAllDeletedResources(CmsDbContext dbc, String poolName, long deletedTo) throws CmsDataAccessException { try { StringBuffer conditions = new StringBuffer(256); // unsubscribe all deleted resources conditions.append(m_sqlManager.readQuery(C_SUBSCRIPTION_DELETE)); conditions.append(BEGIN_CONDITION); conditions.append(m_sqlManager.readQuery(C_SUBSCRIPTION_DELETE_FILTER_DATE)); conditions.append(END_CONDITION); Query q = m_sqlManager.createQueryFromJPQL(dbc, conditions.toString()); q.setParameter(1, Long.valueOf(deletedTo)); @SuppressWarnings("unchecked") List<CmsDAOSubscription> res = q.getResultList(); for (CmsDAOSubscription sb : res) { m_sqlManager.remove(dbc, sb); } } catch (PersistenceException e) { throw new CmsDbSqlException(Messages.get().container(Messages.ERR_GENERIC_SQL_1, C_SUBSCRIPTION_DELETE), e); } } /** * @see org.opencms.db.I_CmsSubscriptionDriver#unsubscribeAllResourcesFor(org.opencms.db.CmsDbContext, java.lang.String, org.opencms.security.CmsPrincipal) */ public void unsubscribeAllResourcesFor(CmsDbContext dbc, String poolName, CmsPrincipal principal) throws CmsDataAccessException { try { if (principal != null) { StringBuffer conditions = new StringBuffer(256); conditions.append(m_sqlManager.readQuery(C_SUBSCRIPTION_DELETE)); conditions.append(BEGIN_CONDITION); conditions.append(m_sqlManager.readQuery(C_SUBSCRIPTION_DELETE_FILTER_PRINCIPAL)); conditions.append(END_CONDITION); Query q = m_sqlManager.createQueryFromJPQL(dbc, conditions.toString()); q.setParameter(1, principal.getId().toString()); @SuppressWarnings("unchecked") List<CmsDAOSubscription> res = q.getResultList(); for (CmsDAOSubscription sb : res) { m_sqlManager.remove(dbc, sb); } } } catch (PersistenceException e) { throw new CmsDbSqlException(Messages.get().container(Messages.ERR_GENERIC_SQL_1, C_SUBSCRIPTION_DELETE), e); } } /** * @see org.opencms.db.I_CmsSubscriptionDriver#unsubscribeResourceFor(org.opencms.db.CmsDbContext, java.lang.String, org.opencms.security.CmsPrincipal, org.opencms.file.CmsResource) */ public void unsubscribeResourceFor(CmsDbContext dbc, String poolName, CmsPrincipal principal, CmsResource resource) throws CmsDataAccessException { try { StringBuffer conditions = new StringBuffer(256); conditions.append(m_sqlManager.readQuery(C_SUBSCRIPTION_DELETE)); conditions.append(BEGIN_CONDITION); conditions.append(m_sqlManager.readQuery(C_SUBSCRIPTION_DELETE_FILTER_PRINCIPAL)); conditions.append(END_CONDITION); conditions.append(BEGIN_INCLUDE_CONDITION); conditions.append(m_sqlManager.readQuery(C_SUBSCRIPTION_DELETE_FILTER_STRUCTURE)); conditions.append(END_CONDITION); Query q = m_sqlManager.createQueryFromJPQL(dbc, conditions.toString()); q.setParameter(1, principal.getId().toString()); q.setParameter(2, resource.getStructureId().toString()); @SuppressWarnings("unchecked") List<CmsDAOSubscription> res = q.getResultList(); for (CmsDAOSubscription sb : res) { m_sqlManager.remove(dbc, sb); } } catch (PersistenceException e) { throw new CmsDbSqlException(Messages.get().container(Messages.ERR_GENERIC_SQL_1, C_SUBSCRIPTION_DELETE), e); } } /** * @see org.opencms.db.I_CmsSubscriptionDriver#unsubscribeResourceForAll(org.opencms.db.CmsDbContext, java.lang.String, org.opencms.file.CmsResource) */ public void unsubscribeResourceForAll(CmsDbContext dbc, String poolName, CmsResource resource) throws CmsDataAccessException { try { StringBuffer conditions = new StringBuffer(256); // unsubscribe resource for all principals conditions.append(m_sqlManager.readQuery(C_SUBSCRIPTION_DELETE)); conditions.append(BEGIN_CONDITION); conditions.append(m_sqlManager.readQuery(C_SUBSCRIPTION_DELETE_FILTER_STRUCTURE)); conditions.append(END_CONDITION); Query q = m_sqlManager.createQueryFromJPQL(dbc, conditions.toString()); q.setParameter(1, resource.getStructureId().toString()); @SuppressWarnings("unchecked") List<CmsDAOSubscription> res = q.getResultList(); for (CmsDAOSubscription sb : res) { m_sqlManager.remove(dbc, sb); } } catch (PersistenceException e) { throw new CmsDbSqlException(Messages.get().container(Messages.ERR_GENERIC_SQL_1, C_SUBSCRIPTION_DELETE), e); } } /** * Adds an entry to the table of visits.<p> * * @param dbc the database context to use * @param poolName the name of the database pool to use * @param visit the visit bean * * @throws CmsDbSqlException if the database operation fails */ protected void addVisit(CmsDbContext dbc, String poolName, CmsVisitEntry visit) throws CmsDbSqlException { try { CmsDAOSubscriptionVisit sv = new CmsDAOSubscriptionVisit(); sv.setUserId(visit.getUserId().toString()); sv.setVisitDate(visit.getDate()); sv.setStructureId(visit.getStructureId() == null ? null : visit.getStructureId().toString()); m_sqlManager.persist(dbc, sv); } catch (PersistenceException e) { throw new CmsDbSqlException(Messages.get().container(Messages.ERR_GENERIC_SQL_1, ""), e); } } /** * Creates a new {@link CmsVisitEntry} object from the given result set entry.<p> * * @param sv the result set * * @return the new {@link CmsVisitEntry} object */ protected CmsVisitEntry internalReadVisitEntry(CmsDAOSubscriptionVisit sv) { CmsUUID userId = new CmsUUID(sv.getUserId()); long date = sv.getVisitDate(); CmsUUID structureId = new CmsUUID(sv.getStructureId()); return new CmsVisitEntry(userId, date, structureId); } /** * Build the whole WHERE SQL statement part for the given visit entry filter.<p> * * @param filter the filter * * @return a pair containing both the SQL and the parameters for it */ protected CmsPair<String, List<I_CmsQueryParameter>> prepareVisitConditions(CmsVisitEntryFilter filter) { List<I_CmsQueryParameter> params = new ArrayList<I_CmsQueryParameter>(); StringBuffer conditions = new StringBuffer(); // user id filter if (filter.getUserId() != null) { if (conditions.length() == 0) { conditions.append(BEGIN_CONDITION); } else { conditions.append(BEGIN_INCLUDE_CONDITION); } conditions.append(m_sqlManager.readQuery(C_VISIT_FILTER_USER_ID)); params.add(new CmsQueryStringParameter(filter.getUserId().toString())); conditions.append(END_CONDITION); } // resource id filter if (filter.getStructureId() != null) { if (conditions.length() == 0) { conditions.append(BEGIN_CONDITION); } else { conditions.append(BEGIN_INCLUDE_CONDITION); } conditions.append(m_sqlManager.readQuery(C_VISIT_FILTER_STRUCTURE_ID)); params.add(new CmsQueryStringParameter(filter.getStructureId().toString())); conditions.append(END_CONDITION); } // date from filter if (filter.getDateFrom() != CmsResource.DATE_RELEASED_DEFAULT) { if (conditions.length() == 0) { conditions.append(BEGIN_CONDITION); } else { conditions.append(BEGIN_INCLUDE_CONDITION); } conditions.append(m_sqlManager.readQuery(C_VISIT_FILTER_DATE_FROM)); params.add(new CmsQueryLongParameter(filter.getDateFrom())); conditions.append(END_CONDITION); } // date to filter if (filter.getDateTo() != CmsResource.DATE_RELEASED_DEFAULT) { if (conditions.length() == 0) { conditions.append(BEGIN_CONDITION); } else { conditions.append(BEGIN_INCLUDE_CONDITION); } conditions.append(m_sqlManager.readQuery(C_VISIT_FILTER_DATE_TO)); params.add(new CmsQueryLongParameter(filter.getDateTo())); conditions.append(END_CONDITION); } return CmsPair.create(conditions.toString(), params); } }