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 GmbH & Co. KG, 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.relations; 029 030import org.opencms.file.CmsDataAccessException; 031import org.opencms.file.CmsResource; 032import org.opencms.main.CmsException; 033import org.opencms.main.CmsLog; 034import org.opencms.util.CmsStringUtil; 035import org.opencms.util.CmsUUID; 036 037import java.io.Serializable; 038 039import org.apache.commons.logging.Log; 040 041/** 042 * Represents a category, that is just a folder.<p> 043 * 044 * The category can be centralized under <code>/system/categories/</code>, 045 * or decentralized in every folder.<p> 046 * 047 * For instance, you can have a category folder under <code>/sites/default/</code> 048 * so, any file under <code>/sites/default/</code> could be assigned to any 049 * category defined under <code>/system/categories/</code> or 050 * <code>/sites/default/categories</code>.<p> 051 * 052 * But a file under <code>/sites/othersite/</code> will only be assignable to 053 * categories defined in <code>/system/categories/</code>.<p> 054 * 055 * @since 6.9.2 056 */ 057public class CmsCategory implements Comparable<CmsCategory>, Serializable { 058 059 /** Logger instance for this class. */ 060 private static final Log LOG = CmsLog.getLog(CmsCategory.class); 061 062 /** The serialization id. */ 063 private static final long serialVersionUID = -6395887983124249138L; 064 065 /** The category's base path. */ 066 private String m_basePath; 067 068 /** The description of the category. */ 069 private String m_description; 070 071 /** Background color to use for the category in the explorer's 'Categories' column. */ 072 private String m_background; 073 074 /** The path of the category. */ 075 private String m_path; 076 077 /** The category's root path. */ 078 private String m_rootPath; 079 080 /** The structure id of the resource that this category represents. */ 081 private CmsUUID m_structureId; 082 083 /** The title of the category. */ 084 private String m_title; 085 086 /** 087 * Creates a new category based on another one, keeping everything except title and description, which are passed in separately.<p> 088 * 089 * @param other the other category to copy fields from 090 * @param title the new title 091 * @param description the new description 092 */ 093 public CmsCategory(CmsCategory other, String title, String description) { 094 095 m_basePath = other.m_basePath; 096 097 m_path = other.m_path; 098 m_rootPath = other.m_rootPath; 099 m_structureId = other.m_structureId; 100 m_description = description != null ? description : other.m_description; 101 m_title = title != null ? title : other.m_title; 102 m_background = other.m_background; 103 } 104 105 /** 106 * Default constructor.<p> 107 * 108 * @param structureId the structure id of the resource that this category represents 109 * @param rootPath the root path of the category folder 110 * @param title the title of the category 111 * @param description the description of the category 112 * @param baseFolder the base categories folder 113 * @param background the background color for displaying the category in the explorer file table (in 6 digit hexadecimal form, e.g. #aabbcc), or null 114 * 115 * @throws CmsException if the root path does not match the given base folder 116 */ 117 public CmsCategory( 118 CmsUUID structureId, 119 String rootPath, 120 String title, 121 String description, 122 String baseFolder, 123 String background) 124 throws CmsException { 125 126 m_structureId = structureId; 127 m_rootPath = rootPath; 128 m_title = title; 129 m_description = description; 130 m_path = getCategoryPath(m_rootPath, baseFolder); 131 m_basePath = m_rootPath.substring(0, m_rootPath.length() - m_path.length()); 132 m_background = background; 133 } 134 135 /** 136 * Empty default constructor which is only used for serialization.<p> 137 */ 138 protected CmsCategory() { 139 140 // do nothing 141 } 142 143 /** 144 * Returns the category path for the given root path.<p> 145 * 146 * @param rootPath the root path 147 * @param baseFolder the categories base folder name 148 * 149 * @return the category path 150 * 151 * @throws CmsException if the root path does not match the given base folder 152 */ 153 public static String getCategoryPath(String rootPath, String baseFolder) throws CmsException { 154 155 String base; 156 if (rootPath.startsWith(CmsCategoryService.CENTRALIZED_REPOSITORY)) { 157 base = CmsCategoryService.CENTRALIZED_REPOSITORY; 158 } else { 159 base = baseFolder; 160 if (!base.endsWith("/")) { 161 base += "/"; 162 } 163 if (!base.startsWith("/")) { 164 base = "/" + base; 165 } 166 int pos = rootPath.indexOf(base); 167 if (pos < 0) { 168 throw new CmsDataAccessException( 169 Messages.get().container(Messages.ERR_CATEGORY_INVALID_LOCATION_1, rootPath)); 170 } 171 base = rootPath.substring(0, pos + base.length()); 172 } 173 return rootPath.substring(base.length()); 174 } 175 176 /** 177 * @see java.lang.Comparable#compareTo(java.lang.Object) 178 */ 179 public int compareTo(CmsCategory cat) { 180 181 boolean thisGlobal = getBasePath().equals(CmsCategoryService.CENTRALIZED_REPOSITORY); 182 boolean thatGlobal = cat.getBasePath().equals(CmsCategoryService.CENTRALIZED_REPOSITORY); 183 if ((thisGlobal && thatGlobal) || (!thisGlobal && !thatGlobal)) { 184 return getPath().compareTo(cat.getPath()); 185 } 186 return thisGlobal ? -1 : 1; 187 } 188 189 /** 190 * @see java.lang.Object#equals(java.lang.Object) 191 */ 192 @Override 193 public boolean equals(Object obj) { 194 195 if (!(obj instanceof CmsCategory)) { 196 return false; 197 } 198 CmsCategory compareCategory = (CmsCategory)obj; 199 if (!compareCategory.getPath().equals(getPath())) { 200 return false; 201 } 202 return true; 203 } 204 205 /** 206 * Gets the configured background color for the category in the 'Categories' explorer column. 207 * 208 * <p>The color should consist of 6 hex digits preceded by a hash symbol (#aabbcc). 209 * 210 * @return the background color, or null if it's not set 211 */ 212 public String getBackground() { 213 214 return m_background; 215 } 216 217 /** 218 * Returns the category's base path.<p> 219 * 220 * @return the category's base path 221 */ 222 public String getBasePath() { 223 224 return m_basePath; 225 } 226 227 /** 228 * Returns the description.<p> 229 * 230 * @return the description 231 */ 232 public String getDescription() { 233 234 return m_description; 235 } 236 237 /** 238 * Returns the id.<p> 239 * 240 * @return the id 241 */ 242 public CmsUUID getId() { 243 244 return m_structureId; 245 } 246 247 /** 248 * Returns the mere category name without it's complete path and without the trailing folder - slash.<p> 249 * 250 * @return the mere category name without it's complete path and without the trailing folder - slash 251 */ 252 public String getName() { 253 254 if (CmsStringUtil.isEmptyOrWhitespaceOnly(m_path)) { 255 return ""; 256 } 257 String result = CmsResource.getName(m_path); 258 // remove trailing slash as categories are not displayed like folders 259 if (CmsResource.isFolder(result)) { 260 result = result.substring(0, result.length() - 1); 261 } 262 return result; 263 } 264 265 /** 266 * Returns the path.<p> 267 * 268 * @return the path 269 */ 270 public String getPath() { 271 272 return m_path; 273 } 274 275 /** 276 * Returns the category's root path.<p> 277 * 278 * @return the category's root path 279 */ 280 public String getRootPath() { 281 282 return m_rootPath; 283 } 284 285 /** 286 * Returns the title.<p> 287 * 288 * @return the title 289 */ 290 public String getTitle() { 291 292 return m_title; 293 } 294 295 /** 296 * @see java.lang.Object#hashCode() 297 */ 298 @Override 299 public int hashCode() { 300 301 return getPath().hashCode(); 302 } 303 304 /** 305 * @see java.lang.Object#toString() 306 */ 307 @Override 308 public String toString() { 309 310 return "[" + CmsCategory.class.getSimpleName() + "/" + System.identityHashCode(this) + ": " + m_rootPath + " ]"; 311 } 312 313}