/*
* 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.CmsDbConsistencyException;
import org.opencms.db.CmsDbContext;
import org.opencms.db.CmsDbEntryNotFoundException;
import org.opencms.db.CmsDbSqlException;
import org.opencms.db.CmsDriverManager;
import org.opencms.db.CmsResourceState;
import org.opencms.db.CmsVfsOnlineResourceAlreadyExistsException;
import org.opencms.db.I_CmsDriver;
import org.opencms.db.I_CmsProjectDriver;
import org.opencms.db.I_CmsVfsDriver;
import org.opencms.db.jpa.persistence.CmsDAOContents;
import org.opencms.db.jpa.persistence.CmsDAOCounters;
import org.opencms.db.jpa.persistence.CmsDAOOfflineContents;
import org.opencms.db.jpa.persistence.CmsDAOOfflineProperties;
import org.opencms.db.jpa.persistence.CmsDAOOfflinePropertyDef;
import org.opencms.db.jpa.persistence.CmsDAOOfflineResourceRelations;
import org.opencms.db.jpa.persistence.CmsDAOOfflineResources;
import org.opencms.db.jpa.persistence.CmsDAOOfflineStructure;
import org.opencms.db.jpa.persistence.CmsDAOOfflineUrlNameMappings;
import org.opencms.db.jpa.persistence.CmsDAOOnlineProperties;
import org.opencms.db.jpa.persistence.CmsDAOOnlinePropertyDef;
import org.opencms.db.jpa.persistence.CmsDAOOnlineResourceRelations;
import org.opencms.db.jpa.persistence.CmsDAOOnlineResources;
import org.opencms.db.jpa.persistence.CmsDAOOnlineStructure;
import org.opencms.db.jpa.persistence.CmsDAOOnlineUrlNameMappings;
import org.opencms.db.jpa.persistence.I_CmsDAOProperties;
import org.opencms.db.jpa.persistence.I_CmsDAOPropertyDef;
import org.opencms.db.jpa.persistence.I_CmsDAOResourceRelations;
import org.opencms.db.jpa.persistence.I_CmsDAOResources;
import org.opencms.db.jpa.persistence.I_CmsDAOStructure;
import org.opencms.db.jpa.persistence.I_CmsDAOUrlNameMappings;
import org.opencms.db.jpa.utils.CmsQueryIntParameter;
import org.opencms.db.jpa.utils.CmsQueryStringParameter;
import org.opencms.db.jpa.utils.I_CmsQueryParameter;
import org.opencms.db.urlname.CmsUrlNameMappingEntry;
import org.opencms.db.urlname.CmsUrlNameMappingFilter;
import org.opencms.file.CmsDataAccessException;
import org.opencms.file.CmsFile;
import org.opencms.file.CmsFolder;
import org.opencms.file.CmsProject;
import org.opencms.file.CmsProperty;
import org.opencms.file.CmsPropertyDefinition;
import org.opencms.file.CmsResource;
import org.opencms.file.CmsResourceFilter;
import org.opencms.file.CmsVfsException;
import org.opencms.file.CmsVfsResourceAlreadyExistsException;
import org.opencms.file.CmsVfsResourceNotFoundException;
import org.opencms.file.I_CmsResource;
import org.opencms.file.history.I_CmsHistoryResource;
import org.opencms.file.types.CmsResourceTypeJsp;
import org.opencms.main.CmsEvent;
import org.opencms.main.CmsException;
import org.opencms.main.CmsLog;
import org.opencms.main.I_CmsEventListener;
import org.opencms.main.OpenCms;
import org.opencms.relations.CmsRelation;
import org.opencms.relations.CmsRelationFilter;
import org.opencms.relations.CmsRelationType;
import org.opencms.security.CmsOrganizationalUnit;
import org.opencms.security.CmsPermissionSet;
import org.opencms.util.CmsDataTypeUtil;
import org.opencms.util.CmsFileUtil;
import org.opencms.util.CmsPair;
import org.opencms.util.CmsStringUtil;
import org.opencms.util.CmsUUID;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceException;
import javax.persistence.Query;
import org.apache.commons.logging.Log;
/**
* JPA database server implementation of the vfs driver methods.<p>
*
* @since 8.0.0
*/
public class CmsVfsDriver implements I_CmsDriver, I_CmsVfsDriver {
/** Internal presentation of empty binary content. */
public static final byte[] EMPTY_BLOB = new byte[0];
/** Query key. */
private static final String C_DELETE_RELATIONS = "C_DELETE_RELATIONS";
/** Query key. */
private static final String C_DELETE_URLNAME_MAPPINGS = "C_DELETE_URLNAME_MAPPINGS";
/** Query key. */
private static final String C_HISTORY_CONTENTS_UPDATE = "C_HISTORY_CONTENTS_UPDATE";
/** Query key. */
private static final String C_MOVE_RELATIONS_SOURCE = "C_MOVE_RELATIONS_SOURCE";
/** Query key. */
private static final String C_MOVE_RELATIONS_TARGET = "C_MOVE_RELATIONS_TARGET";
/** Query key. */
private static final String C_OFFLINE_CONTENTS_UPDATE = "C_OFFLINE_CONTENTS_UPDATE";
/** Query key. */
private static final String C_OFFLINE_FILE_CONTENT_DELETE = "C_OFFLINE_FILE_CONTENT_DELETE";
/** Query key. */
private static final String C_ONLINE_CONTENTS_DELETE = "C_ONLINE_CONTENTS_DELETE";
/** Query key. */
private static final String C_ONLINE_CONTENTS_HISTORY = "C_ONLINE_CONTENTS_HISTORY";
/** Query key. */
private static final String C_ONLINE_FILES_CONTENT = "C_ONLINE_FILES_CONTENT";
/** Query key. */
private static final String C_PROPERTIES_DELETE = "C_PROPERTIES_DELETE";
/** Query key. */
private static final String C_PROPERTIES_DELETE_ALL_STRUCTURE_AND_RESOURCE_VALUES = "C_PROPERTIES_DELETE_ALL_STRUCTURE_AND_RESOURCE_VALUES";
/** Query key. */
private static final String C_PROPERTIES_DELETE_ALL_VALUES_FOR_MAPPING_TYPE = "C_PROPERTIES_DELETE_ALL_VALUES_FOR_MAPPING_TYPE";
/** Query key. */
private static final String C_PROPERTIES_READ = "C_PROPERTIES_READ";
/** Query key. */
private static final String C_PROPERTIES_READALL = "C_PROPERTIES_READALL";
/** Query key. */
private static final String C_PROPERTIES_READALL_COUNT = "C_PROPERTIES_READALL_COUNT";
/** Query key. */
private static final String C_PROPERTIES_UPDATE = "C_PROPERTIES_UPDATE";
/** Query key. */
private static final String C_PROPERTYDEF_DELETE = "C_PROPERTYDEF_DELETE";
/** Query key. */
private static final String C_PROPERTYDEF_READ = "C_PROPERTYDEF_READ";
/** Query key. */
private static final String C_PROPERTYDEF_READALL = "C_PROPERTYDEF_READALL";
/** Query key. */
private static final String C_READ_RELATIONS = "C_READ_RELATIONS";
/** Query key. */
private static final String C_READ_RESOURCE_OUS = "C_READ_RESOURCE_OUS";
/** Query key. */
private static final String C_READ_RESOURCE_STATE = "C_READ_RESOURCE_STATE";
/** Query key. */
private static final String C_READ_STRUCTURE_STATE = "C_READ_STRUCTURE_STATE";
/** Query key. */
private static final String C_READ_URLNAME_MAPPINGS = "C_READ_URLNAME_MAPPINGS";
/** Query key. */
private static final String C_RELATION_FILTER_SOURCE_ID = "C_RELATION_FILTER_SOURCE_ID";
/** Query key. */
private static final String C_RELATION_FILTER_SOURCE_PATH = "C_RELATION_FILTER_SOURCE_PATH";
/** Query key. */
private static final String C_RELATION_FILTER_TARGET_ID = "C_RELATION_FILTER_TARGET_ID";
/** Query key. */
private static final String C_RELATION_FILTER_TARGET_PATH = "C_RELATION_FILTER_TARGET_PATH";
/** Query key. */
private static final String C_RELATION_FILTER_TYPE = "C_RELATION_FILTER_TYPE";
/** Query key. */
private static final String C_RELATIONS_REPAIR_BROKEN = "C_RELATIONS_REPAIR_BROKEN";
/** Query key. */
private static final String C_RELATIONS_UPDATE_BROKEN = "C_RELATIONS_UPDATE_BROKEN";
/** Query key. */
private static final String C_RESOURCE_REPLACE = "C_RESOURCE_REPLACE";
/** Query key. */
private static final String C_RESOURCES_COUNT_SIBLINGS = "C_RESOURCES_COUNT_SIBLINGS";
/** Query key. */
private static final String C_RESOURCES_DELETE_BY_RESOURCEID = "C_RESOURCES_DELETE_BY_RESOURCEID";
/** Query key. */
private static final String C_RESOURCES_GET_RESOURCE_IN_PROJECT_IGNORE_STATE = "C_RESOURCES_GET_RESOURCE_IN_PROJECT_IGNORE_STATE";
/** Query key. */
private static final String C_RESOURCES_GET_RESOURCE_IN_PROJECT_WITH_STATE = "C_RESOURCES_GET_RESOURCE_IN_PROJECT_WITH_STATE";
/** Query key. */
private static final String C_RESOURCES_GET_RESOURCE_IN_PROJECT_WITHOUT_STATE = "C_RESOURCES_GET_RESOURCE_IN_PROJECT_WITHOUT_STATE";
/** Query key. */
private static final String C_RESOURCES_GET_RESOURCE_WITH_PROPERTYDEF = "C_RESOURCES_GET_RESOURCE_WITH_PROPERTYDEF";
/** Query key. */
private static final String C_RESOURCES_GET_RESOURCE_WITH_PROPERTYDEF_VALUE = "C_RESOURCES_GET_RESOURCE_WITH_PROPERTYDEF_VALUE";
/** Query key. */
private static final String C_RESOURCES_GET_SUBRESOURCES = "C_RESOURCES_GET_SUBRESOURCES";
/** Query key. */
private static final String C_RESOURCES_GET_SUBRESOURCES_GET_FILES = "C_RESOURCES_GET_SUBRESOURCES_GET_FILES";
/** Query key. */
private static final String C_RESOURCES_GET_SUBRESOURCES_GET_FOLDERS = "C_RESOURCES_GET_SUBRESOURCES_GET_FOLDERS";
/** Query key. */
private static final String C_RESOURCES_MOVE = "C_RESOURCES_MOVE";
/** Query key. */
private static final String C_RESOURCES_ORDER_BY_PATH = "C_RESOURCES_ORDER_BY_PATH";
/** Query key. */
private static final String C_RESOURCES_READ = "C_RESOURCES_READ";
/** Query key. */
private static final String C_RESOURCES_READ_PARENT_BY_ID = "C_RESOURCES_READ_PARENT_BY_ID";
/** Query key. */
private static final String C_RESOURCES_READ_PARENT_STRUCTURE_ID = "C_RESOURCES_READ_PARENT_STRUCTURE_ID";
/** Query key. */
private static final String C_RESOURCES_READ_RESOURCE_STATE = "C_RESOURCES_READ_RESOURCE_STATE";
/** Query key. */
private static final String C_RESOURCES_READ_TREE = "C_RESOURCES_READ_TREE";
/** Query key. */
private static final String C_RESOURCES_READ_VERSION_RES = "C_RESOURCES_READ_VERSION_RES";
/** Query key. */
private static final String C_RESOURCES_READ_VERSION_STR = "C_RESOURCES_READ_VERSION_STR";
/** Query key. */
private static final String C_RESOURCES_READ_WITH_ACE_1 = "C_RESOURCES_READ_WITH_ACE_1";
/** Query key. */
private static final String C_RESOURCES_READBYID = "C_RESOURCES_READBYID";
/** Query key. */
private static final String C_RESOURCES_SELECT_BY_DATE_LASTMODIFIED_AFTER = "C_RESOURCES_SELECT_BY_DATE_LASTMODIFIED_AFTER";
/** Query key. */
private static final String C_RESOURCES_SELECT_BY_DATE_LASTMODIFIED_BEFORE = "C_RESOURCES_SELECT_BY_DATE_LASTMODIFIED_BEFORE";
/** 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_RESOURCES_SELECT_BY_PROJECT_LASTMODIFIED = "C_RESOURCES_SELECT_BY_PROJECT_LASTMODIFIED";
/** Query key. */
private static final String C_RESOURCES_SELECT_BY_RESOURCE_STATE = "C_RESOURCES_SELECT_BY_RESOURCE_STATE";
/** Query key. */
private static final String C_RESOURCES_SELECT_BY_RESOURCE_TYPE = "C_RESOURCES_SELECT_BY_RESOURCE_TYPE";
/** Query key. */
private static final String C_RESOURCES_SELECT_ONLY_FILES = "C_RESOURCES_SELECT_ONLY_FILES";
/** Query key. */
private static final String C_RESOURCES_SELECT_ONLY_FOLDERS = "C_RESOURCES_SELECT_ONLY_FOLDERS";
/** Query key. */
private static final String C_RESOURCES_SELECT_STRUCTURE_ID = "C_RESOURCES_SELECT_STRUCTURE_ID";
/** Query key. */
private static final String C_RESOURCES_TRANSFER_RESOURCE = "C_RESOURCES_TRANSFER_RESOURCE";
/** Query key. */
private static final String C_RESOURCES_UPDATE_FLAGS = "C_RESOURCES_UPDATE_FLAGS";
/** Query key. */
private static final String C_RESOURCES_UPDATE_PROJECT_LASTMODIFIED = "C_RESOURCES_UPDATE_PROJECT_LASTMODIFIED";
/** Query key. */
private static final String C_RESOURCES_UPDATE_RELEASE_EXPIRED = "C_RESOURCES_UPDATE_RELEASE_EXPIRED";
/** Query key. */
private static final String C_RESOURCES_UPDATE_RESOURCE_PROJECT = "C_RESOURCES_UPDATE_RESOURCE_PROJECT";
/** Query key. */
private static final String C_RESOURCES_UPDATE_RESOURCE_STATE = "C_RESOURCES_UPDATE_RESOURCE_STATE";
/** Query key. */
private static final String C_RESOURCES_UPDATE_RESOURCE_STATELASTMODIFIED = "C_RESOURCES_UPDATE_RESOURCE_STATELASTMODIFIED";
/** Query key. */
private static final String C_RESOURCES_UPDATE_RESOURCE_VERSION = "C_RESOURCES_UPDATE_RESOURCE_VERSION";
/** Query key. */
private static final String C_RESOURCES_UPDATE_RESOURCES = "C_RESOURCES_UPDATE_RESOURCES";
/** Query key. */
private static final String C_RESOURCES_UPDATE_RESOURCES_WITHOUT_STATE = "C_RESOURCES_UPDATE_RESOURCES_WITHOUT_STATE";
/** Query key. */
private static final String C_RESOURCES_UPDATE_SIBLING_COUNT = "C_RESOURCES_UPDATE_SIBLING_COUNT";
/** Query key. */
private static final String C_RESOURCES_UPDATE_STRUCTURE = "C_RESOURCES_UPDATE_STRUCTURE";
/** Query key. */
private static final String C_RESOURCES_UPDATE_STRUCTURE_STATE = "C_RESOURCES_UPDATE_STRUCTURE_STATE";
/** Query key. */
private static final String C_RESOURCES_UPDATE_STRUCTURE_VERSION = "C_RESOURCES_UPDATE_STRUCTURE_VERSION";
/** Query key. */
private static final String C_SELECT_NONDELETED_VFS_SIBLINGS = "C_SELECT_NONDELETED_VFS_SIBLINGS";
/** Query key. */
private static final String C_SELECT_RESOURCES_FOR_PRINCIPAL_ACE = "C_SELECT_RESOURCES_FOR_PRINCIPAL_ACE";
/** Query key. */
private static final String C_SELECT_RESOURCES_FOR_PRINCIPAL_ATTR1 = "C_SELECT_RESOURCES_FOR_PRINCIPAL_ATTR1";
/** Query key. */
private static final String C_SELECT_RESOURCES_FOR_PRINCIPAL_ATTR2 = "C_SELECT_RESOURCES_FOR_PRINCIPAL_ATTR2";
/** Query key. */
private static final String C_SELECT_VFS_SIBLINGS = "C_SELECT_VFS_SIBLINGS";
/** Query key. */
private static final String C_STRUCTURE_DELETE_BY_STRUCTUREID = "C_STRUCTURE_DELETE_BY_STRUCTUREID";
/** Query key. */
private static final String C_STRUCTURE_SELECT_BY_DATE_EXPIRED_AFTER = "C_STRUCTURE_SELECT_BY_DATE_EXPIRED_AFTER";
/** Query key. */
private static final String C_STRUCTURE_SELECT_BY_DATE_EXPIRED_BEFORE = "C_STRUCTURE_SELECT_BY_DATE_EXPIRED_BEFORE";
/** Query key. */
private static final String C_STRUCTURE_SELECT_BY_DATE_RELEASED_AFTER = "C_STRUCTURE_SELECT_BY_DATE_RELEASED_AFTER";
/** Query key. */
private static final String C_STRUCTURE_SELECT_BY_DATE_RELEASED_BEFORE = "C_STRUCTURE_SELECT_BY_DATE_RELEASED_BEFORE";
/** The log object for this class. */
private static final Log LOG = CmsLog.getLog(org.opencms.db.jpa.CmsVfsDriver.class);
/** The driver manager. */
protected CmsDriverManager m_driverManager;
/**
* This field is temporarily used to compute the versions during publishing.<p>
*
* @see #publishVersions(CmsDbContext, CmsResource, boolean)
*/
protected List<CmsUUID> m_resOp = new ArrayList<CmsUUID>();
/** The sql manager. */
protected CmsSqlManager m_sqlManager;
/**
* Escapes the database wildcards within the resource path.<p>
*
* This method is required to ensure chars in the resource path that have a special
* meaning in SQL (for example "_", which is the "any char" operator) are escaped.<p>
*
* It will escape the following chars:
* <ul>
* <li>"_" to "|_"</li>
* </ul>
*
* @param path the resource path
* @return the escaped resource path
*/
public static String escapeDbWildcard(String path) {
return CmsStringUtil.substitute(path, "_", "|_");
}
/**
* This method prepares the JPQL conditions for mapping entries for a given URL name mapping filter.<p>
*
* @param filter the filter from which the JPQL conditions should be generated
*
* @return a pair consisting of an JPQL string and a list of the query parameters for the JPQL
*/
public static CmsPair<String, List<I_CmsQueryParameter>> prepareUrlNameMappingConditions(
CmsUrlNameMappingFilter filter) {
List<String> sqlConditions = new ArrayList<String>();
List<I_CmsQueryParameter> parameters = new ArrayList<I_CmsQueryParameter>();
if (filter.getName() != null) {
sqlConditions.add("T_CmsDAO%(PROJECT)UrlNameMappings.m_name = ?");
parameters.add(new CmsQueryStringParameter(filter.getName()));
}
if (filter.getStructureId() != null) {
sqlConditions.add("T_CmsDAO%(PROJECT)UrlNameMappings.m_structureId = ?");
parameters.add(new CmsQueryStringParameter(filter.getStructureId().toString()));
}
if (filter.getNamePattern() != null) {
sqlConditions.add("T_CmsDAO%(PROJECT)UrlNameMappings.m_name LIKE ? ");
parameters.add(new CmsQueryStringParameter(filter.getNamePattern()));
}
if (filter.getState() != null) {
sqlConditions.add("T_CmsDAO%(PROJECT)UrlNameMappings.m_state = ?");
parameters.add(new CmsQueryIntParameter(filter.getState().intValue()));
}
if (filter.getRejectStructureId() != null) {
sqlConditions.add("T_CmsDAO%(PROJECT)UrlNameMappings.m_structureId <> ? ");
parameters.add(new CmsQueryStringParameter(filter.getRejectStructureId().toString()));
}
if (filter.getLocale() != null) {
sqlConditions.add("T_CmsDAO%(PROJECT)UrlNameMappings.m_locale = ? ");
parameters.add(new CmsQueryStringParameter(filter.getLocale()));
}
String conditionString = CmsStringUtil.listAsString(sqlConditions, " AND ");
return CmsPair.create(conditionString, parameters);
}
/**
* @see org.opencms.db.I_CmsVfsDriver#addUrlNameMappingEntry(org.opencms.db.CmsDbContext, boolean, org.opencms.db.urlname.CmsUrlNameMappingEntry)
*/
public void addUrlNameMappingEntry(CmsDbContext dbc, boolean online, CmsUrlNameMappingEntry entry) {
I_CmsDAOUrlNameMappings m = online ? new CmsDAOOnlineUrlNameMappings() : new CmsDAOOfflineUrlNameMappings();
m.setName(entry.getName());
m.setStructureId(entry.getStructureId().toString());
m.setState(entry.getState());
m.setDateChanged(entry.getDateChanged());
m.setLocale(entry.getLocale());
m_sqlManager.persist(dbc, m);
}
/**
* Counts the number of siblings of a resource.<p>
*
* @param dbc the current database context
* @param projectId the current project id
* @param resourceId the resource id to count the number of siblings from
*
* @return number of siblings
* @throws CmsDataAccessException if something goes wrong
*/
public int countSiblings(CmsDbContext dbc, CmsUUID projectId, CmsUUID resourceId) throws CmsDataAccessException {
int count = 0;
try {
Query q = m_sqlManager.createQuery(dbc, projectId, C_RESOURCES_COUNT_SIBLINGS);
q.setParameter(1, resourceId.toString());
try {
count = CmsDataTypeUtil.numberToInt((Number)q.getSingleResult());
} catch (NoResultException e) {
// do nothing
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
return count;
}
/**
* @see org.opencms.db.I_CmsVfsDriver#createContent(CmsDbContext, CmsUUID, CmsUUID, byte[])
*/
public void createContent(CmsDbContext dbc, CmsUUID projectId, CmsUUID resourceId, byte[] content)
throws CmsDataAccessException {
try {
CmsDAOOfflineContents oc = new CmsDAOOfflineContents();
oc.setResourceId(resourceId.toString());
oc.setFileContent(content);
m_sqlManager.persist(dbc, oc);
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
}
/**
* Creates a {@link CmsFile} instance from a jpa ResultSet.<p>
*
* @param o the jpa ResultSet
* @param projectId the project id
* @param hasFileContentInResultSet flag to include the file content
*
* @return the created file
*/
public CmsFile createFile(Object[] o, CmsUUID projectId, boolean hasFileContentInResultSet) {
I_CmsDAOResources r = (I_CmsDAOResources)o[0];
I_CmsDAOStructure s = (I_CmsDAOStructure)o[1];
String lockedInProjectParameter = (String)o[2];
byte[] content = null;
CmsUUID resProjectId = null;
CmsUUID structureId = new CmsUUID(s.getStructureId());
CmsUUID resourceId = new CmsUUID(r.getResourceId());
String resourcePath = s.getResourcePath();
int resourceType = r.getResourceType();
int resourceFlags = r.getResourceFlags();
int resourceState = r.getResourceState();
int structureState = s.getStructureState();
long dateCreated = r.getDateCreated();
long dateLastModified = r.getDateLastModified();
long dateReleased = s.getDateReleased();
long dateExpired = s.getDateExpired();
int resourceSize = r.getResourceSize();
CmsUUID userCreated = new CmsUUID(r.getUserCreated());
CmsUUID userLastModified = new CmsUUID(r.getUserLastModified());
CmsUUID lockedInProject = new CmsUUID(lockedInProjectParameter);
int siblingCount = r.getSiblingCount();
long dateContent = r.getDateContent();
int resourceVersion = r.getResourceVersion();
int structureVersion = s.getStructureVersion();
// in case of folder type ensure, that the root path has a trailing slash
if (CmsFolder.isFolderType(resourceType)) {
resourcePath = CmsFileUtil.addTrailingSeparator(resourcePath);
}
if (hasFileContentInResultSet) {
//content = m_sqlManager.getBytes(res, m_sqlManager.readQuery("C_RESOURCES_FILE_CONTENT"));
throw new RuntimeException(
"CCmsVfsDriver: public CmsFile createFile(Object[] o, CmsUUID projectId, boolean hasFileContentInResultSet) throws SQLException ");
}
resProjectId = lockedInProject;
int newState = (structureState > resourceState) ? structureState : resourceState;
return new CmsFile(
structureId,
resourceId,
resourcePath,
resourceType,
resourceFlags,
resProjectId,
CmsResourceState.valueOf(newState),
dateCreated,
userCreated,
dateLastModified,
userLastModified,
dateReleased,
dateExpired,
siblingCount,
resourceSize,
dateContent,
resourceVersion + structureVersion,
content);
}
/**
* @see org.opencms.db.I_CmsVfsDriver#createFile(java.sql.ResultSet, org.opencms.util.CmsUUID)
*/
public CmsFile createFile(ResultSet res, CmsUUID projectId) {
LOG.error("This method is not implemented!");
return null;
}
/**
* @see org.opencms.db.I_CmsVfsDriver#createFile(java.sql.ResultSet, org.opencms.util.CmsUUID, boolean)
*/
public CmsFile createFile(ResultSet res, CmsUUID projectId, boolean hasFileContentInResultSet) {
LOG.error("This method is not implemented!");
return null;
}
/**
* Creates a {@link CmsFolder} instance from a jpa ResultSet.<p>
*
* @param o the JDBC ResultSet
* @param projectId the ID of the current project
* @param hasProjectIdInResultSet true if the SQL select query includes the PROJECT_ID table attribute
*
* @return the created folder
*/
public CmsFolder createFolder(Object[] o, CmsUUID projectId, boolean hasProjectIdInResultSet) {
I_CmsDAOResources r = (I_CmsDAOResources)o[0];
I_CmsDAOStructure s = (I_CmsDAOStructure)o[1];
String lockedInProjectParameter = (String)o[2];
CmsUUID structureId = new CmsUUID(s.getStructureId());
CmsUUID resourceId = new CmsUUID(r.getResourceId());
String resourcePath = s.getResourcePath();
int resourceType = r.getResourceType();
int resourceFlags = r.getResourceFlags();
int resourceState = r.getResourceState();
int structureState = s.getStructureState();
long dateCreated = r.getDateCreated();
long dateLastModified = r.getDateLastModified();
long dateReleased = s.getDateReleased();
long dateExpired = s.getDateExpired();
CmsUUID userCreated = new CmsUUID(r.getUserCreated());
CmsUUID userLastModified = new CmsUUID(r.getUserLastModified());
CmsUUID resProjectId = new CmsUUID(lockedInProjectParameter);
int resourceVersion = r.getResourceVersion();
int structureVersion = s.getStructureVersion();
int resourceSize = r.getResourceSize();
// in case of folder type ensure, that the root path has a trailing slash
if (CmsFolder.isFolderSize(resourceSize)) {
resourcePath = CmsFileUtil.addTrailingSeparator(resourcePath);
}
int newState = (structureState > resourceState) ? structureState : resourceState;
return new CmsFolder(
structureId,
resourceId,
resourcePath,
resourceType,
resourceFlags,
resProjectId,
CmsResourceState.valueOf(newState),
dateCreated,
userCreated,
dateLastModified,
userLastModified,
dateReleased,
dateExpired,
resourceVersion + structureVersion);
}
/**
* @see org.opencms.db.I_CmsVfsDriver#createFolder(java.sql.ResultSet, org.opencms.util.CmsUUID, boolean)
*/
public CmsFolder createFolder(ResultSet res, CmsUUID projectId, boolean hasProjectIdInResultSet) {
LOG.error("This method is not implemented!");
return null;
}
/**
* @see org.opencms.db.I_CmsVfsDriver#createOnlineContent(org.opencms.db.CmsDbContext, org.opencms.util.CmsUUID, byte[], int, boolean, boolean)
*/
public void createOnlineContent(
CmsDbContext dbc,
CmsUUID resourceId,
byte[] contents,
int publishTag,
boolean keepOnline,
boolean needToUpdateContent) throws CmsDataAccessException {
try {
boolean dbcHasProjectId = (dbc.getProjectId() != null) && !dbc.getProjectId().isNullUUID();
if (needToUpdateContent || dbcHasProjectId) {
if (dbcHasProjectId || !OpenCms.getSystemInfo().isHistoryEnabled()) {
// remove the online content for this resource id
Query q = m_sqlManager.createQuery(dbc, "C_ONLINE_CONTENTS_DELETE");
q.setParameter(1, resourceId.toString());
q.executeUpdate();
} else {
// put the online content in the history, only if explicit requested
Query q = m_sqlManager.createQuery(dbc, "C_ONLINE_CONTENTS_HISTORY");
q.setParameter(1, resourceId.toString());
@SuppressWarnings("unchecked")
List<CmsDAOContents> res = q.getResultList();
for (CmsDAOContents c : res) {
c.setOnlineFlag(0);
}
}
// create new online content
CmsDAOContents c = new CmsDAOContents();
c.setResourceId(resourceId.toString());
c.setFileContent(contents);
c.setPublishTagFrom(publishTag);
c.setPublishTagTo(publishTag);
c.setOnlineFlag(keepOnline ? 1 : 0);
m_sqlManager.persist(dbc, c);
} else {
// update old content entry
Query q = m_sqlManager.createQuery(dbc, C_HISTORY_CONTENTS_UPDATE);
q.setParameter(1, resourceId.toString());
@SuppressWarnings("unchecked")
List<CmsDAOContents> res = q.getResultList();
for (CmsDAOContents c : res) {
c.setPublishTagTo(publishTag);
}
if (!keepOnline) {
// put the online content in the history
q = m_sqlManager.createQuery(dbc, C_ONLINE_CONTENTS_HISTORY);
q.setParameter(1, resourceId.toString());
@SuppressWarnings("unchecked")
List<CmsDAOContents> res1 = q.getResultList();
for (CmsDAOContents c : res1) {
c.setOnlineFlag(0);
}
}
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
}
/**
* @see org.opencms.db.I_CmsVfsDriver#createPropertyDefinition(org.opencms.db.CmsDbContext, org.opencms.util.CmsUUID, java.lang.String, org.opencms.file.CmsPropertyDefinition.CmsPropertyType)
*/
public CmsPropertyDefinition createPropertyDefinition(
CmsDbContext dbc,
CmsUUID projectId,
String name,
CmsPropertyDefinition.CmsPropertyType type) throws CmsDataAccessException {
try {
I_CmsDAOPropertyDef pd = CmsProject.isOnlineProject(projectId)
? new CmsDAOOnlinePropertyDef()
: new CmsDAOOfflinePropertyDef();
pd.setPropertyDefId(new CmsUUID().toString());
pd.setPropertyDefName(name);
pd.setPropertyDefType(type.getMode());
m_sqlManager.persist(dbc, pd);
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
return readPropertyDefinition(dbc, name, projectId);
}
/**
* @see org.opencms.db.I_CmsVfsDriver#createRelation(org.opencms.db.CmsDbContext, CmsUUID, org.opencms.relations.CmsRelation)
*/
public void createRelation(CmsDbContext dbc, CmsUUID projectId, CmsRelation relation) throws CmsDataAccessException {
try {
I_CmsDAOResourceRelations rr = CmsProject.isOnlineProject(projectId)
? new CmsDAOOnlineResourceRelations()
: new CmsDAOOfflineResourceRelations();
rr.setRelationSourceId(relation.getSourceId().toString());
rr.setRelationSourcePath(relation.getSourcePath());
rr.setRelationTargetId(relation.getTargetId().toString());
rr.setRelationTargetPath(relation.getTargetPath());
rr.setRelationType(relation.getType().getId());
m_sqlManager.persist(dbc, rr);
if (LOG.isDebugEnabled()) {
LOG.debug(Messages.get().getBundle().key(
Messages.LOG_CREATE_RELATION_2,
String.valueOf(projectId),
relation));
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
}
/**
* @see org.opencms.db.I_CmsVfsDriver#createResource(org.opencms.db.CmsDbContext, CmsUUID, org.opencms.file.CmsResource, byte[])
*/
public CmsResource createResource(CmsDbContext dbc, CmsUUID projectId, CmsResource resource, byte[] content)
throws CmsDataAccessException {
CmsUUID newStructureId = null;
// check the resource path
String resourcePath = CmsFileUtil.removeTrailingSeparator(resource.getRootPath());
if (resourcePath.length() > CmsDriverManager.MAX_VFS_RESOURCE_PATH_LENGTH) {
throw new CmsDataAccessException(Messages.get().container(
Messages.ERR_RESOURCENAME_TOO_LONG_2,
resourcePath,
new Integer(CmsDriverManager.MAX_VFS_RESOURCE_PATH_LENGTH)));
}
// check if the parent folder of the resource exists and if is not deleted
if (!resource.getRootPath().equals("/")) {
String parentFolderName = CmsResource.getParentFolder(resource.getRootPath());
CmsFolder parentFolder = m_driverManager.getVfsDriver(dbc).readFolder(dbc, projectId, parentFolderName);
if (parentFolder.getState().isDeleted()) {
throw new CmsDbEntryNotFoundException(Messages.get().container(
Messages.ERR_PARENT_FOLDER_DELETED_1,
resource.getRootPath()));
}
}
// validate the resource length
internalValidateResourceLength(resource);
// set the resource state and modification dates
CmsResourceState newState;
long dateModified;
long dateCreated;
long dateContent = System.currentTimeMillis();
if (projectId.equals(CmsProject.ONLINE_PROJECT_ID)) {
newState = CmsResource.STATE_UNCHANGED;
dateCreated = resource.getDateCreated();
dateModified = resource.getDateLastModified();
} else {
newState = CmsResource.STATE_NEW;
if (resource.isTouched()) {
dateCreated = resource.getDateCreated();
dateModified = resource.getDateLastModified();
} else {
dateCreated = System.currentTimeMillis();
dateModified = dateCreated;
}
}
// check if the resource already exists
newStructureId = resource.getStructureId();
try {
CmsResource existingResource = m_driverManager.getVfsDriver().readResource(
dbc,
dbc.getProjectId().isNullUUID() ? projectId : dbc.getProjectId(),
resourcePath,
true);
if (existingResource.getState().isDeleted()) {
// if an existing resource is deleted, it will be finally removed now.
// but we have to reuse its id in order to avoid orphans in the online project
newStructureId = existingResource.getStructureId();
newState = CmsResource.STATE_CHANGED;
// remove the existing file and it's properties
List<CmsResource> modifiedResources = m_driverManager.getVfsDriver(dbc).readSiblings(
dbc,
projectId,
existingResource,
false);
int propertyDeleteOption = (existingResource.getSiblingCount() > 1)
? CmsProperty.DELETE_OPTION_DELETE_STRUCTURE_VALUES
: CmsProperty.DELETE_OPTION_DELETE_STRUCTURE_AND_RESOURCE_VALUES;
deletePropertyObjects(dbc, projectId, existingResource, propertyDeleteOption);
removeFile(dbc, projectId, existingResource);
OpenCms.fireCmsEvent(new CmsEvent(
I_CmsEventListener.EVENT_RESOURCES_MODIFIED,
Collections.<String, Object> singletonMap(I_CmsEventListener.KEY_RESOURCES, modifiedResources)));
OpenCms.fireCmsEvent(new CmsEvent(
I_CmsEventListener.EVENT_RESOURCE_AND_PROPERTIES_MODIFIED,
Collections.<String, Object> singletonMap(I_CmsEventListener.KEY_RESOURCE, existingResource)));
} else {
// we have a collision: there exists already a resource with the same path/name which cannot be removed
throw new CmsVfsResourceAlreadyExistsException(Messages.get().container(
Messages.ERR_RESOURCE_WITH_NAME_ALREADY_EXISTS_1,
dbc.removeSiteRoot(resource.getRootPath())));
}
} catch (CmsVfsResourceNotFoundException e) {
// that's what we want in the best case- anything else should be thrown
}
try {
// read the parent id
String parentId = internalReadParentId(dbc, projectId, resourcePath);
// use consistent version numbers if the file is being restored
int lastVersion = m_driverManager.getHistoryDriver(dbc).readLastVersion(dbc, newStructureId);
int newStrVersion = 0;
int newResVersion = 0;
if (lastVersion > 0) {
I_CmsHistoryResource histRes = m_driverManager.getHistoryDriver(dbc).readResource(
dbc,
newStructureId,
lastVersion);
newStrVersion = histRes.getStructureVersion();
newResVersion = histRes.getResourceVersion();
}
// write the structure
I_CmsDAOStructure s = CmsProject.isOnlineProject(projectId)
? new CmsDAOOnlineStructure()
: new CmsDAOOfflineStructure();
s.setStructureId(newStructureId.toString());
s.setResourceId(resource.getResourceId().toString());
s.setResourcePath(resourcePath);
s.setStructureState(newState.getState());
s.setDateReleased(resource.getDateReleased());
s.setDateExpired(resource.getDateExpired());
s.setParentId(parentId);
s.setStructureVersion(newStrVersion);
m_sqlManager.persist(dbc, s);
if (!validateResourceIdExists(dbc, projectId, resource.getResourceId())) {
// create the resource record
I_CmsDAOResources r = CmsProject.isOnlineProject(projectId)
? new CmsDAOOnlineResources()
: new CmsDAOOfflineResources();
r.setResourceId(resource.getResourceId().toString());
r.setResourceType(resource.getTypeId());
r.setResourceFlags(resource.getFlags());
r.setDateCreated(dateCreated);
r.setUserCreated(resource.getUserCreated().toString());
r.setDateLastModified(dateModified);
r.setUserLastModified(resource.getUserLastModified().toString());
r.setResourceState(newState.getState());
r.setResourceSize(resource.getLength());
r.setDateContent(dateContent);
r.setProjectLastModified(projectId.toString());
r.setSiblingCount(1);
r.setResourceVersion(newResVersion);
m_sqlManager.persist(dbc, r);
if (resource.isFile() && (content != null)) {
// create the file content
createContent(dbc, projectId, resource.getResourceId(), content);
}
} else {
if ((content != null) || !resource.getState().isKeep()) {
CmsUUID projLastMod = projectId;
CmsResourceState state = CmsResource.STATE_CHANGED;
if (projectId.equals(CmsProject.ONLINE_PROJECT_ID)) {
// in case a sibling is being published
projLastMod = resource.getProjectLastModified();
state = CmsResource.STATE_UNCHANGED;
}
// update the resource record only if state has changed or new content is provided
Query q = m_sqlManager.createQuery(dbc, projectId, C_RESOURCES_UPDATE_RESOURCES);
q.setParameter(1, resource.getResourceId().toString());
@SuppressWarnings("unchecked")
List<I_CmsDAOResources> res = q.getResultList();
for (I_CmsDAOResources r : res) {
r.setResourceType(resource.getTypeId());
r.setResourceFlags(resource.getFlags());
r.setDateLastModified(dateModified);
r.setUserLastModified(resource.getUserLastModified().toString());
r.setResourceState(state.getState());
r.setResourceSize(resource.getLength());
r.setDateContent(resource.getDateContent());
r.setProjectLastModified(projLastMod.toString());
r.setSiblingCount(countSiblings(dbc, projectId, resource.getResourceId()));
}
}
if (resource.isFile()) {
if (content != null) {
// update the file content
writeContent(dbc, resource.getResourceId(), content);
} else if (resource.getState().isKeep()) {
// special case sibling creation - update the link Count
Query q = m_sqlManager.createQuery(dbc, projectId, C_RESOURCES_UPDATE_SIBLING_COUNT);
q.setParameter(1, resource.getResourceId().toString());
@SuppressWarnings("unchecked")
List<I_CmsDAOResources> res = q.getResultList();
for (I_CmsDAOResources r : res) {
r.setSiblingCount(countSiblings(dbc, projectId, resource.getResourceId()));
}
// update the resource flags
q = m_sqlManager.createQuery(dbc, projectId, C_RESOURCES_UPDATE_FLAGS);
q.setParameter(1, resource.getResourceId().toString());
@SuppressWarnings("unchecked")
List<I_CmsDAOResources> resf = q.getResultList();
for (I_CmsDAOResources r : resf) {
r.setResourceFlags(resource.getFlags());
}
}
}
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
repairBrokenRelations(dbc, projectId, resource.getStructureId(), resource.getRootPath());
return readResource(dbc, projectId, newStructureId, false);
}
/**
* Creates a CmsResource instance from a jpa ResultSet.<p>
*
* @param o the jpa ResultSet
* @param projectId the ID of the current project to adjust the modification date in case the resource is a VFS link
*
* @return the created resource
*/
public CmsResource createResource(Object[] o, CmsUUID projectId) {
I_CmsDAOResources r = (I_CmsDAOResources)o[0];
I_CmsDAOStructure s = (I_CmsDAOStructure)o[1];
CmsUUID structureId = new CmsUUID(s.getStructureId());
CmsUUID resourceId = new CmsUUID(r.getResourceId());
String resourcePath = s.getResourcePath();
int resourceType = r.getResourceType();
int resourceFlags = r.getResourceFlags();
CmsUUID resourceProjectLastModified = new CmsUUID(r.getProjectLastModified());
int resourceState = r.getResourceState();
int structureState = s.getStructureState();
long dateCreated = r.getDateCreated();
long dateLastModified = r.getDateLastModified();
long dateReleased = s.getDateReleased();
long dateExpired = s.getDateExpired();
int resourceSize = r.getResourceSize();
boolean isFolder = CmsFolder.isFolderSize(resourceSize);
if (isFolder) {
// in case of folder type ensure, that the root path has a trailing slash
resourcePath = CmsFileUtil.addTrailingSeparator(resourcePath);
}
long dateContent = isFolder ? -1 : r.getDateContent();
CmsUUID userCreated = new CmsUUID(r.getUserCreated());
CmsUUID userLastModified = new CmsUUID(r.getUserLastModified());
int siblingCount = r.getSiblingCount();
int resourceVersion = r.getResourceVersion();
int structureVersion = s.getStructureVersion();
int newState = (structureState > resourceState) ? structureState : resourceState;
// if there is a change increase the version number
int newVersion = resourceVersion + structureVersion + (newState > 0 ? 1 : 0);
CmsResource newResource = new CmsResource(
structureId,
resourceId,
resourcePath,
resourceType,
isFolder,
resourceFlags,
resourceProjectLastModified,
CmsResourceState.valueOf(newState),
dateCreated,
userCreated,
dateLastModified,
userLastModified,
dateReleased,
dateExpired,
siblingCount,
resourceSize,
dateContent,
newVersion);
return newResource;
}
/**
* @see org.opencms.db.I_CmsVfsDriver#createResource(java.sql.ResultSet, org.opencms.util.CmsUUID)
*/
public CmsResource createResource(ResultSet res, CmsUUID projectId) {
LOG.error("This method is not implemented!");
return null;
}
/**
* @see org.opencms.db.I_CmsVfsDriver#createSibling(org.opencms.db.CmsDbContext, org.opencms.file.CmsProject, org.opencms.file.CmsResource)
*/
public void createSibling(CmsDbContext dbc, CmsProject project, CmsResource resource) throws CmsDataAccessException {
if (!project.getUuid().equals(CmsProject.ONLINE_PROJECT_ID)) {
// this method is only intended to be used during publishing
return;
}
// check if the resource already exists
CmsResource existingSibling = null;
CmsUUID newStructureId = resource.getStructureId();
try {
existingSibling = readResource(dbc, project.getUuid(), resource.getRootPath(), true);
if (existingSibling.getState().isDeleted()) {
// if an existing resource is deleted, it will be finally removed now.
// but we have to reuse its id in order to avoid orphans in the online project.
newStructureId = existingSibling.getStructureId();
// remove the existing file and it's properties
List<CmsResource> modifiedResources = readSiblings(dbc, project.getUuid(), existingSibling, false);
int propertyDeleteOption = (existingSibling.getSiblingCount() > 1)
? CmsProperty.DELETE_OPTION_DELETE_STRUCTURE_VALUES
: CmsProperty.DELETE_OPTION_DELETE_STRUCTURE_AND_RESOURCE_VALUES;
deletePropertyObjects(dbc, project.getUuid(), existingSibling, propertyDeleteOption);
removeFile(dbc, project.getUuid(), existingSibling);
OpenCms.fireCmsEvent(new CmsEvent(
I_CmsEventListener.EVENT_RESOURCES_MODIFIED,
Collections.<String, Object> singletonMap(I_CmsEventListener.KEY_RESOURCES, modifiedResources)));
OpenCms.fireCmsEvent(new CmsEvent(
I_CmsEventListener.EVENT_RESOURCE_AND_PROPERTIES_MODIFIED,
Collections.<String, Object> singletonMap(I_CmsEventListener.KEY_RESOURCE, existingSibling)));
} else {
// we have a collision: there exists already a resource with the same path/name which could not be removed
throw new CmsVfsResourceAlreadyExistsException(Messages.get().container(
Messages.ERR_RESOURCE_WITH_NAME_ALREADY_EXISTS_1,
dbc.removeSiteRoot(resource.getRootPath())));
}
} catch (CmsVfsResourceNotFoundException e) {
// that's what we want in the best case- anything else should be thrown
}
// check if a resource with the specified ID already exists
if (!validateResourceIdExists(dbc, project.getUuid(), resource.getResourceId())) {
throw new CmsVfsResourceNotFoundException(Messages.get().container(
Messages.ERR_CREATE_SIBLING_FILE_NOT_FOUND_1,
dbc.removeSiteRoot(resource.getRootPath())));
}
// write a new structure referring to the resource
try {
// use consistent version numbers if the file is being restored
int lastVersion = m_driverManager.getHistoryDriver(dbc).readLastVersion(dbc, newStructureId);
int newStrVersion = 0;
if (lastVersion > 0) {
I_CmsHistoryResource histRes = m_driverManager.getHistoryDriver(dbc).readResource(
dbc,
newStructureId,
lastVersion);
newStrVersion = histRes.getStructureVersion();
}
// read the parent id
String parentId = internalReadParentId(dbc, project.getUuid(), resource.getRootPath());
// write the structure
I_CmsDAOStructure s = CmsProject.isOnlineProject(project.getUuid())
? new CmsDAOOnlineStructure()
: new CmsDAOOfflineStructure();
s.setStructureId(newStructureId.toString());
s.setResourceId(resource.getResourceId().toString());
s.setResourcePath(resource.getRootPath());
s.setStructureState(CmsResource.STATE_UNCHANGED.getState());
s.setDateReleased(resource.getDateReleased());
s.setDateExpired(resource.getDateExpired());
s.setParentId(parentId);
s.setStructureVersion(newStrVersion);
m_sqlManager.persist(dbc, s);
// update the link Count
Query q = m_sqlManager.createQuery(dbc, project, C_RESOURCES_UPDATE_SIBLING_COUNT);
q.setParameter(1, resource.getResourceId().toString());
@SuppressWarnings("unchecked")
List<I_CmsDAOResources> res = q.getResultList();
for (I_CmsDAOResources r : res) {
r.setSiblingCount(countSiblings(dbc, project.getUuid(), resource.getResourceId()));
}
// update the project last modified and flags
q = m_sqlManager.createQuery(dbc, project, C_RESOURCES_UPDATE_RESOURCE_PROJECT);
q.setParameter(1, resource.getResourceId().toString());
@SuppressWarnings("unchecked")
List<I_CmsDAOResources> resr = q.getResultList();
for (I_CmsDAOResources r : resr) {
r.setResourceFlags(resource.getFlags());
r.setProjectLastModified(resource.getProjectLastModified().toString());
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
repairBrokenRelations(dbc, project.getUuid(), resource.getStructureId(), resource.getRootPath());
}
/**
* @see org.opencms.db.I_CmsVfsDriver#deletePropertyDefinition(org.opencms.db.CmsDbContext, org.opencms.file.CmsPropertyDefinition)
*/
public void deletePropertyDefinition(CmsDbContext dbc, CmsPropertyDefinition metadef) throws CmsDataAccessException {
try {
if ((internalCountProperties(dbc, metadef, CmsProject.ONLINE_PROJECT_ID) != 0)
|| (internalCountProperties(dbc, metadef, CmsUUID.getOpenCmsUUID()) != 0)) { // HACK: to get an offline project
throw new CmsDataAccessException(Messages.get().container(
Messages.ERR_DELETE_USED_PROPERTY_1,
metadef.getName()));
}
Query q;
for (int i = 0; i < 2; i++) {
if (i == 0) {
// delete the offline property definition
q = m_sqlManager.createQuery(dbc, CmsUUID.getOpenCmsUUID(), C_PROPERTYDEF_DELETE); // HACK: to get an offline project
} else {
// delete the online property definition
q = m_sqlManager.createQuery(dbc, CmsProject.ONLINE_PROJECT_ID, C_PROPERTYDEF_DELETE);
}
q.setParameter(1, metadef.getId().toString());
@SuppressWarnings("unchecked")
List<I_CmsDAOPropertyDef> res = q.getResultList();
for (I_CmsDAOPropertyDef pd : res) {
m_sqlManager.remove(dbc, pd);
}
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
}
/**
* @see org.opencms.db.I_CmsVfsDriver#deletePropertyObjects(org.opencms.db.CmsDbContext, CmsUUID, org.opencms.file.CmsResource, int)
*/
public void deletePropertyObjects(CmsDbContext dbc, CmsUUID projectId, CmsResource resource, int deleteOption)
throws CmsDataAccessException {
try {
Query q;
if (deleteOption == CmsProperty.DELETE_OPTION_DELETE_STRUCTURE_AND_RESOURCE_VALUES) {
// delete both the structure and resource property values mapped to the specified resource
q = m_sqlManager.createQuery(dbc, projectId, C_PROPERTIES_DELETE_ALL_STRUCTURE_AND_RESOURCE_VALUES);
q.setParameter(1, resource.getResourceId().toString());
q.setParameter(2, Integer.valueOf(CmsProperty.RESOURCE_RECORD_MAPPING));
q.setParameter(3, String.valueOf(resource.getStructureId()));
q.setParameter(4, Integer.valueOf(CmsProperty.STRUCTURE_RECORD_MAPPING));
} else if (deleteOption == CmsProperty.DELETE_OPTION_DELETE_STRUCTURE_VALUES) {
// delete the structure values mapped to the specified resource
q = m_sqlManager.createQuery(dbc, projectId, C_PROPERTIES_DELETE_ALL_VALUES_FOR_MAPPING_TYPE);
q.setParameter(1, resource.getStructureId().toString());
q.setParameter(2, Integer.valueOf(CmsProperty.STRUCTURE_RECORD_MAPPING));
} else if (deleteOption == CmsProperty.DELETE_OPTION_DELETE_RESOURCE_VALUES) {
// delete the resource property values mapped to the specified resource
q = m_sqlManager.createQuery(dbc, projectId, C_PROPERTIES_DELETE_ALL_VALUES_FOR_MAPPING_TYPE);
q.setParameter(1, resource.getResourceId().toString());
q.setParameter(2, Integer.valueOf(CmsProperty.RESOURCE_RECORD_MAPPING));
} else {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_INVALID_DELETE_OPTION_1));
}
@SuppressWarnings("unchecked")
List<I_CmsDAOProperties> res = q.getResultList();
for (I_CmsDAOProperties p : res) {
m_sqlManager.remove(dbc, p);
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
}
/**
* @see org.opencms.db.I_CmsVfsDriver#deleteRelations(org.opencms.db.CmsDbContext, CmsUUID, CmsResource, org.opencms.relations.CmsRelationFilter)
*/
public void deleteRelations(CmsDbContext dbc, CmsUUID projectId, CmsResource resource, CmsRelationFilter filter)
throws CmsDataAccessException {
try {
if (filter.isSource()) {
List params = new ArrayList(7);
StringBuffer queryBuf = new StringBuffer(256);
queryBuf.append(m_sqlManager.readQuery(projectId, C_DELETE_RELATIONS));
queryBuf.append(prepareRelationConditions(projectId, filter, resource, params, true));
Query q = m_sqlManager.createQueryFromJPQL(dbc, queryBuf.toString());
for (int i = 0; i < params.size(); i++) {
q.setParameter(i + 1, params.get(i));
}
@SuppressWarnings("unchecked")
List<I_CmsDAOResourceRelations> res = q.getResultList();
for (I_CmsDAOResourceRelations rr : res) {
m_sqlManager.remove(dbc, rr);
}
}
if (filter.isTarget()) {
List params = new ArrayList(7);
StringBuffer queryBuf = new StringBuffer(256);
queryBuf.append(m_sqlManager.readQuery(projectId, C_DELETE_RELATIONS));
queryBuf.append(prepareRelationConditions(projectId, filter, resource, params, false));
Query q = m_sqlManager.createQueryFromJPQL(dbc, queryBuf.toString());
for (int i = 0; i < params.size(); i++) {
q.setParameter(i + 1, params.get(i));
}
@SuppressWarnings("unchecked")
List<I_CmsDAOResourceRelations> res = q.getResultList();
for (I_CmsDAOResourceRelations rr : res) {
m_sqlManager.remove(dbc, rr);
}
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
// update broken remaining relations
updateBrokenRelations(dbc, projectId, resource.getRootPath());
}
/**
* @see org.opencms.db.I_CmsVfsDriver#deleteUrlNameMappingEntries(org.opencms.db.CmsDbContext, boolean, org.opencms.db.urlname.CmsUrlNameMappingFilter)
*/
public void deleteUrlNameMappingEntries(CmsDbContext dbc, boolean online, CmsUrlNameMappingFilter filter)
throws CmsDataAccessException {
try {
String query = m_sqlManager.readQuery(C_DELETE_URLNAME_MAPPINGS);
query = replaceProject(query, online);
Query q = getQueryForFilter(dbc, query, filter, online);
@SuppressWarnings("unchecked")
List<I_CmsDAOUrlNameMappings> res = q.getResultList();
for (I_CmsDAOUrlNameMappings m : res) {
m_sqlManager.remove(dbc, m);
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
}
/**
* @see org.opencms.db.I_CmsVfsDriver#destroy()
*/
public void destroy() throws Throwable {
m_sqlManager = null;
m_driverManager = null;
if (CmsLog.INIT.isInfoEnabled()) {
CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_SHUTDOWN_DRIVER_1, getClass().getName()));
}
}
/**
* Returns all organizational units for the given resource.<p>
*
* @param dbc the database context
* @param projectId the id of the project
* @param resource the resource
*
* @return a list of {@link org.opencms.security.CmsOrganizationalUnit} objects
*
* @throws CmsDataAccessException
*/
public List<CmsOrganizationalUnit> getResourceOus(CmsDbContext dbc, CmsUUID projectId, CmsResource resource)
throws CmsDataAccessException {
List<CmsOrganizationalUnit> ous = new ArrayList<CmsOrganizationalUnit>();
String resName = resource.getRootPath();
if (resource.isFolder() && !resName.endsWith("/")) {
resName += "/";
}
try {
Query q = m_sqlManager.createQuery(dbc, projectId, C_READ_RESOURCE_OUS);
q.setParameter(1, Integer.valueOf(CmsRelationType.OU_RESOURCE.getId()));
@SuppressWarnings("unchecked")
List<I_CmsDAOResourceRelations> res = internalResourceOus(q.getResultList(), resName);
for (I_CmsDAOResourceRelations rr : res) {
CmsRelation rel = internalReadRelation(rr);
try {
ous.add(m_driverManager.readOrganizationalUnit(
dbc,
rel.getSourcePath().substring(CmsUserDriver.ORGUNIT_BASE_FOLDER.length())));
} catch (CmsException e) {
// should never happen
if (LOG.isErrorEnabled()) {
LOG.error(e.getLocalizedMessage(), e);
}
}
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
return ous;
}
/**
* @see org.opencms.db.I_CmsVfsDriver#getSqlManager()
*/
public CmsSqlManager getSqlManager() {
return m_sqlManager;
}
/**
* @see org.opencms.db.I_CmsVfsDriver#incrementCounter(org.opencms.db.CmsDbContext, java.lang.String)
*/
public int incrementCounter(CmsDbContext dbc, String name) {
CmsDAOCounters c = m_sqlManager.find(dbc, CmsDAOCounters.class, name);
int result = 0;
if (c != null) {
result = c.getCounter();
c.setCounter(c.getCounter() + 1);
} else {
c = new CmsDAOCounters();
c.setName(name);
c.setCounter(1);
m_sqlManager.persist(dbc, c);
}
return result;
}
/**
* @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) {
CmsParameterConfiguration config = configurationManager.getConfiguration();
String poolUrl = config.get("db.vfs.pool");
String classname = config.get("db.vfs.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_CmsVfsDriver#initSqlManager(String)
*/
public CmsSqlManager initSqlManager(String classname) {
return CmsSqlManager.getInstance(classname);
}
/**
* @see org.opencms.db.I_CmsVfsDriver#moveResource(CmsDbContext, CmsUUID, CmsResource, String)
*/
public void moveResource(CmsDbContext dbc, CmsUUID projectId, CmsResource source, String destinationPath)
throws CmsDataAccessException {
if ((dbc.getRequestContext() != null)
&& (dbc.getRequestContext().getAttribute(REQ_ATTR_CHECK_PERMISSIONS) != null)) {
// only check write permissions
checkWritePermissionsInFolder(dbc, source);
return;
}
// determine destination folder
String destinationFoldername = CmsResource.getParentFolder(destinationPath);
// read the destination folder (will also check read permissions)
CmsFolder destinationFolder = m_driverManager.readFolder(dbc, destinationFoldername, CmsResourceFilter.ALL);
if (!projectId.equals(CmsProject.ONLINE_PROJECT_ID)) {
// check online resource
try {
CmsResource onlineResource = m_driverManager.getVfsDriver(dbc).readResource(
dbc,
CmsProject.ONLINE_PROJECT_ID,
destinationPath,
true);
if (!onlineResource.getStructureId().equals(source.getStructureId())) {
// source resource has been moved and it is not the
// same as the resource that is being trying to move back
CmsResource offlineResource = null;
try {
// read new location in offline project
offlineResource = readResource(
dbc,
dbc.getRequestContext().getCurrentProject().getUuid(),
onlineResource.getStructureId(),
true);
} catch (CmsException e) {
// should never happen
if (LOG.isErrorEnabled()) {
LOG.error(e.getMessage(), e);
}
}
throw new CmsVfsOnlineResourceAlreadyExistsException(Messages.get().container(
Messages.ERR_OVERWRITE_MOVED_RESOURCE_3,
dbc.removeSiteRoot(source.getRootPath()),
dbc.removeSiteRoot(destinationPath),
dbc.removeSiteRoot(offlineResource == null ? "__ERROR__" : offlineResource.getRootPath())));
}
} catch (CmsVfsResourceNotFoundException e) {
// ok, no online resource
}
}
try {
Query q = m_sqlManager.createQuery(dbc, projectId, C_RESOURCES_MOVE);
q.setParameter(1, source.getStructureId().toString());
@SuppressWarnings("unchecked")
List<I_CmsDAOStructure> res = q.getResultList();
for (I_CmsDAOStructure s : res) {
s.setResourcePath(CmsFileUtil.removeTrailingSeparator(destinationPath)); // must remove trailing slash
s.setParentId(destinationFolder.getStructureId().toString());
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
moveRelations(dbc, projectId, source.getStructureId(), destinationPath);
repairBrokenRelations(dbc, projectId, source.getStructureId(), destinationPath);
try {
m_driverManager.repairCategories(dbc, projectId, readResource(dbc, projectId, destinationPath, true));
} catch (CmsException e) {
throw new CmsDataAccessException(e.getMessageContainer(), e);
}
// repair project resources
if (!projectId.equals(CmsProject.ONLINE_PROJECT_ID) && (dbc.getRequestContext() != null)) {
String deletedResourceRootPath = source.getRootPath();
dbc.getRequestContext().setAttribute(CmsProjectDriver.DBC_ATTR_READ_PROJECT_FOR_RESOURCE, Boolean.TRUE);
I_CmsProjectDriver projectDriver = m_driverManager.getProjectDriver(dbc);
Iterator<CmsProject> itProjects = projectDriver.readProjects(dbc, deletedResourceRootPath).iterator();
while (itProjects.hasNext()) {
CmsProject project = itProjects.next();
projectDriver.deleteProjectResource(dbc, project.getUuid(), deletedResourceRootPath);
projectDriver.createProjectResource(dbc, project.getUuid(), destinationPath);
}
}
}
/**
* @see org.opencms.db.I_CmsVfsDriver#publishResource(org.opencms.db.CmsDbContext, org.opencms.file.CmsProject, org.opencms.file.CmsResource, org.opencms.file.CmsResource)
*/
public void publishResource(
CmsDbContext dbc,
CmsProject onlineProject,
CmsResource onlineResource,
CmsResource offlineResource) throws CmsDataAccessException {
// validate the resource length
internalValidateResourceLength(offlineResource);
int resourceSize = offlineResource.getLength();
String resourcePath = CmsFileUtil.removeTrailingSeparator(offlineResource.getRootPath());
Query q;
try {
boolean resourceExists = validateResourceIdExists(
dbc,
onlineProject.getUuid(),
offlineResource.getResourceId());
if (resourceExists) {
// the resource record exists online already
// update the online resource record
q = m_sqlManager.createQuery(dbc, onlineProject, C_RESOURCES_UPDATE_RESOURCES);
q.setParameter(1, offlineResource.getResourceId().toString());
@SuppressWarnings("unchecked")
List<I_CmsDAOResources> res = q.getResultList();
for (I_CmsDAOResources r : res) {
r.setResourceType(offlineResource.getTypeId());
r.setResourceFlags(offlineResource.getFlags());
r.setDateLastModified(offlineResource.getDateLastModified());
r.setUserLastModified(offlineResource.getUserLastModified().toString());
r.setResourceState(CmsResource.STATE_UNCHANGED.getState());
r.setResourceSize(resourceSize);
r.setDateContent(offlineResource.getDateContent());
r.setProjectLastModified(offlineResource.getProjectLastModified().toString());
r.setSiblingCount(countSiblings(dbc, onlineProject.getUuid(), onlineResource.getResourceId()));
}
} else {
// the resource record does NOT exist online yet
// create the resource record online
I_CmsDAOResources r = CmsProject.isOnlineProject(onlineProject.getUuid())
? new CmsDAOOnlineResources()
: new CmsDAOOfflineResources();
r.setResourceId(offlineResource.getResourceId().toString());
r.setResourceType(offlineResource.getTypeId());
r.setResourceFlags(offlineResource.getFlags());
r.setDateCreated(offlineResource.getDateCreated());
r.setUserCreated(offlineResource.getUserCreated().toString());
r.setDateLastModified(offlineResource.getDateLastModified());
r.setUserLastModified(offlineResource.getUserLastModified().toString());
r.setResourceState(CmsResource.STATE_UNCHANGED.getState());
r.setResourceSize(resourceSize);
r.setDateContent(offlineResource.getDateContent());
r.setProjectLastModified(offlineResource.getProjectLastModified().toString());
r.setSiblingCount(1); // initial siblings count
r.setResourceVersion(1); // initial resource version
m_sqlManager.persist(dbc, r);
}
// read the parent id
String parentId = internalReadParentId(dbc, onlineProject.getUuid(), resourcePath);
if (validateStructureIdExists(dbc, onlineProject.getUuid(), offlineResource.getStructureId())) {
// update the online structure record
q = m_sqlManager.createQuery(dbc, onlineProject, C_RESOURCES_UPDATE_STRUCTURE);
q.setParameter(1, offlineResource.getStructureId().toString());
@SuppressWarnings("unchecked")
List<I_CmsDAOStructure> res = q.getResultList();
for (I_CmsDAOStructure s : res) {
s.setResourceId(offlineResource.getResourceId().toString());
s.setResourcePath(resourcePath);
s.setStructureState(CmsResource.STATE_UNCHANGED.getState());
s.setDateReleased(offlineResource.getDateReleased());
s.setDateExpired(offlineResource.getDateExpired());
s.setParentId(parentId);
}
} else {
I_CmsDAOStructure s = CmsProject.isOnlineProject(onlineProject.getUuid())
? new CmsDAOOnlineStructure()
: new CmsDAOOfflineStructure();
s.setStructureId(offlineResource.getStructureId().toString());
s.setResourceId(offlineResource.getResourceId().toString());
s.setResourcePath(resourcePath);
s.setStructureState(CmsResource.STATE_UNCHANGED.getState());
s.setDateReleased(offlineResource.getDateReleased());
s.setDateExpired(offlineResource.getDateExpired());
s.setParentId(parentId);
s.setStructureVersion(resourceExists ? 1 : 0); // new resources start with 0, new siblings with 1
m_sqlManager.persist(dbc, s);
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
}
/**
* @see org.opencms.db.I_CmsVfsDriver#publishVersions(org.opencms.db.CmsDbContext, org.opencms.file.CmsResource, boolean)
*/
public void publishVersions(CmsDbContext dbc, CmsResource resource, boolean firstSibling)
throws CmsDataAccessException {
// if resource is null just flush the internal cache
if (resource == null) {
m_resOp.clear();
return;
}
if (!dbc.getProjectId().isNullUUID() || dbc.currentProject().isOnlineProject()) {
// this method is supposed to be used only in the offline project
return;
}
if (firstSibling) {
// reset the resource operation flag
m_resOp.remove(resource.getResourceId());
}
boolean resOp = false; // assume structure operation
CmsResourceState resState = internalReadResourceState(dbc, dbc.currentProject().getUuid(), resource);
CmsResourceState strState = internalReadStructureState(dbc, dbc.currentProject().getUuid(), resource);
if (!resState.isUnchanged()) {
if (strState.isDeleted()) {
resOp = (resState.isDeleted() || (resource.getSiblingCount() == 1) || (countSiblings(
dbc,
dbc.currentProject().getUuid(),
resource.getResourceId()) == 1));
} else {
resOp = true;
}
}
if (!firstSibling) {
if (resOp) {
return;
}
if (m_resOp.contains(resource.getResourceId())) {
return;
}
}
// read the offline version numbers
Map<String, Integer> versions = readVersions(
dbc,
dbc.currentProject().getUuid(),
resource.getResourceId(),
resource.getStructureId());
int strVersion = versions.get("structure").intValue();
int resVersion = versions.get("resource").intValue();
if (resOp) {
if (resource.getSiblingCount() > 1) {
m_resOp.add(resource.getResourceId());
}
resVersion++;
}
if (!resOp) {
strVersion++;
}
try {
if (resOp) {
// update the resource version
Query q = m_sqlManager.createQuery(
dbc,
CmsProject.ONLINE_PROJECT_ID,
C_RESOURCES_UPDATE_RESOURCE_VERSION);
q.setParameter(1, resource.getResourceId().toString());
@SuppressWarnings("unchecked")
List<I_CmsDAOResources> res = q.getResultList();
for (I_CmsDAOResources r : res) {
r.setResourceVersion(resVersion);
}
}
if (!resOp || strState.isNew()) {
// update the structure version
Query q = m_sqlManager.createQuery(
dbc,
CmsProject.ONLINE_PROJECT_ID,
C_RESOURCES_UPDATE_STRUCTURE_VERSION);
q.setParameter(1, resource.getStructureId().toString());
@SuppressWarnings("unchecked")
List<I_CmsDAOStructure> res = q.getResultList();
for (I_CmsDAOStructure s : res) {
s.setStructureVersion(strVersion);
}
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
}
/**
* @see org.opencms.db.I_CmsVfsDriver#readChildResources(org.opencms.db.CmsDbContext, org.opencms.file.CmsProject, org.opencms.file.CmsResource, boolean, boolean)
*/
public List<CmsResource> readChildResources(
CmsDbContext dbc,
CmsProject currentProject,
CmsResource resource,
boolean getFolders,
boolean getFiles) throws CmsDataAccessException {
List<CmsResource> result = new ArrayList<CmsResource>();
CmsUUID projectId = currentProject.getUuid();
String resourceTypeClause;
if (getFolders && getFiles) {
resourceTypeClause = null;
} else if (getFolders) {
resourceTypeClause = m_sqlManager.readQuery(projectId, C_RESOURCES_GET_SUBRESOURCES_GET_FOLDERS);
} else {
resourceTypeClause = m_sqlManager.readQuery(projectId, C_RESOURCES_GET_SUBRESOURCES_GET_FILES);
}
StringBuffer query = new StringBuffer();
query.append(m_sqlManager.readQuery(projectId, C_RESOURCES_GET_SUBRESOURCES));
if (resourceTypeClause != null) {
query.append(' ');
query.append(resourceTypeClause);
}
try {
Query q = m_sqlManager.createQueryFromJPQL(dbc, query.toString());
q.setParameter(1, resource.getStructureId().toString());
@SuppressWarnings("unchecked")
List<Object[]> res = q.getResultList();
I_CmsDAOResources r;
for (Object[] o : res) {
r = (I_CmsDAOResources)o[0];
long size = r.getResourceSize();
if (CmsFolder.isFolderSize(size)) {
result.add(createFolder(o, projectId, false));
} else {
result.add(createFile(o, projectId, false));
}
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
// sort result in memory, this is to avoid DB dependencies in the result order
Collections.sort(result, I_CmsResource.COMPARE_ROOT_PATH_IGNORE_CASE_FOLDERS_FIRST);
return result;
}
/**
* @see org.opencms.db.I_CmsVfsDriver#readContent(org.opencms.db.CmsDbContext, CmsUUID, org.opencms.util.CmsUUID)
*/
public byte[] readContent(CmsDbContext dbc, CmsUUID projectId, CmsUUID resourceId) throws CmsDataAccessException {
byte[] byteRes = null;
boolean resourceExists = false;
try {
if (projectId.equals(CmsProject.ONLINE_PROJECT_ID)) {
// ONLINE PROJECT
Query q = m_sqlManager.createQuery(dbc, projectId, C_ONLINE_FILES_CONTENT);
q.setParameter(1, resourceId.toString());
try {
byteRes = ((CmsDAOContents)q.getSingleResult()).getFileContent();
resourceExists = true;
} catch (NoResultException e) {
// do nothing
}
} else {
// OFFLINE PROJECT
CmsDAOOfflineContents c = m_sqlManager.find(dbc, CmsDAOOfflineContents.class, resourceId.toString());
if (c != null) {
byteRes = c.getFileContent();
resourceExists = true;
}
}
if (!resourceExists) {
throw new CmsVfsResourceNotFoundException(Messages.get().container(
Messages.ERR_READ_CONTENT_WITH_RESOURCE_ID_2,
resourceId,
Boolean.valueOf(projectId.equals(CmsProject.ONLINE_PROJECT_ID))));
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
return byteRes == null ? EMPTY_BLOB : byteRes;
}
/**
* @see org.opencms.db.I_CmsVfsDriver#readFolder(org.opencms.db.CmsDbContext, CmsUUID, org.opencms.util.CmsUUID)
*/
public CmsFolder readFolder(CmsDbContext dbc, CmsUUID projectId, CmsUUID folderId) throws CmsDataAccessException {
CmsFolder folder = null;
try {
Query q = m_sqlManager.createQuery(dbc, projectId, C_RESOURCES_READBYID);
q.setParameter(1, folderId.toString());
try {
Object[] o = (Object[])q.getSingleResult();
folder = createFolder(o, projectId, true);
} catch (NoResultException e) {
throw new CmsVfsResourceNotFoundException(Messages.get().container(
Messages.ERR_READ_FOLDER_WITH_ID_1,
folderId));
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
return folder;
}
/**
* @see org.opencms.db.I_CmsVfsDriver#readFolder(org.opencms.db.CmsDbContext, CmsUUID, java.lang.String)
*/
public CmsFolder readFolder(CmsDbContext dbc, CmsUUID projectId, String folderPath) throws CmsDataAccessException {
CmsFolder folder = null;
folderPath = CmsFileUtil.removeTrailingSeparator(folderPath);
try {
Query q = m_sqlManager.createQuery(dbc, projectId, C_RESOURCES_READ);
q.setParameter(1, folderPath);
try {
Object[] o = (Object[])q.getSingleResult();
folder = createFolder(o, projectId, true);
} catch (NoResultException e) {
throw new CmsVfsResourceNotFoundException(Messages.get().container(
Messages.ERR_READ_FOLDER_1,
dbc.removeSiteRoot(folderPath)));
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
return folder;
}
/**
* @see org.opencms.db.I_CmsVfsDriver#readParentFolder(org.opencms.db.CmsDbContext, CmsUUID, org.opencms.util.CmsUUID)
*/
public CmsFolder readParentFolder(CmsDbContext dbc, CmsUUID projectId, CmsUUID structureId)
throws CmsDataAccessException {
CmsFolder parent = null;
try {
Query q = m_sqlManager.createQuery(dbc, projectId, C_RESOURCES_READ_PARENT_BY_ID);
q.setParameter(1, structureId.toString());
try {
Object[] o = (Object[])q.getSingleResult();
parent = new CmsFolder(createResource(o, projectId));
} catch (NoResultException e) {
// do nothing
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
return parent;
}
/**
* @see org.opencms.db.I_CmsVfsDriver#readPropertyDefinition(org.opencms.db.CmsDbContext, java.lang.String, CmsUUID)
*/
public CmsPropertyDefinition readPropertyDefinition(CmsDbContext dbc, String name, CmsUUID projectId)
throws CmsDataAccessException {
CmsPropertyDefinition propDef = null;
try {
Query q = m_sqlManager.createQuery(dbc, projectId, C_PROPERTYDEF_READ);
q.setParameter(1, name);
try {
I_CmsDAOPropertyDef pd = (I_CmsDAOPropertyDef)q.getSingleResult();
propDef = new CmsPropertyDefinition(
new CmsUUID(pd.getPropertyDefId()),
pd.getPropertyDefName(),
CmsPropertyDefinition.CmsPropertyType.valueOf(pd.getPropertyDefType()));
} catch (NoResultException e) {
throw new CmsDbEntryNotFoundException(Messages.get().container(
Messages.ERR_NO_PROPERTYDEF_WITH_NAME_1,
name));
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
return propDef;
}
/**
* @see org.opencms.db.I_CmsVfsDriver#readPropertyDefinitions(org.opencms.db.CmsDbContext, CmsUUID)
*/
public List<CmsPropertyDefinition> readPropertyDefinitions(CmsDbContext dbc, CmsUUID projectId)
throws CmsDataAccessException {
ArrayList<CmsPropertyDefinition> propertyDefinitions = new ArrayList<CmsPropertyDefinition>();
try {
Query q = m_sqlManager.createQuery(dbc, projectId, C_PROPERTYDEF_READALL);
@SuppressWarnings("unchecked")
List<I_CmsDAOPropertyDef> res = q.getResultList();
for (I_CmsDAOPropertyDef pd : res) {
propertyDefinitions.add(new CmsPropertyDefinition(
new CmsUUID(pd.getPropertyDefId()),
pd.getPropertyDefName(),
CmsPropertyDefinition.CmsPropertyType.valueOf(pd.getPropertyDefType())));
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
return propertyDefinitions;
}
/**
* @see org.opencms.db.I_CmsVfsDriver#readPropertyObject(org.opencms.db.CmsDbContext, java.lang.String, org.opencms.file.CmsProject, org.opencms.file.CmsResource)
*/
public CmsProperty readPropertyObject(CmsDbContext dbc, String key, CmsProject project, CmsResource resource)
throws CmsDataAccessException {
CmsUUID projectId = ((dbc.getProjectId() == null) || dbc.getProjectId().isNullUUID())
? project.getUuid()
: dbc.getProjectId();
String propertyValue = null;
int mappingType = -1;
CmsProperty property = null;
int resultSize = 0;
try {
Query q = m_sqlManager.createQuery(dbc, projectId, C_PROPERTIES_READ);
q.setParameter(1, key);
q.setParameter(2, resource.getStructureId().toString());
q.setParameter(3, resource.getResourceId().toString());
@SuppressWarnings("unchecked")
List<I_CmsDAOProperties> res = q.getResultList();
for (I_CmsDAOProperties o : res) {
if (resultSize >= 2) {
throw new CmsDbConsistencyException(Messages.get().container(
Messages.ERR_TOO_MANY_PROPERTIES_3,
key,
resource.getRootPath(),
new Integer(resultSize)));
}
if (property == null) {
property = new CmsProperty();
property.setName(key);
}
propertyValue = o.getPropertyValue();
mappingType = o.getPropertyMappingType();
if (mappingType == CmsProperty.STRUCTURE_RECORD_MAPPING) {
property.setStructureValue(propertyValue);
} else if (mappingType == CmsProperty.RESOURCE_RECORD_MAPPING) {
property.setResourceValue(propertyValue);
} else {
throw new CmsDbConsistencyException(Messages.get().container(
Messages.ERR_UNKNOWN_PROPERTY_VALUE_MAPPING_3,
resource.getRootPath(),
new Integer(mappingType),
key));
}
resultSize++;
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
return (property != null) ? property : CmsProperty.getNullProperty();
}
/**
* @see org.opencms.db.I_CmsVfsDriver#readPropertyObjects(org.opencms.db.CmsDbContext, org.opencms.file.CmsProject, org.opencms.file.CmsResource)
*/
public List<CmsProperty> readPropertyObjects(CmsDbContext dbc, CmsProject project, CmsResource resource)
throws CmsDataAccessException {
CmsUUID projectId = ((dbc.getProjectId() == null) || dbc.getProjectId().isNullUUID())
? project.getUuid()
: dbc.getProjectId();
int mappingType = -1;
Map<String, CmsProperty> propertyMap = new HashMap<String, CmsProperty>();
String propertyKey;
String propertyValue;
CmsProperty property;
try {
Query q = m_sqlManager.createQuery(dbc, projectId, C_PROPERTIES_READALL);
q.setParameter(1, resource.getStructureId().toString());
q.setParameter(2, resource.getResourceId().toString());
@SuppressWarnings("unchecked")
List<Object[]> res = q.getResultList();
for (Object[] o : res) {
propertyKey = null;
propertyValue = null;
mappingType = -1;
propertyKey = ((I_CmsDAOPropertyDef)o[0]).getPropertyDefName();
propertyValue = ((I_CmsDAOProperties)o[1]).getPropertyValue();
mappingType = ((I_CmsDAOProperties)o[1]).getPropertyMappingType();
property = propertyMap.get(propertyKey);
if (property == null) {
// there doesn't exist a property object for this key yet
property = new CmsProperty();
property.setName(propertyKey);
propertyMap.put(propertyKey, property);
}
if (mappingType == CmsProperty.STRUCTURE_RECORD_MAPPING) {
// this property value is mapped to a structure record
property.setStructureValue(propertyValue);
} else if (mappingType == CmsProperty.RESOURCE_RECORD_MAPPING) {
// this property value is mapped to a resource record
property.setResourceValue(propertyValue);
} else {
throw new CmsDbConsistencyException(Messages.get().container(
Messages.ERR_UNKNOWN_PROPERTY_VALUE_MAPPING_3,
resource.getRootPath(),
new Integer(mappingType),
propertyKey));
}
property.setOrigin(resource.getRootPath());
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
return new ArrayList<CmsProperty>(propertyMap.values());
}
/**
* @see org.opencms.db.I_CmsVfsDriver#readRelations(org.opencms.db.CmsDbContext, CmsUUID, CmsResource, org.opencms.relations.CmsRelationFilter)
*/
public List<CmsRelation> readRelations(
CmsDbContext dbc,
CmsUUID projectId,
CmsResource resource,
CmsRelationFilter filter) throws CmsDataAccessException {
Set<CmsRelation> relations = new HashSet<CmsRelation>();
try {
if (filter.isSource()) {
List<String> params = new ArrayList<String>(7);
StringBuffer queryBuf = new StringBuffer(256);
queryBuf.append(m_sqlManager.readQuery(projectId, C_READ_RELATIONS));
queryBuf.append(prepareRelationConditions(projectId, filter, resource, params, true));
if (LOG.isDebugEnabled()) {
LOG.debug(queryBuf.toString());
}
Query q = m_sqlManager.createQueryFromJPQL(dbc, queryBuf.toString());
for (int i = 0; i < params.size(); i++) {
q.setParameter(i + 1, params.get(i));
}
@SuppressWarnings("unchecked")
List<I_CmsDAOResourceRelations> res = q.getResultList();
for (I_CmsDAOResourceRelations rr : res) {
relations.add(internalReadRelation(rr));
}
}
if (filter.isTarget()) {
List<String> params = new ArrayList<String>(7);
StringBuffer queryBuf = new StringBuffer(256);
queryBuf.append(m_sqlManager.readQuery(projectId, C_READ_RELATIONS));
queryBuf.append(prepareRelationConditions(projectId, filter, resource, params, false));
if (LOG.isDebugEnabled()) {
LOG.debug(queryBuf.toString());
}
Query q = m_sqlManager.createQueryFromJPQL(dbc, queryBuf.toString());
for (int i = 0; i < params.size(); i++) {
q.setParameter(i + 1, params.get(i));
}
@SuppressWarnings("unchecked")
List<I_CmsDAOResourceRelations> res = q.getResultList();
for (I_CmsDAOResourceRelations rr : res) {
relations.add(internalReadRelation(rr));
}
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
List<CmsRelation> result = new ArrayList<CmsRelation>(relations);
Collections.sort(result, CmsRelation.COMPARATOR);
return result;
}
/**
* @see org.opencms.db.I_CmsVfsDriver#readResource(org.opencms.db.CmsDbContext, CmsUUID, org.opencms.util.CmsUUID, boolean)
*/
public CmsResource readResource(CmsDbContext dbc, CmsUUID projectId, CmsUUID structureId, boolean includeDeleted)
throws CmsDataAccessException {
CmsResource resource = null;
try {
Query q = m_sqlManager.createQuery(dbc, projectId, C_RESOURCES_READBYID);
q.setParameter(1, structureId.toString());
try {
Object[] o = (Object[])q.getSingleResult();
resource = createResource(o, projectId);
} catch (NoResultException e) {
throw new CmsVfsResourceNotFoundException(Messages.get().container(
Messages.ERR_READ_RESOURCE_WITH_ID_1,
structureId));
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
// check if this resource is marked as deleted and if we are allowed to return a deleted resource
if ((resource != null) && resource.getState().isDeleted() && !includeDeleted) {
throw new CmsVfsResourceNotFoundException(Messages.get().container(
Messages.ERR_READ_DELETED_RESOURCE_1,
dbc.removeSiteRoot(resource.getRootPath())));
}
return resource;
}
/**
* @see org.opencms.db.I_CmsVfsDriver#readResource(org.opencms.db.CmsDbContext, CmsUUID, java.lang.String, boolean)
*/
public CmsResource readResource(CmsDbContext dbc, CmsUUID projectId, String path, boolean includeDeleted)
throws CmsDataAccessException {
CmsResource resource = null;
// must remove trailing slash
path = CmsFileUtil.removeTrailingSeparator(path);
boolean endsWithSlash = path.endsWith("/");
try {
Query q = m_sqlManager.createQuery(dbc, projectId, C_RESOURCES_READ);
q.setParameter(1, path);
try {
Object[] o = (Object[])q.getSingleResult();
resource = createResource(o, projectId);
// check if the resource is a file, it is not allowed to end with a "/" then
if (endsWithSlash && resource.isFile()) {
throw new CmsVfsResourceNotFoundException(Messages.get().container(
Messages.ERR_READ_RESOURCE_1,
dbc.removeSiteRoot(path + "/")));
}
} catch (NoResultException e) {
throw new CmsVfsResourceNotFoundException(Messages.get().container(
Messages.ERR_READ_RESOURCE_1,
dbc.removeSiteRoot(path)));
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
// check if this resource is marked as deleted and if we are allowed to return a deleted resource
if ((resource != null) && resource.getState().isDeleted() && !includeDeleted) {
throw new CmsVfsResourceNotFoundException(Messages.get().container(
Messages.ERR_READ_DELETED_RESOURCE_1,
dbc.removeSiteRoot(resource.getRootPath())));
}
return resource;
}
/**
* @see org.opencms.db.I_CmsVfsDriver#readResources(org.opencms.db.CmsDbContext, CmsUUID, CmsResourceState, int)
*/
public List<CmsResource> readResources(CmsDbContext dbc, CmsUUID projectId, CmsResourceState state, int mode)
throws CmsDataAccessException {
List<CmsResource> result = new ArrayList<CmsResource>();
Query q;
try {
if (mode == CmsDriverManager.READMODE_MATCHSTATE) {
q = m_sqlManager.createQuery(dbc, projectId, C_RESOURCES_GET_RESOURCE_IN_PROJECT_WITH_STATE);
q.setParameter(1, projectId.toString());
q.setParameter(2, Integer.valueOf(state.getState()));
q.setParameter(3, Integer.valueOf(state.getState()));
q.setParameter(4, Integer.valueOf(state.getState()));
q.setParameter(5, Integer.valueOf(state.getState()));
} else if (mode == CmsDriverManager.READMODE_UNMATCHSTATE) {
q = m_sqlManager.createQuery(dbc, projectId, C_RESOURCES_GET_RESOURCE_IN_PROJECT_WITHOUT_STATE);
q.setParameter(1, projectId.toString());
q.setParameter(2, Integer.valueOf(state.getState()));
q.setParameter(3, Integer.valueOf(state.getState()));
} else {
q = m_sqlManager.createQuery(dbc, projectId, C_RESOURCES_GET_RESOURCE_IN_PROJECT_IGNORE_STATE);
q.setParameter(1, projectId.toString());
}
@SuppressWarnings("unchecked")
List<Object[]> res = q.getResultList();
for (Object[] o : res) {
CmsResource resource = createResource(o, projectId);
result.add(resource);
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
return result;
}
/**
* @see org.opencms.db.I_CmsVfsDriver#readResourcesForPrincipalACE(org.opencms.db.CmsDbContext, org.opencms.file.CmsProject, org.opencms.util.CmsUUID)
*/
public List<CmsResource> readResourcesForPrincipalACE(CmsDbContext dbc, CmsProject project, CmsUUID principalId)
throws CmsDataAccessException {
CmsResource currentResource = null;
List<CmsResource> resources = new ArrayList<CmsResource>();
try {
Query q = m_sqlManager.createQuery(dbc, project, C_SELECT_RESOURCES_FOR_PRINCIPAL_ACE);
q.setParameter(1, principalId.toString());
@SuppressWarnings("unchecked")
List<Object[]> res = q.getResultList();
for (Object[] o : res) {
currentResource = createFile(o, project.getUuid(), false);
resources.add(currentResource);
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
return resources;
}
/**
* @see org.opencms.db.I_CmsVfsDriver#readResourcesForPrincipalAttr(org.opencms.db.CmsDbContext, org.opencms.file.CmsProject, org.opencms.util.CmsUUID)
*/
public List<CmsResource> readResourcesForPrincipalAttr(CmsDbContext dbc, CmsProject project, CmsUUID principalId)
throws CmsDataAccessException {
CmsResource currentResource = null;
List<CmsResource> resources = new ArrayList<CmsResource>();
try {
// JPQL does not support UNION clause
String[] queries = {C_SELECT_RESOURCES_FOR_PRINCIPAL_ATTR1, C_SELECT_RESOURCES_FOR_PRINCIPAL_ATTR2};
String[] parameters = {principalId.toString(), principalId.toString()};
Query q;
for (int i = 0; i < queries.length; i++) {
q = m_sqlManager.createQuery(dbc, project, queries[i]);
q.setParameter(1, parameters[i]);
@SuppressWarnings("unchecked")
List<Object[]> res = q.getResultList();
for (Object[] o : res) {
currentResource = createFile(o, project.getUuid(), false);
resources.add(currentResource);
}
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
return resources;
}
/**
* @see org.opencms.db.I_CmsVfsDriver#readResourcesWithProperty(org.opencms.db.CmsDbContext, CmsUUID, org.opencms.util.CmsUUID, String, String)
*/
public List<CmsResource> readResourcesWithProperty(
CmsDbContext dbc,
CmsUUID projectId,
CmsUUID propertyDef,
String path,
String value) throws CmsDataAccessException {
List<CmsResource> resources = new ArrayList<CmsResource>();
Query q;
List<Object[]> res = new ArrayList<Object[]>();
try {
if (value == null) {
q = m_sqlManager.createQuery(dbc, projectId, C_RESOURCES_GET_RESOURCE_WITH_PROPERTYDEF);
q.setParameter(1, propertyDef.toString());
q.setParameter(2, escapeDbWildcard(path + "%"));
res.addAll(q.getResultList());
} else {
q = m_sqlManager.createQuery(dbc, projectId, C_RESOURCES_GET_RESOURCE_WITH_PROPERTYDEF_VALUE);
q.setParameter(1, propertyDef.toString());
q.setParameter(2, escapeDbWildcard(path + "%"));
q.setParameter(3, "%" + value + "%");
q.setParameter(4, escapeDbWildcard(path + "%"));
q.setParameter(5, "%" + value + "%");
res.addAll(q.getResultList());
}
for (Object[] o : res) {
CmsResource resource = createResource(o, projectId);
resources.add(resource);
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
return resources;
}
/**
* @see org.opencms.db.I_CmsVfsDriver#readResourceTree(org.opencms.db.CmsDbContext, CmsUUID, java.lang.String, int, CmsResourceState, long, long, long, long, long, long, int)
*/
public List<CmsResource> readResourceTree(
CmsDbContext dbc,
CmsUUID projectId,
String parentPath,
int type,
CmsResourceState state,
long lastModifiedAfter,
long lastModifiedBefore,
long releasedAfter,
long releasedBefore,
long expiredAfter,
long expiredBefore,
int mode) throws CmsDataAccessException {
List<CmsResource> result = new ArrayList<CmsResource>();
StringBuffer conditions = new StringBuffer();
List params = new ArrayList(5);
// prepare the selection criteria
prepareProjectCondition(projectId, mode, conditions, params);
prepareResourceCondition(projectId, mode, conditions);
prepareTypeCondition(projectId, type, mode, conditions, params);
prepareTimeRangeCondition(projectId, lastModifiedAfter, lastModifiedBefore, conditions, params);
prepareReleasedTimeRangeCondition(projectId, releasedAfter, releasedBefore, conditions, params);
prepareExpiredTimeRangeCondition(projectId, expiredAfter, expiredBefore, conditions, params);
preparePathCondition(projectId, parentPath, mode, conditions, params);
prepareStateCondition(projectId, state, mode, conditions, params);
// now read matching resources within the subtree
try {
StringBuffer queryBuf = new StringBuffer(256);
queryBuf.append(m_sqlManager.readQuery(projectId, C_RESOURCES_READ_TREE));
queryBuf.append(conditions);
queryBuf.append(" ");
queryBuf.append(m_sqlManager.readQuery(projectId, C_RESOURCES_ORDER_BY_PATH));
Query q = m_sqlManager.createQueryFromJPQL(dbc, queryBuf.toString());
for (int i = 0; i < params.size(); i++) {
q.setParameter(i + 1, params.get(i));
}
@SuppressWarnings("unchecked")
List<Object[]> res = q.getResultList();
for (Object[] o : res) {
CmsResource resource = createResource(o, projectId);
result.add(resource);
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
return result;
}
/**
* @see org.opencms.db.I_CmsVfsDriver#readSiblings(org.opencms.db.CmsDbContext, CmsUUID, org.opencms.file.CmsResource, boolean)
*/
public List<CmsResource> readSiblings(
CmsDbContext dbc,
CmsUUID projectId,
CmsResource resource,
boolean includeDeleted) throws CmsDataAccessException {
CmsResource currentResource = null;
List<CmsResource> vfsLinks = new ArrayList<CmsResource>();
Query q;
try {
if (includeDeleted) {
q = m_sqlManager.createQuery(dbc, projectId, C_SELECT_VFS_SIBLINGS);
} else {
q = m_sqlManager.createQuery(dbc, projectId, C_SELECT_NONDELETED_VFS_SIBLINGS);
}
q.setParameter(1, resource.getResourceId().toString());
@SuppressWarnings("unchecked")
List<Object[]> res = q.getResultList();
for (Object[] o : res) {
currentResource = createFile(o, projectId, false);
vfsLinks.add(currentResource);
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
return vfsLinks;
}
/**
* @see org.opencms.db.I_CmsVfsDriver#readUrlNameMappingEntries(org.opencms.db.CmsDbContext, boolean, org.opencms.db.urlname.CmsUrlNameMappingFilter)
*/
public List<CmsUrlNameMappingEntry> readUrlNameMappingEntries(
CmsDbContext dbc,
boolean online,
CmsUrlNameMappingFilter filter) throws CmsDataAccessException {
List<CmsUrlNameMappingEntry> result = new ArrayList<CmsUrlNameMappingEntry>();
try {
String query = m_sqlManager.readQuery(C_READ_URLNAME_MAPPINGS);
Query q = getQueryForFilter(dbc, query, filter, online);
@SuppressWarnings("unchecked")
List<I_CmsDAOUrlNameMappings> res = q.getResultList();
for (I_CmsDAOUrlNameMappings m : res) {
CmsUrlNameMappingEntry entry = internalCreateUrlNameMappingEntry(m);
result.add(entry);
}
return result;
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
}
/**
* @see org.opencms.db.I_CmsVfsDriver#readVersions(org.opencms.db.CmsDbContext, org.opencms.util.CmsUUID, org.opencms.util.CmsUUID, org.opencms.util.CmsUUID)
*/
public Map<String, Integer> readVersions(
CmsDbContext dbc,
CmsUUID projectId,
CmsUUID resourceId,
CmsUUID structureId) throws CmsDataAccessException {
int structureVersion = -1;
int resourceVersion = -1;
Query q;
try {
// read the offline version numbers, first for the resource entry
q = m_sqlManager.createQuery(dbc, projectId, C_RESOURCES_READ_VERSION_RES);
q.setParameter(1, resourceId.toString());
try {
resourceVersion = CmsDataTypeUtil.numberToInt((Number)q.getSingleResult());
} catch (NoResultException e) {
// do nothing
}
// then for the structure entry
q = m_sqlManager.createQuery(dbc, projectId, C_RESOURCES_READ_VERSION_STR);
q.setParameter(1, structureId.toString());
try {
structureVersion = CmsDataTypeUtil.numberToInt((Number)q.getSingleResult());
} catch (NoResultException e) {
// do nothing
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
Map<String, Integer> result = new HashMap<String, Integer>();
result.put("structure", new Integer(structureVersion));
result.put(I_CmsEventListener.KEY_RESOURCE, new Integer(resourceVersion));
return result;
}
/**
* @see org.opencms.db.I_CmsVfsDriver#removeFile(org.opencms.db.CmsDbContext, CmsUUID, org.opencms.file.CmsResource)
*/
public void removeFile(CmsDbContext dbc, CmsUUID projectId, CmsResource resource) throws CmsDataAccessException {
int siblingCount = 0;
try {
// delete the structure record
Query q = m_sqlManager.createQuery(dbc, projectId, C_STRUCTURE_DELETE_BY_STRUCTUREID);
q.setParameter(1, resource.getStructureId().toString());
@SuppressWarnings("unchecked")
List<I_CmsDAOStructure> res = q.getResultList();
for (I_CmsDAOStructure ps : res) {
m_sqlManager.remove(dbc, ps);
}
// count the references to the resource
siblingCount = countSiblings(dbc, projectId, resource.getResourceId());
if (siblingCount > 0) {
// update the link Count
q = m_sqlManager.createQuery(dbc, projectId, C_RESOURCES_UPDATE_SIBLING_COUNT);
q.setParameter(1, resource.getResourceId().toString());
@SuppressWarnings("unchecked")
List<I_CmsDAOResources> ress = q.getResultList();
for (I_CmsDAOResources r : ress) {
r.setSiblingCount(siblingCount);
}
// update the resource flags
q = m_sqlManager.createQuery(dbc, projectId, C_RESOURCES_UPDATE_FLAGS);
q.setParameter(1, resource.getResourceId().toString());
@SuppressWarnings("unchecked")
List<I_CmsDAOResources> resf = q.getResultList();
for (I_CmsDAOResources r : resf) {
r.setResourceFlags(resource.getFlags());
}
} else {
// if not referenced any longer, also delete the resource and the content record
q = m_sqlManager.createQuery(dbc, projectId, C_RESOURCES_DELETE_BY_RESOURCEID);
q.setParameter(1, resource.getResourceId().toString());
@SuppressWarnings("unchecked")
List<I_CmsDAOResources> res1 = q.getResultList();
for (I_CmsDAOResources pr : res1) {
m_sqlManager.remove(dbc, pr);
}
boolean dbcHasProjectId = (dbc.getProjectId() != null) && !dbc.getProjectId().isNullUUID();
// if online we have to keep historical content
if (projectId.equals(CmsProject.ONLINE_PROJECT_ID)) {
// put the online content in the history
q = m_sqlManager.createQuery(dbc, C_ONLINE_CONTENTS_HISTORY);
q.setParameter(1, resource.getResourceId().toString());
@SuppressWarnings("unchecked")
List<CmsDAOContents> res2 = q.getResultList();
for (CmsDAOContents c : res2) {
c.setOnlineFlag(0);
}
} else if (dbcHasProjectId) {
// remove current online version
q = m_sqlManager.createQuery(dbc, C_ONLINE_CONTENTS_DELETE);
q.setParameter(1, resource.getResourceId().toString());
q.executeUpdate();
} else {
// delete content records with this resource id
q = m_sqlManager.createQuery(dbc, C_OFFLINE_FILE_CONTENT_DELETE);
q.setParameter(1, resource.getResourceId().toString());
q.executeUpdate();
}
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
}
/**
* @see org.opencms.db.I_CmsVfsDriver#removeFolder(org.opencms.db.CmsDbContext, org.opencms.file.CmsProject, org.opencms.file.CmsResource)
*/
public void removeFolder(CmsDbContext dbc, CmsProject currentProject, CmsResource resource)
throws CmsDataAccessException {
if ((dbc.getRequestContext() != null)
&& (dbc.getRequestContext().getAttribute(REQ_ATTR_CHECK_PERMISSIONS) != null)) {
// only check write permissions
checkWritePermissionsInFolder(dbc, resource);
return;
}
// check if the folder has any resources in it
Iterator<CmsResource> childResources = readChildResources(dbc, currentProject, resource, true, true).iterator();
CmsUUID projectId = CmsProject.ONLINE_PROJECT_ID;
if (currentProject.isOnlineProject()) {
projectId = CmsUUID.getOpenCmsUUID(); // HACK: to get an offline project id
}
// collect the names of the resources inside the folder, excluding the moved resources
StringBuffer errorResNames = new StringBuffer(128);
while (childResources.hasNext()) {
CmsResource errorRes = childResources.next();
// if deleting offline, or not moved, or just renamed inside the deleted folder
// so, it may remain some orphan online entries for moved resources
// which will be fixed during the publishing of the moved resources
boolean error = !currentProject.isOnlineProject();
if (!error) {
try {
String originalPath = m_driverManager.getVfsDriver().readResource(
dbc,
projectId,
errorRes.getRootPath(),
true).getRootPath();
error = originalPath.equals(errorRes.getRootPath())
|| originalPath.startsWith(resource.getRootPath());
} catch (CmsVfsResourceNotFoundException e) {
// ignore
}
}
if (error) {
if (errorResNames.length() != 0) {
errorResNames.append(", ");
}
errorResNames.append("[" + dbc.removeSiteRoot(errorRes.getRootPath()) + "]");
}
}
// the current implementation only deletes empty folders
if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(errorResNames.toString())) {
throw new CmsVfsException(Messages.get().container(
Messages.ERR_DELETE_NONEMTY_FOLDER_2,
dbc.removeSiteRoot(resource.getRootPath()),
errorResNames.toString()));
}
internalRemoveFolder(dbc, currentProject, resource);
// remove project resources
String deletedResourceRootPath = resource.getRootPath();
if (dbc.getRequestContext() != null) {
dbc.getRequestContext().setAttribute(CmsProjectDriver.DBC_ATTR_READ_PROJECT_FOR_RESOURCE, Boolean.TRUE);
I_CmsProjectDriver projectDriver = m_driverManager.getProjectDriver(dbc);
Iterator<CmsProject> itProjects = projectDriver.readProjects(dbc, deletedResourceRootPath).iterator();
while (itProjects.hasNext()) {
CmsProject project = itProjects.next();
projectDriver.deleteProjectResource(dbc, project.getUuid(), deletedResourceRootPath);
}
}
}
/**
* @see org.opencms.db.I_CmsVfsDriver#replaceResource(org.opencms.db.CmsDbContext, org.opencms.file.CmsResource, byte[], int)
*/
public void replaceResource(CmsDbContext dbc, CmsResource newResource, byte[] resContent, int newResourceType)
throws CmsDataAccessException {
if (resContent == null) {
// nothing to do
return;
}
try {
// write the file content
writeContent(dbc, newResource.getResourceId(), resContent);
// update the resource record
Query q = m_sqlManager.createQuery(dbc, dbc.currentProject(), C_RESOURCE_REPLACE);
q.setParameter(1, newResource.getResourceId().toString());
@SuppressWarnings("unchecked")
List<I_CmsDAOResources> res = q.getResultList();
for (I_CmsDAOResources r : res) {
r.setResourceType(newResourceType);
r.setResourceSize(resContent.length);
r.setDateContent(System.currentTimeMillis());
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
}
/**
* @see org.opencms.db.I_CmsVfsDriver#setDriverManager(org.opencms.db.CmsDriverManager)
*/
public void setDriverManager(CmsDriverManager driverManager) {
m_driverManager = driverManager;
}
/**
* @see org.opencms.db.I_CmsVfsDriver#setSqlManager(org.opencms.db.CmsSqlManager)
*/
public void setSqlManager(org.opencms.db.CmsSqlManager sqlManager) {
m_sqlManager = (CmsSqlManager)sqlManager;
}
/**
* @see org.opencms.db.I_CmsVfsDriver#transferResource(org.opencms.db.CmsDbContext, org.opencms.file.CmsProject, org.opencms.file.CmsResource, org.opencms.util.CmsUUID, org.opencms.util.CmsUUID)
*/
public void transferResource(
CmsDbContext dbc,
CmsProject project,
CmsResource resource,
CmsUUID createdUser,
CmsUUID lastModifiedUser) throws CmsDataAccessException {
if (createdUser == null) {
createdUser = resource.getUserCreated();
}
if (lastModifiedUser == null) {
lastModifiedUser = resource.getUserLastModified();
}
try {
Query q = m_sqlManager.createQuery(dbc, project, C_RESOURCES_TRANSFER_RESOURCE);
q.setParameter(1, resource.getResourceId().toString());
@SuppressWarnings("unchecked")
List<I_CmsDAOResources> res = q.getResultList();
for (I_CmsDAOResources r : res) {
r.setUserCreated(createdUser.toString());
r.setUserLastModified(lastModifiedUser.toString());
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
}
/**
* @see org.opencms.db.I_CmsVfsDriver#updateRelations(CmsDbContext, CmsProject, CmsResource)
*/
public void updateRelations(CmsDbContext dbc, CmsProject onlineProject, CmsResource offlineResource)
throws CmsDataAccessException {
// delete online relations
I_CmsVfsDriver vfsDriver = m_driverManager.getVfsDriver(dbc);
vfsDriver.deleteRelations(dbc, onlineProject.getUuid(), offlineResource, CmsRelationFilter.TARGETS);
CmsUUID projectId;
if (!dbc.getProjectId().isNullUUID()) {
projectId = CmsProject.ONLINE_PROJECT_ID;
} else {
projectId = dbc.currentProject().getUuid();
}
// copy offline to online relations
CmsUUID dbcProjectId = dbc.getProjectId();
dbc.setProjectId(CmsUUID.getNullUUID());
Iterator<CmsRelation> itRelations = m_driverManager.getVfsDriver(dbc).readRelations(
dbc,
projectId,
offlineResource,
CmsRelationFilter.TARGETS).iterator();
dbc.setProjectId(dbcProjectId);
while (itRelations.hasNext()) {
vfsDriver.createRelation(dbc, onlineProject.getUuid(), itRelations.next());
}
}
/**
* @see org.opencms.db.I_CmsVfsDriver#validateResourceIdExists(org.opencms.db.CmsDbContext, CmsUUID, org.opencms.util.CmsUUID)
*/
public boolean validateResourceIdExists(CmsDbContext dbc, CmsUUID projectId, CmsUUID resourceId)
throws CmsDataAccessException {
boolean exists = false;
try {
Query q = m_sqlManager.createQuery(dbc, projectId, C_RESOURCES_READ_RESOURCE_STATE);
q.setParameter(1, resourceId.toString());
try {
@SuppressWarnings("unused")
int state = CmsDataTypeUtil.numberToInt((Number)q.getSingleResult());
exists = true;
} catch (NoResultException e) {
// do nothing
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
return exists;
}
/**
* @see org.opencms.db.I_CmsVfsDriver#validateStructureIdExists(org.opencms.db.CmsDbContext, CmsUUID, org.opencms.util.CmsUUID)
*/
public boolean validateStructureIdExists(CmsDbContext dbc, CmsUUID projectId, CmsUUID structureId)
throws CmsDataAccessException {
boolean found = false;
int count = 0;
try {
Query q = m_sqlManager.createQuery(dbc, projectId, C_RESOURCES_SELECT_STRUCTURE_ID);
q.setParameter(1, structureId.toString());
try {
count = CmsDataTypeUtil.numberToInt((Number)q.getSingleResult());
found = (count == 1);
} catch (NoResultException e) {
// do nothing
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
return found;
}
/**
* @see org.opencms.db.I_CmsVfsDriver#writeContent(org.opencms.db.CmsDbContext, org.opencms.util.CmsUUID, byte[])
*/
public void writeContent(CmsDbContext dbc, CmsUUID resourceId, byte[] content) throws CmsDataAccessException {
try {
Query q = m_sqlManager.createQuery(dbc, dbc.currentProject(), C_OFFLINE_CONTENTS_UPDATE);
// update the file content in the database.
q.setParameter(1, resourceId.toString());
@SuppressWarnings("unchecked")
List<CmsDAOOfflineContents> res = q.getResultList();
for (CmsDAOOfflineContents oc : res) {
oc.setFileContent(content);
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
}
/**
* @see org.opencms.db.I_CmsVfsDriver#writeLastModifiedProjectId(org.opencms.db.CmsDbContext, org.opencms.file.CmsProject, CmsUUID, org.opencms.file.CmsResource)
*/
public void writeLastModifiedProjectId(CmsDbContext dbc, CmsProject project, CmsUUID projectId, CmsResource resource)
throws CmsDataAccessException {
try {
Query q = m_sqlManager.createQuery(dbc, project, C_RESOURCES_UPDATE_PROJECT_LASTMODIFIED);
q.setParameter(1, resource.getResourceId().toString());
@SuppressWarnings("unchecked")
List<I_CmsDAOResources> res = q.getResultList();
for (I_CmsDAOResources r : res) {
r.setProjectLastModified(projectId.toString());
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
}
/**
* @see org.opencms.db.I_CmsVfsDriver#writePropertyObject(org.opencms.db.CmsDbContext, org.opencms.file.CmsProject, org.opencms.file.CmsResource, org.opencms.file.CmsProperty)
*/
public void writePropertyObject(CmsDbContext dbc, CmsProject project, CmsResource resource, CmsProperty property)
throws CmsDataAccessException {
CmsUUID projectId = ((dbc.getProjectId() == null) || dbc.getProjectId().isNullUUID())
? project.getUuid()
: dbc.getProjectId();
// TODO: check if we need autocreation for link property definition types too
CmsPropertyDefinition propertyDefinition = null;
try {
// read the property definition
propertyDefinition = readPropertyDefinition(dbc, property.getName(), projectId);
} catch (CmsDbEntryNotFoundException e) {
if (property.autoCreatePropertyDefinition()) {
propertyDefinition = createPropertyDefinition(
dbc,
projectId,
property.getName(),
CmsPropertyDefinition.TYPE_NORMAL);
try {
readPropertyDefinition(dbc, property.getName(), CmsProject.ONLINE_PROJECT_ID);
} catch (CmsDataAccessException e1) {
createPropertyDefinition(
dbc,
CmsProject.ONLINE_PROJECT_ID,
property.getName(),
CmsPropertyDefinition.TYPE_NORMAL);
}
try {
m_driverManager.getHistoryDriver(dbc).readPropertyDefinition(dbc, property.getName());
} catch (CmsDataAccessException e1) {
m_driverManager.getHistoryDriver(dbc).createPropertyDefinition(
dbc,
property.getName(),
CmsPropertyDefinition.TYPE_NORMAL);
}
OpenCms.fireCmsEvent(new CmsEvent(
I_CmsEventListener.EVENT_PROPERTY_DEFINITION_CREATED,
Collections.<String, Object> singletonMap("propertyDefinition", propertyDefinition)));
} else {
throw new CmsDbEntryNotFoundException(Messages.get().container(
Messages.ERR_NO_PROPERTYDEF_WITH_NAME_1,
property.getName()));
}
}
try {
// read the existing property to test if we need the
// insert or update query to write a property value
CmsProperty existingProperty = readPropertyObject(dbc, propertyDefinition.getName(), project, resource);
if (existingProperty.isIdentical(property)) {
// property already has the identical values set, no write required
return;
}
for (int i = 0; i < 2; i++) {
int mappingType = -1;
String value = null;
CmsUUID id = null;
boolean existsPropertyValue = false;
boolean deletePropertyValue = false;
// 1) take any required decisions to choose and fill the correct SQL query
if (i == 0) {
// write/delete the *structure value* on the first cycle
if ((existingProperty.getStructureValue() != null) && property.isDeleteStructureValue()) {
// this property value is marked to be deleted
deletePropertyValue = true;
} else {
value = property.getStructureValue();
if (CmsStringUtil.isEmptyOrWhitespaceOnly(value)) {
// no structure value set or the structure value is an empty string,
// continue with the resource value
continue;
}
}
// set the vars to be written to the database
mappingType = CmsProperty.STRUCTURE_RECORD_MAPPING;
id = resource.getStructureId();
existsPropertyValue = existingProperty.getStructureValue() != null;
} else {
// write/delete the *resource value* on the second cycle
if ((existingProperty.getResourceValue() != null) && property.isDeleteResourceValue()) {
// this property value is marked to be deleted
deletePropertyValue = true;
} else {
value = property.getResourceValue();
if (CmsStringUtil.isEmptyOrWhitespaceOnly(value)) {
// no resource value set or the resource value is an empty string,
// break out of the loop
break;
}
}
// set the vars to be written to the database
mappingType = CmsProperty.RESOURCE_RECORD_MAPPING;
id = resource.getResourceId();
existsPropertyValue = existingProperty.getResourceValue() != null;
}
// 2) execute the SQL query
Query q;
if (!deletePropertyValue) {
// insert/update the property value
if (existsPropertyValue) {
// {structure|resource} property value already exists- use update statement
q = m_sqlManager.createQuery(dbc, projectId, C_PROPERTIES_UPDATE);
q.setParameter(1, id.toString());
q.setParameter(2, Integer.valueOf(mappingType));
q.setParameter(3, propertyDefinition.getId().toString());
@SuppressWarnings("unchecked")
List<I_CmsDAOProperties> res = q.getResultList();
for (I_CmsDAOProperties p : res) {
p.setPropertyValue(m_sqlManager.validateEmpty(value));
}
} else {
// {structure|resource} property value doesn't exist- use create statement
I_CmsDAOProperties p = CmsProject.isOnlineProject(project.getUuid())
? new CmsDAOOnlineProperties()
: new CmsDAOOfflineProperties();
p.setPropertyId(new CmsUUID().toString());
p.setPropertyDefId(propertyDefinition.getId().toString());
p.setPropertyMappingId(id.toString());
p.setPropertyMappingType(mappingType);
p.setPropertyValue(m_sqlManager.validateEmpty(value));
m_sqlManager.persist(dbc, p);
}
} else {
// {structure|resource} property value marked as deleted- use delete statement
q = m_sqlManager.createQuery(dbc, projectId, C_PROPERTIES_DELETE);
q.setParameter(1, propertyDefinition.getId().toString());
q.setParameter(2, id.toString());
q.setParameter(3, Integer.valueOf(mappingType));
@SuppressWarnings("unchecked")
List<I_CmsDAOProperties> res = q.getResultList();
for (I_CmsDAOProperties pr : res) {
m_sqlManager.remove(dbc, pr);
}
}
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
}
/**
* @see org.opencms.db.I_CmsVfsDriver#writePropertyObjects(org.opencms.db.CmsDbContext, org.opencms.file.CmsProject, org.opencms.file.CmsResource, java.util.List)
*/
public void writePropertyObjects(
CmsDbContext dbc,
CmsProject project,
CmsResource resource,
List<CmsProperty> properties) throws CmsDataAccessException {
for (CmsProperty property : properties) {
writePropertyObject(dbc, project, resource, property);
}
}
/**
* @see org.opencms.db.I_CmsVfsDriver#writeResource(org.opencms.db.CmsDbContext, CmsUUID, org.opencms.file.CmsResource, int)
*/
public void writeResource(CmsDbContext dbc, CmsUUID projectId, CmsResource resource, int changed)
throws CmsDataAccessException {
// validate the resource length
internalValidateResourceLength(resource);
String resourcePath = CmsFileUtil.removeTrailingSeparator(resource.getRootPath());
// this task is split into two statements because some DBs (e.g. Oracle) doesn't support multi-table updates
long resourceDateModified;
if (resource.isTouched()) {
resourceDateModified = resource.getDateLastModified();
} else {
resourceDateModified = System.currentTimeMillis();
}
CmsResourceState structureState = resource.getState();
CmsResourceState resourceState = resource.getState();
CmsResourceState structureStateOld = internalReadStructureState(dbc, projectId, resource);
CmsResourceState resourceStateOld = internalReadResourceState(dbc, projectId, resource);
CmsUUID projectLastModified = projectId;
if (changed == CmsDriverManager.UPDATE_RESOURCE_STATE) {
resourceState = resourceStateOld;
resourceState = (resourceState.isNew() ? CmsResource.STATE_NEW : CmsResource.STATE_CHANGED);
structureState = structureStateOld;
} else if (changed == CmsDriverManager.UPDATE_STRUCTURE_STATE) {
structureState = structureStateOld;
structureState = (structureState.isNew() ? CmsResource.STATE_NEW : CmsResource.STATE_CHANGED);
} else if (changed == CmsDriverManager.NOTHING_CHANGED) {
projectLastModified = resource.getProjectLastModified();
} else {
resourceState = resourceStateOld;
resourceState = (resourceState.isNew() ? CmsResource.STATE_NEW : CmsResource.STATE_CHANGED);
structureState = structureStateOld;
structureState = (structureState.isNew() ? CmsResource.STATE_NEW : CmsResource.STATE_CHANGED);
}
try {
Query q;
if (changed != CmsDriverManager.UPDATE_STRUCTURE_STATE) {
// if the resource was unchanged
q = m_sqlManager.createQuery(dbc, projectId, C_RESOURCES_UPDATE_RESOURCES);
q.setParameter(1, resource.getResourceId().toString());
@SuppressWarnings("unchecked")
List<I_CmsDAOResources> res = q.getResultList();
for (I_CmsDAOResources r : res) {
r.setResourceType(resource.getTypeId());
r.setResourceFlags(resource.getFlags());
r.setDateLastModified(resourceDateModified);
r.setUserLastModified(resource.getUserLastModified().toString());
r.setResourceState(resourceState.getState());
r.setResourceSize(resource.getLength());
r.setDateContent(resource.getDateContent());
r.setProjectLastModified(projectLastModified.toString());
r.setSiblingCount(countSiblings(dbc, projectId, resource.getResourceId()));
}
} else {
q = m_sqlManager.createQuery(dbc, projectId, C_RESOURCES_UPDATE_RESOURCES_WITHOUT_STATE);
q.setParameter(1, resource.getResourceId().toString());
@SuppressWarnings("unchecked")
List<I_CmsDAOResources> res = q.getResultList();
for (I_CmsDAOResources r : res) {
r.setResourceType(resource.getTypeId());
r.setResourceFlags(resource.getFlags());
r.setDateLastModified(resourceDateModified);
r.setUserLastModified(resource.getUserLastModified().toString());
r.setResourceSize(resource.getLength());
r.setDateContent(resource.getDateContent());
r.setProjectLastModified(projectLastModified.toString());
r.setSiblingCount(countSiblings(dbc, projectId, resource.getResourceId()));
}
}
// read the parent id
String parentId = internalReadParentId(dbc, projectId, resourcePath);
// update the structure
q = m_sqlManager.createQuery(dbc, projectId, C_RESOURCES_UPDATE_STRUCTURE);
q.setParameter(1, resource.getStructureId().toString());
@SuppressWarnings("unchecked")
List<I_CmsDAOStructure> res = q.getResultList();
for (I_CmsDAOStructure s : res) {
s.setResourceId(resource.getResourceId().toString());
s.setResourcePath(resourcePath);
s.setStructureState(structureState.getState());
s.setDateReleased(resource.getDateReleased());
s.setDateExpired(resource.getDateExpired());
s.setParentId(parentId);
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
}
/**
* @see org.opencms.db.I_CmsVfsDriver#writeResourceState(org.opencms.db.CmsDbContext, org.opencms.file.CmsProject, org.opencms.file.CmsResource, int, boolean)
*/
public void writeResourceState(
CmsDbContext dbc,
CmsProject project,
CmsResource resource,
int changed,
boolean isPublishing) throws CmsDataAccessException {
if (project.getUuid().equals(CmsProject.ONLINE_PROJECT_ID)) {
return;
}
try {
Query q;
if (changed == CmsDriverManager.UPDATE_RESOURCE_PROJECT) {
q = m_sqlManager.createQuery(dbc, project, C_RESOURCES_UPDATE_RESOURCE_PROJECT);
q.setParameter(1, resource.getResourceId().toString());
@SuppressWarnings("unchecked")
List<I_CmsDAOResources> resr = q.getResultList();
for (I_CmsDAOResources r : resr) {
r.setResourceFlags(resource.getFlags());
r.setProjectLastModified(project.getUuid().toString());
}
}
if (changed == CmsDriverManager.UPDATE_RESOURCE) {
q = m_sqlManager.createQuery(dbc, project, C_RESOURCES_UPDATE_RESOURCE_STATELASTMODIFIED);
q.setParameter(1, resource.getResourceId().toString());
@SuppressWarnings("unchecked")
List<I_CmsDAOResources> res = q.getResultList();
for (I_CmsDAOResources r : res) {
r.setResourceState(resource.getState().getState());
r.setDateLastModified(resource.getDateLastModified());
r.setUserLastModified(resource.getUserLastModified().toString());
r.setProjectLastModified(project.getUuid().toString());
}
}
if ((changed == CmsDriverManager.UPDATE_RESOURCE_STATE) || (changed == CmsDriverManager.UPDATE_ALL)) {
q = m_sqlManager.createQuery(dbc, project, C_RESOURCES_UPDATE_RESOURCE_STATE);
q.setParameter(1, resource.getResourceId().toString());
@SuppressWarnings("unchecked")
List<I_CmsDAOResources> res = q.getResultList();
for (I_CmsDAOResources r : res) {
r.setResourceState(resource.getState().getState());
r.setProjectLastModified(project.getUuid().toString());
}
}
if ((changed == CmsDriverManager.UPDATE_STRUCTURE)
|| (changed == CmsDriverManager.UPDATE_ALL)
|| (changed == CmsDriverManager.UPDATE_STRUCTURE_STATE)) {
q = m_sqlManager.createQuery(dbc, project, C_RESOURCES_UPDATE_STRUCTURE_STATE);
q.setParameter(1, resource.getStructureId().toString());
@SuppressWarnings("unchecked")
List<I_CmsDAOStructure> res = q.getResultList();
for (I_CmsDAOStructure s : res) {
s.setStructureState(resource.getState().getState());
}
}
if ((changed == CmsDriverManager.UPDATE_STRUCTURE) || (changed == CmsDriverManager.UPDATE_ALL)) {
q = m_sqlManager.createQuery(dbc, project, C_RESOURCES_UPDATE_RELEASE_EXPIRED);
q.setParameter(1, resource.getStructureId().toString());
@SuppressWarnings("unchecked")
List<I_CmsDAOStructure> res = q.getResultList();
for (I_CmsDAOStructure s : res) {
s.setDateReleased(resource.getDateReleased());
s.setDateExpired(resource.getDateExpired());
}
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
if (isPublishing) {
internalUpdateVersions(dbc, resource);
}
}
/**
* Checks that the current user has write permissions for all subresources of the given folder.<p>
*
* @param dbc the current database context
* @param folder the folder to check
*
* @throws CmsDataAccessException if something goes wrong
*/
protected void checkWritePermissionsInFolder(CmsDbContext dbc, CmsResource folder) throws CmsDataAccessException {
CmsUUID projectId = dbc.getRequestContext().getCurrentProject().getUuid();
// first read all subresources with ACEs
List<CmsResource> resources = new ArrayList<CmsResource>();
try {
Query q = m_sqlManager.createQuery(dbc, projectId, C_RESOURCES_READ_WITH_ACE_1);
q.setParameter(1, escapeDbWildcard(folder.getRootPath() + "%"));
@SuppressWarnings("unchecked")
List<Object[]> res = q.getResultList();
for (Object[] o : res) {
resources.add(createResource(o, projectId));
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
// check current user write permission for each of these resources
Iterator<CmsResource> itResources = resources.iterator();
while (itResources.hasNext()) {
CmsResource resource = itResources.next();
try {
m_driverManager.getSecurityManager().checkPermissions(
dbc.getRequestContext(),
resource,
CmsPermissionSet.ACCESS_WRITE,
false,
CmsResourceFilter.ALL);
} catch (CmsException e) {
throw new CmsDataAccessException(e.getMessageContainer(), e);
}
}
// then check for possible jsp pages without permissions
CmsResourceFilter filter = CmsResourceFilter.ALL;
itResources = readTypesInResourceTree(
dbc,
projectId,
folder.getRootPath(),
CmsResourceTypeJsp.getJspResourceTypeIds(),
filter.getState(),
filter.getModifiedAfter(),
filter.getModifiedBefore(),
filter.getReleaseAfter(),
filter.getReleaseBefore(),
filter.getExpireAfter(),
filter.getExpireBefore(),
CmsDriverManager.READMODE_INCLUDE_TREE).iterator();
while (itResources.hasNext()) {
CmsResource resource = itResources.next();
try {
m_driverManager.getSecurityManager().checkPermissions(
dbc.getRequestContext(),
resource,
CmsPermissionSet.ACCESS_WRITE,
false,
CmsResourceFilter.ALL);
} catch (CmsException e) {
throw new CmsDataAccessException(e.getMessageContainer(), e);
}
}
}
/**
* Returns the count of properties for a property definition.<p>
*
* @param dbc the current database context
* @param propertyDefinition the property definition to test
* @param projectId the ID of the current project
*
* @return the amount of properties for a property definition
* @throws CmsDataAccessException if something goes wrong
*/
protected int internalCountProperties(CmsDbContext dbc, CmsPropertyDefinition propertyDefinition, CmsUUID projectId)
throws CmsDataAccessException {
int count = 0;
try {
// create statement
Query q = m_sqlManager.createQuery(dbc, projectId, C_PROPERTIES_READALL_COUNT);
q.setParameter(1, propertyDefinition.getId().toString());
try {
count = CmsDataTypeUtil.numberToInt((Number)q.getSingleResult());
} catch (NoResultException e) {
throw new CmsDbConsistencyException(Messages.get().container(
Messages.ERR_COUNTING_PROPERTIES_1,
propertyDefinition.getName()));
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
return count;
}
/**
* Creates an URL name mapping entry from a result set.<p>
*
* @param m a I_CmsDAOUrlNameMappings
* @return the URL name mapping entry created from the result set
*
*/
protected CmsUrlNameMappingEntry internalCreateUrlNameMappingEntry(I_CmsDAOUrlNameMappings m) {
String name = m.getName();
CmsUUID structureId = new CmsUUID(m.getStructureId());
int state = m.getState();
long dateChanged = m.getDateChanged();
String locale = m.getLocale();
return new CmsUrlNameMappingEntry(name, structureId, state, dateChanged, locale);
}
/**
* Returns the parent id of the given resource.<p>
*
* @param dbc the current database context
* @param projectId the current project id
* @param resourcename the resource name to read the parent id for
*
* @return the parent id of the given resource
*
* @throws CmsDataAccessException if something goes wrong
*/
protected String internalReadParentId(CmsDbContext dbc, CmsUUID projectId, String resourcename)
throws CmsDataAccessException {
if ("/".equalsIgnoreCase(resourcename)) {
return CmsUUID.getNullUUID().toString();
}
String parent = CmsResource.getParentFolder(resourcename);
parent = CmsFileUtil.removeTrailingSeparator(parent);
String parentId = null;
try {
Query q = m_sqlManager.createQuery(dbc, projectId, C_RESOURCES_READ_PARENT_STRUCTURE_ID);
q.setParameter(1, parent);
try {
parentId = (String)q.getSingleResult();
} catch (NoResultException e) {
throw new CmsVfsResourceNotFoundException(Messages.get().container(
Messages.ERR_READ_PARENT_ID_1,
dbc.removeSiteRoot(resourcename)));
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
return parentId;
}
/**
* Creates a new {@link CmsRelation} object from the given result set entry.<p>
*
* @param rr the resource relation
*
* @return the new {@link CmsRelation} object
*/
protected CmsRelation internalReadRelation(I_CmsDAOResourceRelations rr) {
CmsUUID sourceId = new CmsUUID(rr.getRelationSourceId());
String sourcePath = rr.getRelationSourcePath();
CmsUUID targetId = new CmsUUID(rr.getRelationTargetId());
String targetPath = rr.getRelationTargetPath();
int type = rr.getRelationType();
return new CmsRelation(sourceId, sourcePath, targetId, targetPath, CmsRelationType.valueOf(type));
}
/**
* Returns the resource state of the given resource.<p>
*
* @param dbc the database context
* @param projectId the id of the project
* @param resource the resource to read the resource state for
*
* @return the resource state of the given resource
*
* @throws CmsDataAccessException if something goes wrong
*/
protected CmsResourceState internalReadResourceState(CmsDbContext dbc, CmsUUID projectId, CmsResource resource)
throws CmsDataAccessException {
CmsResourceState state = CmsResource.STATE_KEEP;
try {
Query q = m_sqlManager.createQuery(dbc, projectId, C_READ_RESOURCE_STATE);
q.setParameter(1, resource.getResourceId().toString());
try {
state = CmsResourceState.valueOf(CmsDataTypeUtil.numberToInt((Number)q.getSingleResult()));
} catch (NoResultException e) {
// do nothing
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
return state;
}
/**
* Returns the structure state of the given resource.<p>
*
* @param dbc the database context
* @param projectId the id of the project
* @param resource the resource to read the structure state for
*
* @return the structure state of the given resource
*
* @throws CmsDataAccessException if something goes wrong
*/
protected CmsResourceState internalReadStructureState(CmsDbContext dbc, CmsUUID projectId, CmsResource resource)
throws CmsDataAccessException {
CmsResourceState state = CmsResource.STATE_KEEP;
try {
Query q = m_sqlManager.createQuery(dbc, projectId, C_READ_STRUCTURE_STATE);
q.setParameter(1, resource.getStructureId().toString());
try {
state = CmsResourceState.valueOf(CmsDataTypeUtil.numberToInt((Number)q.getSingleResult()));
} catch (NoResultException e) {
// do nothing
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
return state;
}
/**
* Removes a resource physically in the database.<p>
*
* @param dbc the current database context
* @param currentProject the current project
* @param resource the folder to remove
*
* @throws CmsDataAccessException if something goes wrong
*/
protected void internalRemoveFolder(CmsDbContext dbc, CmsProject currentProject, CmsResource resource)
throws CmsDataAccessException {
try {
// delete the structure record
Query q = m_sqlManager.createQuery(dbc, currentProject, C_STRUCTURE_DELETE_BY_STRUCTUREID);
q.setParameter(1, resource.getStructureId().toString());
I_CmsDAOStructure s = (I_CmsDAOStructure)q.getSingleResult();
m_sqlManager.remove(dbc, s);
// delete the resource record
q = m_sqlManager.createQuery(dbc, currentProject, C_RESOURCES_DELETE_BY_RESOURCEID);
q.setParameter(1, resource.getResourceId().toString());
I_CmsDAOResources r = (I_CmsDAOResources)q.getSingleResult();
m_sqlManager.remove(dbc, r);
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
}
/**
* Postprocess C_READ_RESOURCE_OUS query, because some databases
* do not support indexOf function.
*
* @param set - result of C_READ_RESOURCE_OUS query
* @param resName - string for comparison
*
* @return - the result of original C_READ_RESOURCE_OUS query
*/
protected List<I_CmsDAOResourceRelations> internalResourceOus(List<I_CmsDAOResourceRelations> set, String resName) {
List<I_CmsDAOResourceRelations> result = new ArrayList<I_CmsDAOResourceRelations>();
if (resName == null) {
return result;
}
for (I_CmsDAOResourceRelations rr : set) {
if ((rr.getRelationTargetPath() != null) && (resName.indexOf(rr.getRelationTargetPath()) != -1)) {
result.add(rr);
}
}
return result;
}
/**
* Updates the offline version numbers.<p>
*
* @param dbc the current database context
* @param resource the resource to update the version number for
*
* @throws CmsDataAccessException if something goes wrong
*/
protected void internalUpdateVersions(CmsDbContext dbc, CmsResource resource) throws CmsDataAccessException {
if (dbc.getRequestContext() == null) {
// no needed during initialization
return;
}
if (dbc.currentProject().isOnlineProject()) {
// this method is supposed to be used only in the offline project
return;
}
// read the online version numbers
Map<String, Integer> onlineVersions = readVersions(
dbc,
CmsProject.ONLINE_PROJECT_ID,
resource.getResourceId(),
resource.getStructureId());
int onlineStructureVersion = onlineVersions.get("structure").intValue();
int onlineResourceVersion = onlineVersions.get("resource").intValue();
try {
// update the resource version
Query q = m_sqlManager.createQuery(dbc, dbc.currentProject(), C_RESOURCES_UPDATE_RESOURCE_VERSION);
q.setParameter(1, resource.getResourceId().toString());
@SuppressWarnings("unchecked")
List<I_CmsDAOResources> res = q.getResultList();
for (I_CmsDAOResources r : res) {
r.setResourceVersion(onlineResourceVersion);
}
// update the structure version
q = m_sqlManager.createQuery(dbc, dbc.currentProject(), C_RESOURCES_UPDATE_STRUCTURE_VERSION);
q.setParameter(1, resource.getStructureId().toString());
@SuppressWarnings("unchecked")
List<I_CmsDAOStructure> ress = q.getResultList();
for (I_CmsDAOStructure s : ress) {
s.setStructureVersion(onlineStructureVersion);
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
}
/**
* Validates that the length setting of a resource is always correct.<p>
*
* Files need to have a resource length of >= 0, while folders require
* a resource length of -1.<p>
*
* @param resource the resource to check the length for
*
* @throws CmsDataAccessException if something goes wrong
*/
protected void internalValidateResourceLength(CmsResource resource) throws CmsDataAccessException {
if (resource.isFolder() && (resource.getLength() == -1)) {
return;
}
if (resource.isFile() && (resource.getLength() >= 0)) {
return;
}
throw new CmsDataAccessException(Messages.get().container(
Messages.ERR_INVALID_RESOURCE_LENGTH_2,
new Integer(resource.getLength()),
resource.getRootPath()));
}
/**
* Moves all relations of a resource to the new path.<p>
*
* @param dbc the current database context
* @param projectId the id of the project to apply the changes
* @param structureId the structure id of the resource to apply the changes to
* @param rootPath the new root path
*
* @throws CmsDataAccessException if something goes wrong
*/
protected void moveRelations(CmsDbContext dbc, CmsUUID projectId, CmsUUID structureId, String rootPath)
throws CmsDataAccessException {
try {
Query q = m_sqlManager.createQuery(dbc, projectId, C_MOVE_RELATIONS_SOURCE);
q.setParameter(1, structureId.toString());
@SuppressWarnings("unchecked")
List<I_CmsDAOResourceRelations> res = q.getResultList();
I_CmsDAOResourceRelations newR;
for (I_CmsDAOResourceRelations rr : res) {
newR = CmsProject.isOnlineProject(projectId)
? new CmsDAOOnlineResourceRelations()
: new CmsDAOOfflineResourceRelations();
newR.setRelationSourceId(rr.getRelationSourceId());
newR.setRelationSourcePath(rootPath);
newR.setRelationTargetId(rr.getRelationTargetId());
newR.setRelationTargetPath(rr.getRelationTargetPath());
newR.setRelationType(rr.getRelationType());
m_sqlManager.remove(dbc, rr);
m_sqlManager.persist(dbc, newR);
}
q = m_sqlManager.createQuery(dbc, projectId, C_MOVE_RELATIONS_TARGET);
q.setParameter(1, structureId.toString());
@SuppressWarnings("unchecked")
List<I_CmsDAOResourceRelations> res1 = q.getResultList();
for (I_CmsDAOResourceRelations rr : res1) {
newR = CmsProject.isOnlineProject(projectId)
? new CmsDAOOnlineResourceRelations()
: new CmsDAOOfflineResourceRelations();
newR.setRelationSourceId(rr.getRelationSourceId());
newR.setRelationSourcePath(rr.getRelationSourcePath());
newR.setRelationTargetId(rr.getRelationTargetId());
newR.setRelationTargetPath(rootPath);
newR.setRelationType(rr.getRelationType());
m_sqlManager.remove(dbc, rr);
m_sqlManager.persist(dbc, newR);
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
}
/**
* Appends the appropriate selection criteria related with the expiration date.<p>
*
* @param projectId the id of the project of the resources
* @param startTime the start time
* @param endTime the end time
* @param conditions buffer to append the selection criteria
* @param params list to append the selection parameters
*/
protected void prepareExpiredTimeRangeCondition(
CmsUUID projectId,
long startTime,
long endTime,
StringBuffer conditions,
List params) {
if (startTime > 0L) {
// READ_IGNORE_TIME: if NOT set, add condition to match expired date against startTime
conditions.append(BEGIN_INCLUDE_CONDITION);
conditions.append(m_sqlManager.readQuery(projectId, C_STRUCTURE_SELECT_BY_DATE_EXPIRED_AFTER));
conditions.append(END_CONDITION);
params.add(Long.valueOf(startTime));
}
if (endTime > 0L) {
// READ_IGNORE_TIME: if NOT set, add condition to match expired date against endTime
conditions.append(BEGIN_INCLUDE_CONDITION);
conditions.append(m_sqlManager.readQuery(projectId, C_STRUCTURE_SELECT_BY_DATE_EXPIRED_BEFORE));
conditions.append(END_CONDITION);
params.add(Long.valueOf(endTime));
}
}
/**
* Appends the appropriate selection criteria related with the parentPath.<p>
*
* @param projectId the id of the project of the resources
* @param parent the parent path or UUID (if mode is C_READMODE_EXCLUDE_TREE)
* @param mode the selection mode
* @param conditions buffer to append the selection criteria
* @param params list to append the selection parameters
*/
protected void preparePathCondition(CmsUUID projectId, String parent, int mode, StringBuffer conditions, List params) {
if (parent == CmsDriverManager.READ_IGNORE_PARENT) {
// parent can be ignored
return;
}
if ((mode & CmsDriverManager.READMODE_EXCLUDE_TREE) > 0) {
// only return immediate children - use UUID optimization
conditions.append(BEGIN_INCLUDE_CONDITION);
conditions.append(m_sqlManager.readQuery(projectId, C_RESOURCES_SELECT_BY_PARENT_UUID));
conditions.append(END_CONDITION);
params.add(parent);
return;
}
if ("/".equalsIgnoreCase(parent)) {
// if root folder is parent, no additional condition is needed since all resources match anyway
return;
}
// add condition to read path subtree
conditions.append(BEGIN_INCLUDE_CONDITION);
conditions.append(m_sqlManager.readQuery(projectId, C_RESOURCES_SELECT_BY_PATH_PREFIX));
conditions.append(END_CONDITION);
params.add(CmsFileUtil.addTrailingSeparator(escapeDbWildcard(parent)) + "%");
}
/**
* Appends the appropriate selection criteria related with the projectId.<p>
*
* @param projectId the id of the project of the resources
* @param mode the selection mode
* @param conditions buffer to append the selection criteria
* @param params list to append the selection parameters
*/
protected void prepareProjectCondition(CmsUUID projectId, int mode, StringBuffer conditions, List params) {
if ((mode & CmsDriverManager.READMODE_INCLUDE_PROJECT) > 0) {
// C_READMODE_INCLUDE_PROJECT: add condition to match the PROJECT_ID
conditions.append(BEGIN_INCLUDE_CONDITION);
conditions.append(m_sqlManager.readQuery(projectId, C_RESOURCES_SELECT_BY_PROJECT_LASTMODIFIED));
conditions.append(END_CONDITION);
params.add(String.valueOf(projectId));
}
}
/**
* Build the whole WHERE sql statement part for the given relation filter.<p>
*
* @param projectId the current project id
* @param filter the filter
* @param resource the resource (may be null, if you want to delete all relations for the resource in the filter)
* @param params the parameter values (return parameter)
* @param checkSource if the query is for the source relations
*
* @return the WHERE sql statement part string
*/
protected String prepareRelationConditions(
CmsUUID projectId,
CmsRelationFilter filter,
CmsResource resource,
List params,
boolean checkSource) {
StringBuffer conditions = new StringBuffer(128);
params.clear(); // be sure the parameters list is clear
// source or target filter
if (filter.isSource() || filter.isTarget()) {
// source or target id filter from resource
if (resource != null) {
conditions.append(BEGIN_CONDITION);
if (filter.isSource() && checkSource) {
if (!filter.isIncludeSubresources()) {
conditions.append(m_sqlManager.readQuery(projectId, C_RELATION_FILTER_TARGET_ID));
params.add(resource.getStructureId().toString());
} else {
conditions.append(m_sqlManager.readQuery(projectId, C_RELATION_FILTER_TARGET_PATH));
params.add(resource.getRootPath() + '%');
}
} else if (filter.isTarget() && !checkSource) {
if (!filter.isIncludeSubresources()) {
conditions.append(m_sqlManager.readQuery(projectId, C_RELATION_FILTER_SOURCE_ID));
params.add(resource.getStructureId().toString());
} else {
conditions.append(m_sqlManager.readQuery(projectId, C_RELATION_FILTER_SOURCE_PATH));
params.add(resource.getRootPath() + '%');
}
}
conditions.append(END_CONDITION);
}
// target or source id filter from filter parameter
if (filter.getStructureId() != null) {
if (conditions.length() == 0) {
conditions.append(BEGIN_CONDITION);
} else {
conditions.append(BEGIN_INCLUDE_CONDITION);
}
if (filter.isSource() && checkSource) {
conditions.append(m_sqlManager.readQuery(projectId, C_RELATION_FILTER_SOURCE_ID));
params.add(filter.getStructureId().toString());
} else if (filter.isTarget() && !checkSource) {
conditions.append(m_sqlManager.readQuery(projectId, C_RELATION_FILTER_TARGET_ID));
params.add(filter.getStructureId().toString());
}
conditions.append(END_CONDITION);
}
// target or source path filter from filter parameter
if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(filter.getPath())) {
if (conditions.length() == 0) {
conditions.append(BEGIN_CONDITION);
} else {
conditions.append(BEGIN_INCLUDE_CONDITION);
}
String queryPath = filter.getPath();
if (filter.isIncludeSubresources()) {
queryPath += '%';
}
if (filter.isSource() && checkSource) {
conditions.append(m_sqlManager.readQuery(projectId, C_RELATION_FILTER_SOURCE_PATH));
params.add(queryPath);
} else if (filter.isTarget() && !checkSource) {
conditions.append(m_sqlManager.readQuery(projectId, C_RELATION_FILTER_TARGET_PATH));
params.add(queryPath);
}
conditions.append(END_CONDITION);
}
}
// relation type filter
Set types = filter.getTypes();
if (!types.isEmpty()) {
if (conditions.length() == 0) {
conditions.append(BEGIN_CONDITION);
} else {
conditions.append(BEGIN_INCLUDE_CONDITION);
}
conditions.append(m_sqlManager.readQuery(projectId, C_RELATION_FILTER_TYPE));
conditions.append(BEGIN_CONDITION);
Iterator it = types.iterator();
while (it.hasNext()) {
CmsRelationType type = (CmsRelationType)it.next();
conditions.append("?");
params.add(Integer.valueOf(type.getId()));
if (it.hasNext()) {
conditions.append(", ");
}
}
conditions.append(END_CONDITION);
conditions.append(END_CONDITION);
}
return conditions.toString();
}
/**
* Appends the appropriate selection criteria related with the released date.<p>
*
* @param projectId the id of the project
* @param startTime the start time
* @param endTime the stop time
* @param conditions buffer to append the selection criteria
* @param params list to append the selection parameters
*/
protected void prepareReleasedTimeRangeCondition(
CmsUUID projectId,
long startTime,
long endTime,
StringBuffer conditions,
List params) {
if (startTime > 0L) {
// READ_IGNORE_TIME: if NOT set, add condition to match released date against startTime
conditions.append(BEGIN_INCLUDE_CONDITION);
conditions.append(m_sqlManager.readQuery(projectId, C_STRUCTURE_SELECT_BY_DATE_RELEASED_AFTER));
conditions.append(END_CONDITION);
params.add(Long.valueOf(startTime));
}
if (endTime > 0L) {
// READ_IGNORE_TIME: if NOT set, add condition to match released date against endTime
conditions.append(BEGIN_INCLUDE_CONDITION);
conditions.append(m_sqlManager.readQuery(projectId, C_STRUCTURE_SELECT_BY_DATE_RELEASED_BEFORE));
conditions.append(END_CONDITION);
params.add(Long.valueOf(endTime));
}
}
/**
* Appends the appropriate selection criteria related with the read mode.<p>
*
* @param projectId the id of the project of the resources
* @param mode the selection mode
* @param conditions buffer to append the selection criteria
*/
protected void prepareResourceCondition(CmsUUID projectId, int mode, StringBuffer conditions) {
if ((mode & CmsDriverManager.READMODE_ONLY_FOLDERS) > 0) {
// C_READMODE_ONLY_FOLDERS: add condition to match only folders
conditions.append(BEGIN_INCLUDE_CONDITION);
conditions.append(m_sqlManager.readQuery(projectId, C_RESOURCES_SELECT_ONLY_FOLDERS));
conditions.append(END_CONDITION);
} else if ((mode & CmsDriverManager.READMODE_ONLY_FILES) > 0) {
// C_READMODE_ONLY_FILES: add condition to match only files
conditions.append(BEGIN_INCLUDE_CONDITION);
conditions.append(m_sqlManager.readQuery(projectId, C_RESOURCES_SELECT_ONLY_FILES));
conditions.append(END_CONDITION);
}
}
/**
* Appends the appropriate selection criteria related with the resource state.<p>
*
* @param projectId the id of the project of the resources
* @param state the resource state
* @param mode the selection mode
* @param conditions buffer to append the selection criteria
* @param params list to append the selection parameters
*/
protected void prepareStateCondition(
CmsUUID projectId,
CmsResourceState state,
int mode,
StringBuffer conditions,
List params) {
if (state != null) {
if ((mode & CmsDriverManager.READMODE_EXCLUDE_STATE) > 0) {
// C_READ_MODIFIED_STATES: add condition to match against any state but not given state
conditions.append(BEGIN_EXCLUDE_CONDITION);
} else {
// otherwise add condition to match against given state if necessary
conditions.append(BEGIN_INCLUDE_CONDITION);
}
conditions.append(m_sqlManager.readQuery(projectId, C_RESOURCES_SELECT_BY_RESOURCE_STATE));
conditions.append(END_CONDITION);
params.add(Integer.valueOf(state.getState()));
params.add(Integer.valueOf(state.getState()));
}
}
/**
* Appends the appropriate selection criteria related with the date of the last modification.<p>
*
* @param projectId the id of the project of the resources
* @param startTime start of the time range
* @param endTime end of the time range
* @param conditions buffer to append the selection criteria
* @param params list to append the selection parameters
*/
protected void prepareTimeRangeCondition(
CmsUUID projectId,
long startTime,
long endTime,
StringBuffer conditions,
List params) {
if (startTime > 0L) {
// READ_IGNORE_TIME: if NOT set, add condition to match last modified date against startTime
conditions.append(BEGIN_INCLUDE_CONDITION);
conditions.append(m_sqlManager.readQuery(projectId, C_RESOURCES_SELECT_BY_DATE_LASTMODIFIED_AFTER));
conditions.append(END_CONDITION);
params.add(Long.valueOf(startTime));
}
if (endTime > 0L) {
// READ_IGNORE_TIME: if NOT set, add condition to match last modified date against endTime
conditions.append(BEGIN_INCLUDE_CONDITION);
conditions.append(m_sqlManager.readQuery(projectId, C_RESOURCES_SELECT_BY_DATE_LASTMODIFIED_BEFORE));
conditions.append(END_CONDITION);
params.add(Long.valueOf(endTime));
}
}
/**
* Appends the appropriate selection criteria related with the resource type.<p>
*
* @param projectId the id of the project of the resources
* @param type the resource type
* @param mode the selection mode
* @param conditions buffer to append the selection criteria
* @param params list to append the selection parameters
*/
protected void prepareTypeCondition(CmsUUID projectId, int type, int mode, StringBuffer conditions, List params) {
if (type != CmsDriverManager.READ_IGNORE_TYPE) {
if ((mode & CmsDriverManager.READMODE_EXCLUDE_TYPE) > 0) {
// C_READ_FILE_TYPES: add condition to match against any type, but not given type
conditions.append(BEGIN_EXCLUDE_CONDITION);
conditions.append(m_sqlManager.readQuery(projectId, C_RESOURCES_SELECT_BY_RESOURCE_TYPE));
conditions.append(END_CONDITION);
params.add(Integer.valueOf(type));
} else {
//otherwise add condition to match against given type if necessary
conditions.append(BEGIN_INCLUDE_CONDITION);
conditions.append(m_sqlManager.readQuery(projectId, C_RESOURCES_SELECT_BY_RESOURCE_TYPE));
conditions.append(END_CONDITION);
params.add(Integer.valueOf(type));
}
}
}
/**
* Appends the appropriate selection criteria related with the resource type.<p>
*
* @param projectId the id of the project of the resources
* @param types the resource type id's
* @param mode the selection mode
* @param conditions buffer to append the selection criteria
* @param params list to append the selection parameters
*/
protected void prepareTypesCondition(
CmsUUID projectId,
List<Integer> types,
int mode,
StringBuffer conditions,
List params) {
if ((types == null) || types.isEmpty()) {
if ((mode & CmsDriverManager.READMODE_EXCLUDE_TYPE) > 0) {
// C_READ_FILE_TYPES: add condition to match against any type, but not given type
conditions.append(BEGIN_EXCLUDE_CONDITION);
conditions.append(m_sqlManager.readQuery(projectId, C_RESOURCES_SELECT_BY_RESOURCE_TYPE));
conditions.append(END_CONDITION);
params.add(Integer.valueOf(CmsDriverManager.READ_IGNORE_TYPE));
} else {
//otherwise add condition to match against given type if necessary
conditions.append(BEGIN_INCLUDE_CONDITION);
Iterator<Integer> typeIt = types.iterator();
while (typeIt.hasNext()) {
conditions.append(m_sqlManager.readQuery(projectId, C_RESOURCES_SELECT_BY_RESOURCE_TYPE));
params.add(typeIt.next());
if (typeIt.hasNext()) {
conditions.append(OR_CONDITION);
}
}
conditions.append(END_CONDITION);
}
}
}
/**
* Reads all resources inside a given project matching the criteria specified by parameter values.<p>
*
* Important: If {@link CmsDriverManager#READMODE_EXCLUDE_TREE} is true (or {@link CmsDriverManager#READMODE_INCLUDE_TREE} is false),
* the provided parent String must be the UUID of the parent folder, NOT the parent folder path.<p>
*
* @param dbc the current database context
* @param projectId the project id for matching resources
* @param parentPath the path to the resource used as root of the searched subtree or {@link CmsDriverManager#READ_IGNORE_PARENT},
* {@link CmsDriverManager#READMODE_EXCLUDE_TREE} means to read immediate children only
* @param types the resource types of matching resources or <code>null</code> (meaning inverted by {@link CmsDriverManager#READMODE_EXCLUDE_TYPE}
* @param state the state of matching resources (meaning inverted by {@link CmsDriverManager#READMODE_EXCLUDE_STATE} or <code>null</code> to ignore
* @param lastModifiedAfter the start of the time range for the last modification date of matching resources or READ_IGNORE_TIME
* @param lastModifiedBefore the end of the time range for the last modification date of matching resources or READ_IGNORE_TIME
* @param releasedAfter the start of the time range for the release date of matching resources
* @param releasedBefore the end of the time range for the release date of matching resources
* @param expiredAfter the start of the time range for the expire date of matching resources
* @param expiredBefore the end of the time range for the expire date of matching resources
* @param mode additional mode flags:
* <ul>
* <li>{@link CmsDriverManager#READMODE_INCLUDE_TREE}
* <li>{@link CmsDriverManager#READMODE_EXCLUDE_TREE}
* <li>{@link CmsDriverManager#READMODE_INCLUDE_PROJECT}
* <li>{@link CmsDriverManager#READMODE_EXCLUDE_TYPE}
* <li>{@link CmsDriverManager#READMODE_EXCLUDE_STATE}
* </ul>
*
* @return a list of CmsResource objects matching the given criteria
*
* @throws CmsDataAccessException if something goes wrong
*/
protected List<CmsResource> readTypesInResourceTree(
CmsDbContext dbc,
CmsUUID projectId,
String parentPath,
List<Integer> types,
CmsResourceState state,
long lastModifiedAfter,
long lastModifiedBefore,
long releasedAfter,
long releasedBefore,
long expiredAfter,
long expiredBefore,
int mode) throws CmsDataAccessException {
List<CmsResource> result = new ArrayList<CmsResource>();
StringBuffer conditions = new StringBuffer();
List params = new ArrayList(5);
// prepare the selection criteria
prepareProjectCondition(projectId, mode, conditions, params);
prepareResourceCondition(projectId, mode, conditions);
prepareTypesCondition(projectId, types, mode, conditions, params);
prepareTimeRangeCondition(projectId, lastModifiedAfter, lastModifiedBefore, conditions, params);
prepareReleasedTimeRangeCondition(projectId, releasedAfter, releasedBefore, conditions, params);
prepareExpiredTimeRangeCondition(projectId, expiredAfter, expiredBefore, conditions, params);
preparePathCondition(projectId, parentPath, mode, conditions, params);
prepareStateCondition(projectId, state, mode, conditions, params);
// now read matching resources within the subtree
List<Object[]> res = null;
try {
StringBuffer queryBuf = new StringBuffer(256);
queryBuf.append(m_sqlManager.readQuery(projectId, C_RESOURCES_READ_TREE));
queryBuf.append(conditions);
queryBuf.append(" ");
queryBuf.append(m_sqlManager.readQuery(projectId, C_RESOURCES_ORDER_BY_PATH));
Query q = m_sqlManager.createQueryFromJPQL(dbc, queryBuf.toString());
for (int i = 0; i < params.size(); i++) {
if (params.get(i) instanceof Integer) {
q.setParameter(i + 1, ((Integer)params.get(i)).intValue());
} else if (params.get(i) instanceof Long) {
q.setParameter(i + 1, ((Long)params.get(i)).longValue());
} else {
q.setParameter(i + 1, params.get(i));
}
}
res = q.getResultList();
for (Object[] obj : res) {
CmsResource resource = createResource(obj, projectId);
result.add(resource);
}
} catch (PersistenceException e) {
throw new CmsDbSqlException(Messages.get().container(Messages.ERR_GENERIC_SQL_1, C_RESOURCES_READ_TREE), e);
}
return result;
}
/**
* Repairs broken links.<p>
*
* When a resource is created any relation pointing to it is updated to use the right id.<p>
*
* @param dbc the current database context
* @param projectId the project id
* @param structureId the structure id of the resource that may help to repair broken links
* @param rootPath the path of the resource that may help to repair broken links
*
* @throws CmsDataAccessException if something goes wrong
*/
protected void repairBrokenRelations(CmsDbContext dbc, CmsUUID projectId, CmsUUID structureId, String rootPath)
throws CmsDataAccessException {
try {
Query q = m_sqlManager.createQuery(dbc, projectId, C_RELATIONS_REPAIR_BROKEN);
q.setParameter(1, rootPath);
@SuppressWarnings("unchecked")
List<I_CmsDAOResourceRelations> res = q.getResultList();
I_CmsDAOResourceRelations newR;
for (I_CmsDAOResourceRelations rr : res) {
newR = CmsProject.isOnlineProject(projectId)
? new CmsDAOOnlineResourceRelations()
: new CmsDAOOfflineResourceRelations();
newR.setRelationSourceId(rr.getRelationSourceId());
newR.setRelationSourcePath(rr.getRelationSourcePath());
newR.setRelationTargetId(structureId.toString());
newR.setRelationTargetPath(rr.getRelationTargetPath());
newR.setRelationType(rr.getRelationType());
m_sqlManager.remove(dbc, rr);
m_sqlManager.persist(dbc, newR);
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
}
/**
* Updates broken links.<p>
*
* When a resource is deleted, then the relations pointing to
* the deleted resource are set to the null uuid.<p>
*
* @param dbc the current database context
* @param projectId the project id
* @param rootPath the root path of the resource that has been deleted
*
* @throws CmsDataAccessException if something goes wrong
*/
protected void updateBrokenRelations(CmsDbContext dbc, CmsUUID projectId, String rootPath)
throws CmsDataAccessException {
try {
Query q = m_sqlManager.createQuery(dbc, projectId, C_RELATIONS_UPDATE_BROKEN);
q.setParameter(1, rootPath);
@SuppressWarnings("unchecked")
List<I_CmsDAOResourceRelations> res = q.getResultList();
I_CmsDAOResourceRelations newR;
for (I_CmsDAOResourceRelations rr : res) {
newR = CmsProject.isOnlineProject(projectId)
? new CmsDAOOnlineResourceRelations()
: new CmsDAOOfflineResourceRelations();
newR.setRelationSourceId(rr.getRelationSourceId());
newR.setRelationSourcePath(rr.getRelationSourcePath());
newR.setRelationTargetId(CmsUUID.getNullUUID().toString());
newR.setRelationTargetPath(rr.getRelationTargetPath());
newR.setRelationType(rr.getRelationType());
m_sqlManager.remove(dbc, rr);
m_sqlManager.persist(dbc, newR);
}
} catch (PersistenceException e) {
throw new CmsDataAccessException(Messages.get().container(Messages.ERR_JPA_PERSITENCE, e), e);
}
}
/**
* Creates a query by combining a base query with the generated JPQL conditions for a given
* URL name mapping filter.<p>
*
* @param dbc the db context
* @param baseQuery the base query to which the conditions should be appended
* @param filter the filter from which to generate the conditions
* @param online what project to use - ONLINE or OFFLINE project
*
* @return the created prepared statement
*
* @throws PersistenceException if something goes wrong
*/
private Query getQueryForFilter(CmsDbContext dbc, String baseQuery, CmsUrlNameMappingFilter filter, boolean online)
throws PersistenceException {
CmsPair<String, List<I_CmsQueryParameter>> conditionData = prepareUrlNameMappingConditions(filter);
String whereClause = "";
if (!conditionData.getFirst().equals("")) {
whereClause = " WHERE " + conditionData.getFirst();
}
String query = baseQuery + whereClause;
query = replaceProject(query, online);
Query q = m_sqlManager.createQueryFromJPQL(dbc, query);
int counter = 1;
for (I_CmsQueryParameter param : conditionData.getSecond()) {
param.insertIntoQuery(q, counter);
counter += 1;
}
return q;
}
/**
* Replaces the %(PROJECT) macro inside a query with either Online or Offline, depending on the value
* of a flag.<p>
*
* We use this instead of the ${PROJECT} replacement mechanism when we need explicit control over the
* project, and don't want to implicitly use the project of the DB context.<p>
*
* @param query the query in which the macro should be replaced
* @param online if true, the macro will be replaced with "ONLINE", else "OFFLINE"
*
* @return the query with the replaced macro
*/
private String replaceProject(String query, boolean online) {
return query.replace("%(PROJECT)", online ? CmsSqlManager.ONLINE_PROJECT : CmsSqlManager.OFFLINE_PROJECT);
}
}