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