/* * File : $Source: /alkacon/cvs/alkacon/com.alkacon.opencms.commons/src/com/alkacon/opencms/commons/CmsConfigurableCollector.java,v $ * Date : $Date: 2008/03/03 08:27:23 $ * Version: $Revision: 1.4 $ * * This file is part of the Alkacon OpenCms Add-On Module Package * * Copyright (c) 2007 Alkacon Software GmbH (http://www.alkacon.com) * * The Alkacon OpenCms Add-On Module Package is free software: * you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The Alkacon OpenCms Add-On Module Package 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with the Alkacon OpenCms Add-On Module Package. * If not, see http://www.gnu.org/licenses/. * * For further information about Alkacon Software GmbH, please see the * company website: http://www.alkacon.com. * * For further information about OpenCms, please see the * project website: http://www.opencms.org. */ package com.alkacon.opencms.commons; import org.opencms.file.CmsDataAccessException; import org.opencms.file.CmsObject; import org.opencms.file.CmsResource; import org.opencms.file.CmsResourceFilter; import org.opencms.file.I_CmsResource; import org.opencms.file.collectors.A_CmsResourceCollector; import org.opencms.main.CmsException; import org.opencms.main.CmsIllegalArgumentException; import org.opencms.relations.CmsCategory; import org.opencms.relations.CmsCategoryService; import org.opencms.util.CmsStringUtil; import org.opencms.xml.CmsXmlException; import org.opencms.xml.content.CmsXmlContent; import org.opencms.xml.content.CmsXmlContentFactory; import org.opencms.xml.types.I_CmsXmlContentValue; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Set; /** * Collects VFS resources as configured.<p> * * This configurable collector can be used to collect different resource types in different VFS folders. Use * {@link com.alkacon.opencms.commons.CmsCollectorConfiguration} objects to configure the collector.<p> * * @author Andreas Zahner * * @version $Revision: 1.4 $ * * @since 6.0.1 */ public class CmsConfigurableCollector extends A_CmsResourceCollector { /** The collector name. */ public static final String COLLECTOR_NAME = "configurableCollector"; /** Node name for XMLContent collector configuration file: the node(s) containing the categories. */ public static final String NODE_CATEGORY = "Category"; /** Node name for XMLContent collector configuration file: the node containing the VFS folder. */ public static final String NODE_FOLDER = "Folder"; /** Node name for XMLContent collector configuration file: the node(s) containing the mandatory properties. */ public static final String NODE_PROPERTY = "Property"; /** Node name for XMLContent collector configuration file: the node containing a configuration. */ public static final String NODE_RESCONFIG = "ResConfig"; /** Node name for XMLContent collector configuration file: the node containing the resource type name. */ public static final String NODE_RESTYPE = "ResType"; /** The collector configurations to use to collect the resources. */ private final List<CmsCollectorConfiguration> m_collectorConfigurations; /** The path prefix to use when reading the collector configurations. */ private String m_pathPrefix; /** * Constructor that initializes an empty collector configuration list.<p> */ public CmsConfigurableCollector() { this(""); } /** * Constructor that initializes an empty collector configuration list.<p> * * @param pathPrefix the prefix to use when reading the collector configurations */ public CmsConfigurableCollector(String pathPrefix) { super(); setDefaultCollectorName(COLLECTOR_NAME); setDefaultCollectorParam(""); m_collectorConfigurations = new ArrayList<CmsCollectorConfiguration>(); m_pathPrefix = pathPrefix; } /** * Constructor that initializes the collector configuration list.<p> * * @param collectorConfigurations the list of collector configurations to use */ public CmsConfigurableCollector(List<CmsCollectorConfiguration> collectorConfigurations) { this(); m_collectorConfigurations.addAll(collectorConfigurations); } /** * Returns the collector configurations to use to collect the resources.<p> * * @return the collector configurations to use to collect the resources */ public List<CmsCollectorConfiguration> getCollectorConfigurations() { return m_collectorConfigurations; } /** * @see org.opencms.file.collectors.I_CmsResourceCollector#getCollectorNames() */ public List<String> getCollectorNames() { return Collections.singletonList(COLLECTOR_NAME); } /** * @see org.opencms.file.collectors.I_CmsResourceCollector#getCreateLink(org.opencms.file.CmsObject, java.lang.String, java.lang.String) */ public String getCreateLink(CmsObject cms, String collectorName, String param) { // this collector does not support resource creation links return null; } /** * @see org.opencms.file.collectors.I_CmsResourceCollector#getCreateParam(org.opencms.file.CmsObject, java.lang.String, java.lang.String) */ public String getCreateParam(CmsObject cms, String collectorName, String param) { // this collector does not support resource creation parameters return null; } /** * @see org.opencms.file.collectors.I_CmsResourceCollector#getResults(org.opencms.file.CmsObject, java.lang.String, java.lang.String) */ public List<CmsResource> getResults(CmsObject cms, String collectorName, String param) throws CmsDataAccessException, CmsException { // if action is not set use default if (collectorName == null) { collectorName = COLLECTOR_NAME; } return getAllInFolder(cms, param); } /** * Sets the collector configurations to use to collect the resources.<p> * * @param collectorConfigurations the collector configurations to use to collect the resources */ public void setCollectorConfigurations(List<CmsCollectorConfiguration> collectorConfigurations) { m_collectorConfigurations.clear(); m_collectorConfigurations.addAll(collectorConfigurations); } /** * Returns all resources in the folder pointed to by the parameter.<p> * * @param cms the current OpenCms user context * @param param the folder name to use * * @return all resources in the folder matching the given criteria * * @throws CmsException if something goes wrong * @throws CmsIllegalArgumentException if the given param argument is not a link to a single file * */ protected List<CmsResource> getAllInFolder(CmsObject cms, String param) throws CmsException, CmsIllegalArgumentException { List<CmsCollectorConfiguration> collectorConfigurations = getCollectorConfigurations(); if (CmsStringUtil.isNotEmpty(param)) { // read configuration from param specifying config file in VFS try { collectorConfigurations = readConfigurationFromFile(cms, param); } catch (CmsException e) { // error reading collector configuration file throw new CmsXmlException(Messages.get().container(Messages.ERR_COLLECTOR_CONFIG_INVALID_1, param)); } } Set<CmsResource> collected = new HashSet<CmsResource>(); for (int i = 0; i < collectorConfigurations.size(); i++) { // loop all configurations and collect the resources CmsCollectorConfiguration config = collectorConfigurations.get(i); CmsResourceFilter filter = CmsResourceFilter.DEFAULT.addExcludeFlags(CmsResource.FLAG_TEMPFILE); if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(config.getResourceType())) { filter = filter.addRequireType(config.getResourceTypeId()); } List<CmsResource> resources = cms.readResources(config.getUri(), filter, config.isRecursive()); if (config.getCategories().size() > 0) { // check the categories of each resource List<CmsResource> catResources = new ArrayList<CmsResource>(resources.size()); CmsCategoryService service = CmsCategoryService.getInstance(); for (CmsResource resource : resources) { List<CmsCategory> categories = service.readResourceCategories(cms, cms.getSitePath(resource)); for (CmsCategory neededCategory : config.getCategories()) { if (categories.contains(neededCategory)) { catResources.add(resource); break; } } } resources = catResources; } if (config.getProperties().size() > 0) { // check the properties of each resource for (int k = resources.size() - 1; k > -1; k--) { CmsResource res = resources.get(k); cms.readPropertyObjects(res, false); boolean addToResult = true; for (int m = config.getProperties().size() - 1; m > -1; m--) { // loop all required properties String propertyDef = config.getProperties().get(m); if (CmsStringUtil.isEmptyOrWhitespaceOnly(cms.readPropertyObject(res, propertyDef, false).getValue())) { addToResult = false; break; } } if (addToResult) { collected.add(res); } } } else { // no properties to check, add all resources collected.addAll(resources); } } List<CmsResource> result = new ArrayList<CmsResource>(collected); Collections.sort(result, I_CmsResource.COMPARE_ROOT_PATH); Collections.reverse(result); return result; } /** * Returns the collector configuration that is read from an XmlContent resource.<p> * * @param cms the current OpenCms user context * @param resourceName the absolute path to the VFS resource to read * * @return the collector configuration that is read from an XmlContent resource * * @throws CmsException if something goes wrong */ private List<CmsCollectorConfiguration> readConfigurationFromFile(CmsObject cms, String resourceName) throws CmsException { List<CmsCollectorConfiguration> result = new ArrayList<CmsCollectorConfiguration>(); Locale locale = cms.getRequestContext().getLocale(); // get the resource CmsResource res = cms.readResource(resourceName); CmsXmlContent xml = CmsXmlContentFactory.unmarshal(cms, cms.readFile(res)); // get the configuration nodes String prefix = ""; if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(m_pathPrefix)) { prefix = m_pathPrefix + "/"; } List<I_CmsXmlContentValue> configurations = xml.getValues(prefix + NODE_RESCONFIG, locale); int configurationSize = configurations.size(); for (int i = 0; i < configurationSize; i++) { // loop all configuration nodes I_CmsXmlContentValue resConfig = configurations.get(i); String resConfigPath = resConfig.getPath() + "/"; String resType = xml.getStringValue(cms, resConfigPath + NODE_RESTYPE, locale); String folder = xml.getStringValue(cms, resConfigPath + NODE_FOLDER, locale); // determine the properties to check List<I_CmsXmlContentValue> propertyValues = xml.getValues(resConfigPath + NODE_PROPERTY, locale); List<String> properties = new ArrayList<String>(propertyValues.size()); for (int k = propertyValues.size() - 1; k > -1; k--) { I_CmsXmlContentValue value = propertyValues.get(k); properties.add(value.getStringValue(cms)); } // determine the categories to check List<I_CmsXmlContentValue> categoryValues = xml.getValues(resConfigPath + NODE_CATEGORY, locale); List<CmsCategory> categories = new ArrayList<CmsCategory>(categoryValues.size()); for (int k = categoryValues.size() - 1; k > -1; k--) { I_CmsXmlContentValue value = categoryValues.get(k); String categoryPath = value.getStringValue(cms); CmsResource catRes = cms.readResource(categoryPath); categories.add(CmsCategoryService.getInstance().getCategory(cms, catRes)); } // add the configuration to the result result.add(new CmsCollectorConfiguration(folder, resType, properties, categories)); } return result; } }