001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.util; 029 030import org.opencms.file.CmsObject; 031import org.opencms.file.CmsProperty; 032import org.opencms.file.CmsResource; 033import org.opencms.file.CmsResourceFilter; 034import org.opencms.file.CmsVfsResourceAlreadyExistsException; 035import org.opencms.file.types.CmsResourceTypeFolder; 036import org.opencms.main.CmsException; 037import org.opencms.main.CmsLog; 038import org.opencms.main.OpenCms; 039 040import java.util.ArrayList; 041import java.util.List; 042import java.util.Locale; 043import java.util.Map; 044 045import org.apache.commons.logging.Log; 046 047import com.google.common.collect.Lists; 048 049/** 050 * Provides Vfs utility functions.<p> 051 * 052 * @since 11.0.0 053 */ 054public final class CmsVfsUtil { 055 056 /** The log instance for this class. */ 057 private static final Log LOG = CmsLog.getLog(CmsVfsUtil.class); 058 059 /** 060 * Hides the public constructor.<p> 061 */ 062 private CmsVfsUtil() { 063 064 // empty 065 } 066 067 /** 068 * Creates a folder and its parent folders if they don't exist.<p> 069 * 070 * @param cms the CMS context to use 071 * @param rootPath the folder root path 072 * 073 * @throws CmsException if something goes wrong 074 */ 075 public static void createFolder(CmsObject cms, String rootPath) throws CmsException { 076 077 CmsObject rootCms = OpenCms.initCmsObject(cms); 078 rootCms.getRequestContext().setSiteRoot(""); 079 List<String> parents = new ArrayList<String>(); 080 String currentPath = rootPath; 081 while (currentPath != null) { 082 if (rootCms.existsResource(currentPath)) { 083 break; 084 } 085 parents.add(currentPath); 086 currentPath = CmsResource.getParentFolder(currentPath); 087 } 088 parents = Lists.reverse(parents); 089 for (String parent : parents) { 090 try { 091 rootCms.createResource( 092 parent, 093 OpenCms.getResourceManager().getResourceType(CmsResourceTypeFolder.getStaticTypeName())); 094 try { 095 rootCms.unlockResource(parent); 096 } catch (CmsException e) { 097 // may happen if parent folder is locked also 098 if (LOG.isInfoEnabled()) { 099 LOG.info(e.getLocalizedMessage(), e); 100 } 101 } 102 } catch (CmsVfsResourceAlreadyExistsException e) { 103 // nop 104 } 105 } 106 } 107 108 /** 109 * Checks if the provided resource is a default file. 110 * @param cms the context 111 * @param resource the resource to check 112 * @return true, if the file is an default file. False if the file is no default file or an exception occurred. 113 */ 114 public static boolean isDefaultFile(CmsObject cms, CmsResource resource) { 115 116 if ((null == resource) || resource.isFolder()) { 117 return false; 118 } 119 try { 120 CmsResource defaultFile = cms.readDefaultFile( 121 CmsResource.getFolderPath(cms.getSitePath(resource)), 122 CmsResourceFilter.ALL); 123 return (null != defaultFile) && defaultFile.getRootPath().equals(resource.getRootPath()); 124 } catch (Throwable t) { 125 String message = "Failed to check if \"" 126 + resource.getRootPath() 127 + "\" is a default file. Assuming it is not."; 128 if (LOG.isDebugEnabled()) { 129 LOG.debug(message, t); 130 } else { 131 LOG.error(message); 132 } 133 } 134 return false; 135 } 136 137 /** 138 * Reads the property value for the provided name and resource. 139 * The locale specific properties are read first, with fallback to the default property. 140 * 141 * In case the resource is a default file and the property is not found on the file itself, 142 * the property is read (again locale specific) on the folder as fallback. 143 * 144 * @param cms the context 145 * @param resource the resource to read the property from 146 * @param propertyName the name of the property to read 147 * @param locale the locale to read the property in. 148 * @return the property value or null, if the property is not set at all or a exception occurred. 149 */ 150 public static String readPropertyValueWithFolderFallbackForDefaultFiles( 151 CmsObject cms, 152 153 CmsResource resource, 154 String propertyName, 155 Locale locale) { 156 157 try { 158 List<CmsProperty> resourcePropsList = cms.readPropertyObjects(resource, false); 159 Map<String, CmsProperty> resourceProps = CmsProperty.getPropertyMap(resourcePropsList); 160 String value = CmsProperty.getLocaleSpecificPropertyValue(resourceProps, propertyName, locale); 161 if ((value == null) && isDefaultFile(cms, resource)) { 162 try { 163 List<CmsProperty> folderPropsList = cms.readPropertyObjects( 164 CmsResource.getFolderPath(cms.getSitePath(resource)), 165 false); 166 Map<String, CmsProperty> folderProps = CmsProperty.getPropertyMap(folderPropsList); 167 value = CmsProperty.getLocaleSpecificPropertyValue(folderProps, propertyName, locale); 168 } catch (Throwable e) { 169 String message = "Failed to read folder property \"" 170 + propertyName 171 + "\" for resource \"" 172 + resource.getRootPath() 173 + "\"."; 174 if (LOG.isDebugEnabled()) { 175 LOG.debug(message, e); 176 } else { 177 LOG.error(message); 178 } 179 } 180 } 181 return value; 182 } catch (Throwable e) { 183 String message = "Failed to read property \"" 184 + propertyName 185 + "\" for resource \"" 186 + (null == resource ? "null" : resource.getRootPath()) 187 + "\"."; 188 if (LOG.isDebugEnabled()) { 189 LOG.debug(message, e); 190 } else { 191 LOG.error(message); 192 } 193 return null; 194 } 195 } 196 197}