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

org.opencms.file.wrapper.CmsResourceWrapperModules Maven / Gradle / Ivy

Go to download

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

There is a newer version: 18.0
Show newest version
/*
 * This library is part of OpenCms -
 * the Open Source Content Management System
 *
 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * For further information about Alkacon Software, please see the
 * company website: http://www.alkacon.com
 *
 * For further information about OpenCms, please see the
 * project website: http://www.opencms.org
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package org.opencms.file.wrapper;

import org.opencms.db.CmsResourceState;
import org.opencms.file.CmsFile;
import org.opencms.file.CmsObject;
import org.opencms.file.CmsProject;
import org.opencms.file.CmsProperty;
import org.opencms.file.CmsResource;
import org.opencms.file.CmsResourceFilter;
import org.opencms.file.CmsVfsResourceNotFoundException;
import org.opencms.file.types.CmsResourceTypeBinary;
import org.opencms.file.types.CmsResourceTypeFolder;
import org.opencms.jlan.CmsJlanDiskInterface;
import org.opencms.loader.CmsLoaderException;
import org.opencms.lock.CmsLock;
import org.opencms.main.CmsException;
import org.opencms.main.CmsIllegalArgumentException;
import org.opencms.main.CmsLog;
import org.opencms.main.OpenCms;
import org.opencms.module.CmsModule;
import org.opencms.util.CmsFileUtil;
import org.opencms.util.CmsStringUtil;
import org.opencms.util.CmsUUID;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.logging.Log;

import com.google.common.collect.Lists;

/**
 * Resource wrapper used to import/export modules by copying them to/from virtual folders.

*/ public class CmsResourceWrapperModules extends A_CmsResourceWrapper { /** The logger instance to use for this class. */ private static final Log LOG = CmsLog.getLog(CmsResourceWrapperModules.class); /** The base folder under which the virtual resources from this resource wrapper are available. */ public static final String BASE_PATH = "/modules"; /** The virtual folder which can be used to import modules. */ public static final String IMPORT_PATH = BASE_PATH + "/import"; /** The virtual folder which can be used to export modules. */ public static final String EXPORT_PATH = BASE_PATH + "/export"; /** The virtual folder which can be used to provide logs for module operations. */ public static final String LOG_PATH = BASE_PATH + "/log"; /** List of virtual folders made available by this resource wrapper. */ public static final List FOLDERS = Collections.unmodifiableList( Arrays.asList(BASE_PATH, IMPORT_PATH, EXPORT_PATH, LOG_PATH)); /** Cache for imported module files. */ private Map m_importDataCache = new ConcurrentHashMap(); /** * Map containing the last update time for a given import folder path.

* * Why do we need this if we just want to write files in the import folder and not read them? * The reason is that when using this wrapper with the JLAN CIFS connector, some clients check * on the status of the import file before they write any data to it, and fail mysteriously if it isn't found, * so we have to pretend that the file actually exists after creating it. **/ ConcurrentHashMap m_importFileUpdateCache = new ConcurrentHashMap(); /** * @see org.opencms.file.wrapper.A_CmsResourceWrapper#addResourcesToFolder(org.opencms.file.CmsObject, java.lang.String, org.opencms.file.CmsResourceFilter) */ @Override public List addResourcesToFolder(CmsObject cms, String resourcename, CmsResourceFilter filter) throws CmsException { String resourceNameWithTrailingSlash = CmsStringUtil.joinPaths(resourcename, "/"); if (matchPath("/", resourceNameWithTrailingSlash)) { return getVirtualResourcesForRoot(cms); } else if (matchPath(BASE_PATH, resourceNameWithTrailingSlash)) { return getVirtualResourcesForBasePath(cms); } else if (matchPath(EXPORT_PATH, resourceNameWithTrailingSlash)) { return getVirtualResourcesForExport(cms); } else if (matchPath(IMPORT_PATH, resourceNameWithTrailingSlash)) { return getVirtualResourcesForImport(cms); } else if (matchPath(LOG_PATH, resourceNameWithTrailingSlash)) { return getVirtualLogResources(cms); } return Collections.emptyList(); } /** * @see org.opencms.file.wrapper.A_CmsResourceWrapper#createResource(org.opencms.file.CmsObject, java.lang.String, int, byte[], java.util.List) */ @Override public CmsResource createResource( CmsObject cms, String resourcename, int type, byte[] content, List properties) throws CmsException, CmsIllegalArgumentException { if (matchParentPath(IMPORT_PATH, resourcename)) { CmsResource res = createFakeBinaryFile(resourcename, 0); CmsFile file = new CmsFile(res); file.setContents(content); OpenCms.getModuleManager().getImportExportRepository().importModule( CmsResource.getName(resourcename), content); m_importFileUpdateCache.put(resourcename, Long.valueOf(System.currentTimeMillis())); return file; } else { return super.createResource(cms, resourcename, type, content, properties); } } /** * @see org.opencms.file.wrapper.A_CmsResourceWrapper#deleteResource(org.opencms.file.CmsObject, java.lang.String, org.opencms.file.CmsResource.CmsResourceDeleteMode) */ @Override public boolean deleteResource(CmsObject cms, String resourcename, CmsResource.CmsResourceDeleteMode siblingMode) throws CmsException { if (matchParentPath(EXPORT_PATH, resourcename)) { String fileName = CmsResource.getName(resourcename); boolean result = OpenCms.getModuleManager().getImportExportRepository().deleteModule(fileName); return result; } else { return false; } } /** * @see org.opencms.file.wrapper.A_CmsResourceWrapper#getLock(org.opencms.file.CmsObject, org.opencms.file.CmsResource) */ @Override public CmsLock getLock(CmsObject cms, CmsResource resource) throws CmsException { if (isFakePath(resource.getRootPath())) { return CmsLock.getNullLock(); } else { return super.getLock(cms, resource); } } /** * @see org.opencms.file.wrapper.I_CmsResourceWrapper#isWrappedResource(org.opencms.file.CmsObject, org.opencms.file.CmsResource) */ public boolean isWrappedResource(CmsObject cms, CmsResource res) { return CmsStringUtil.isPrefixPath(BASE_PATH, res.getRootPath()); } /** * @see org.opencms.file.wrapper.A_CmsResourceWrapper#lockResource(org.opencms.file.CmsObject, java.lang.String, boolean) */ @Override public boolean lockResource(CmsObject cms, String resourcename, boolean temporary) { return isFakePath(resourcename); } /** * @see org.opencms.file.wrapper.A_CmsResourceWrapper#readFile(org.opencms.file.CmsObject, java.lang.String, org.opencms.file.CmsResourceFilter) */ @Override public CmsFile readFile(CmsObject cms, String resourcename, CmsResourceFilter filter) throws CmsException { // this method isn't actually called when using the JLAN repository, because readResource already returns a CmsFile when needed cms.getRequestContext().removeAttribute(CmsJlanDiskInterface.NO_FILESIZE_REQUIRED); CmsResource res = readResource(cms, resourcename, filter); return (CmsFile)res; } /** * @see org.opencms.file.wrapper.A_CmsResourceWrapper#readResource(org.opencms.file.CmsObject, java.lang.String, org.opencms.file.CmsResourceFilter) */ @Override public CmsResource readResource(CmsObject cms, String resourcepath, CmsResourceFilter filter) throws CmsException { if (resourcepath.endsWith("desktop.ini")) { return null; } for (String folder : FOLDERS) { if (matchPath(resourcepath, folder)) { return createFakeFolder(folder); } } if (matchParentPath(IMPORT_PATH, resourcepath)) { if (hasImportFile(resourcepath)) { CmsFile importData = m_importDataCache.get(resourcepath); if (importData != null) { return importData; } return new CmsFile(createFakeBinaryFile(resourcepath)); } } if (matchParentPath(EXPORT_PATH, resourcepath)) { CmsFile resultFile = new CmsFile(createFakeBinaryFile(resourcepath)); if (cms.getRequestContext().getAttribute(CmsJlanDiskInterface.NO_FILESIZE_REQUIRED) == null) { // we *do* require the file size, so we need to get the module data LOG.info("Getting data for " + resourcepath); byte[] data = OpenCms.getModuleManager().getImportExportRepository().getExportedModuleData( CmsResource.getName(resourcepath), cms.getRequestContext().getCurrentProject()); resultFile.setContents(data); } return resultFile; } if (matchParentPath(LOG_PATH, resourcepath)) { CmsFile resultFile = new CmsFile(createFakeBinaryFile(resourcepath)); // if (cms.getRequestContext().getAttribute(CmsJlanDiskInterface.NO_FILESIZE_REQUIRED) == null) { String moduleName = CmsResource.getName(resourcepath).replaceFirst("\\.log$", ""); try { byte[] data = OpenCms.getModuleManager().getImportExportRepository().getModuleLog().readLog(moduleName); resultFile.setContents(data); return resultFile; } catch (IOException e) { throw new CmsVfsResourceNotFoundException( org.opencms.db.Messages.get().container(org.opencms.db.Messages.ERR_READ_RESOURCE_1, resourcepath), e); } } return super.readResource(cms, resourcepath, filter); } /** * @see org.opencms.file.wrapper.A_CmsResourceWrapper#unlockResource(org.opencms.file.CmsObject, java.lang.String) */ @Override public boolean unlockResource(CmsObject cms, String resourcename) { return isFakePath(resourcename); } /** * @see org.opencms.file.wrapper.A_CmsResourceWrapper#writeFile(org.opencms.file.CmsObject, org.opencms.file.CmsFile) */ @Override public CmsFile writeFile(CmsObject cms, CmsFile resource) throws CmsException { if (matchParentPath(IMPORT_PATH, resource.getRootPath())) { OpenCms.getModuleManager().getImportExportRepository().importModule( CmsResource.getName(resource.getRootPath()), resource.getContents()); m_importFileUpdateCache.put(resource.getRootPath(), Long.valueOf(System.currentTimeMillis())); m_importDataCache.put(resource.getRootPath(), resource); return resource; } else { return super.writeFile(cms, resource); } } /** * Creates a fake CmsResource of type 'binary'.

* * @param rootPath the root path * * @return the fake resource * * @throws CmsLoaderException if the binary type is missing */ protected CmsResource createFakeBinaryFile(String rootPath) throws CmsLoaderException { return createFakeBinaryFile(rootPath, 0); } /** * Creates a fake CmsResource of type 'binary'.

* * @param rootPath the root path * @param dateLastModified the last modification date to use * * @return the fake resource * * @throws CmsLoaderException if the binary type is missing */ protected CmsResource createFakeBinaryFile(String rootPath, long dateLastModified) throws CmsLoaderException { CmsUUID structureId = CmsUUID.getConstantUUID("s-" + rootPath); CmsUUID resourceId = CmsUUID.getConstantUUID("r-" + rootPath); @SuppressWarnings("deprecation") int type = OpenCms.getResourceManager().getResourceType(CmsResourceTypeBinary.getStaticTypeName()).getTypeId(); boolean isFolder = false; int flags = 0; CmsUUID projectId = CmsProject.ONLINE_PROJECT_ID; CmsResourceState state = CmsResource.STATE_UNCHANGED; long dateCreated = 0; long dateReleased = 1; long dateContent = 1; int version = 0; CmsUUID userCreated = CmsUUID.getNullUUID(); CmsUUID userLastModified = CmsUUID.getNullUUID(); long dateExpired = Integer.MAX_VALUE; int linkCount = 0; int size = 1; CmsResource resource = new CmsResource( structureId, resourceId, rootPath, type, isFolder, flags, projectId, state, dateCreated, userCreated, dateLastModified, userLastModified, dateReleased, dateExpired, linkCount, size, dateContent, version); return resource; } /** * Creates a fake CmsResource of type 'folder'.

* * @param rootPath the root path * * @return the fake resource * * @throws CmsLoaderException if the 'folder' type can not be found */ protected CmsResource createFakeFolder(String rootPath) throws CmsLoaderException { if (rootPath.endsWith("/")) { rootPath = CmsFileUtil.removeTrailingSeparator(rootPath); } CmsUUID structureId = CmsUUID.getConstantUUID("s-" + rootPath); CmsUUID resourceId = CmsUUID.getConstantUUID("r-" + rootPath); @SuppressWarnings("deprecation") int type = OpenCms.getResourceManager().getResourceType(CmsResourceTypeFolder.getStaticTypeName()).getTypeId(); boolean isFolder = true; int flags = 0; CmsUUID projectId = CmsProject.ONLINE_PROJECT_ID; CmsResourceState state = CmsResource.STATE_UNCHANGED; long dateCreated = 0; long dateLastModified = 0; long dateReleased = 1; long dateContent = 1; int version = 0; CmsUUID userCreated = CmsUUID.getNullUUID(); CmsUUID userLastModified = CmsUUID.getNullUUID(); long dateExpired = Integer.MAX_VALUE; int linkCount = 0; int size = -1; CmsResource resource = new CmsResource( structureId, resourceId, rootPath, type, isFolder, flags, projectId, state, dateCreated, userCreated, dateLastModified, userLastModified, dateReleased, dateExpired, linkCount, size, dateContent, version); return resource; } /** * Gets the virtual resources in the log folder.

* * @param cms the CMS context * @return the list of virtual log resources * * @throws CmsException if something goes wrong */ private List getVirtualLogResources(CmsObject cms) throws CmsException { List virtualResources = Lists.newArrayList(); for (CmsModule module : OpenCms.getModuleManager().getAllInstalledModules()) { String path = CmsStringUtil.joinPaths(LOG_PATH, module.getName() + ".log"); CmsResource res = createFakeBinaryFile(path); virtualResources.add(res); } return virtualResources; } /** * Gets the virtual resources for the base folder.

* * @param cms the current CMS context * @return the virtual resources for the base folder * * @throws CmsException if something goes wrong */ private List getVirtualResourcesForBasePath(CmsObject cms) throws CmsException { return Arrays.asList(createFakeFolder(IMPORT_PATH), createFakeFolder(EXPORT_PATH), createFakeFolder(LOG_PATH)); } /** * Gets the virtual resources for the export folder.

* * @param cms the CMS context * @return the list of resources for the export folder * * @throws CmsException if something goes wrong */ private List getVirtualResourcesForExport(CmsObject cms) throws CmsException { List virtualResources = Lists.newArrayList(); for (String name : OpenCms.getModuleManager().getImportExportRepository().getModuleFileNames()) { String path = CmsStringUtil.joinPaths(EXPORT_PATH, name); CmsResource res = createFakeBinaryFile(path); virtualResources.add(res); } return virtualResources; } /** * Gets the virtual resources for the import folder.

* * @param cms the CMS context * * @return the virtual resources for the import folder */ private List getVirtualResourcesForImport(CmsObject cms) { List result = Lists.newArrayList(); return result; } /** * Gets the virtual resources to add to the root folder.

* * @param cms the CMS context to use * @return the virtual resources for the root folder * * @throws CmsException if something goes wrong */ private List getVirtualResourcesForRoot(CmsObject cms) throws CmsException { CmsResource resource = createFakeFolder(BASE_PATH); return Arrays.asList(resource); } /** * Checks if the the import file is available.

* * @param resourcepath the resource path * * @return true if the import file is available */ private boolean hasImportFile(String resourcepath) { Long value = m_importFileUpdateCache.get(resourcepath); if (value == null) { return false; } long age = System.currentTimeMillis() - value.longValue(); return age < 5000; } /** * Returns true if the given path is a fake path handled by this resource wrapper.

* * @param resourcename the path * * @return true if the path is a fake path handled by this resource wrapper */ private boolean isFakePath(String resourcename) { for (String folder : FOLDERS) { if (matchPath(folder, resourcename) || matchParentPath(folder, resourcename)) { return true; } } return false; } /** * Checks if a given path is a direct descendant of another path.

* * @param expectedParent the expected parent folder * @param path a path * @return true if the path is a direct child of expectedParent */ private boolean matchParentPath(String expectedParent, String path) { String parent = CmsResource.getParentFolder(path); if (parent == null) { return false; } return matchPath(expectedParent, parent); } /** * Checks if a path matches another part.

* * This is basically an equality test, but ignores the presence/absence of trailing slashes. * * @param expected the expected path * @param actual the actual path * @return true if the actual path matches the expected path */ private boolean matchPath(String expected, String actual) { return CmsStringUtil.joinPaths(actual, "/").equals(CmsStringUtil.joinPaths(expected, "/")); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy