/*
* 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);
}
}