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.CmsResource; 031import org.opencms.util.CmsUUID; 032 033import java.util.Collections; 034import java.util.HashSet; 035import java.util.Iterator; 036import java.util.Set; 037 038/** 039 * A filter to retrieve the relations for a given resource.<p> 040 * 041 * @since 6.0.0 042 */ 043public final class CmsRelationFilter implements Cloneable { 044 045 /** To filter all sources and targets. */ 046 public static final CmsRelationFilter ALL = new CmsRelationFilter(true, true); 047 048 /** To filter all sources. */ 049 public static final CmsRelationFilter SOURCES = new CmsRelationFilter(true, false); 050 051 /** To filter all targets. */ 052 public static final CmsRelationFilter TARGETS = new CmsRelationFilter(false, true); 053 054 /** If set the filter extends the result to the given path and all its subresources. */ 055 private boolean m_includeSubresources; 056 057 /** To filter relations for a given source path. */ 058 private String m_path; 059 060 /** If set the filter looks for matching targets. */ 061 private boolean m_source; 062 063 /** The structure id of the resource to filter. */ 064 private CmsUUID m_structureId; 065 066 /** If set the filter looks for matching sources. */ 067 private boolean m_target; 068 069 /** The types to filter. */ 070 private Set<CmsRelationType> m_types = new HashSet<CmsRelationType>(); 071 072 /** 073 * Private constructor.<p> 074 * 075 * @param source if set the filter looks for matching targets 076 * @param target if set the filter looks for matching sources 077 */ 078 private CmsRelationFilter(boolean source, boolean target) { 079 080 m_source = source; 081 m_target = target; 082 } 083 084 /** 085 * Utility method which prepares a filter for relations which point *from* a given structure id.<p> 086 * 087 * @param structureId the structure id 088 * 089 * @return the new relation filter 090 */ 091 public static CmsRelationFilter relationsFromStructureId(CmsUUID structureId) { 092 093 return SOURCES.filterStructureId(structureId); 094 } 095 096 /** 097 * Utility method which prepares a filter for relations which point *to* a given structure id.<p> 098 * 099 * @param structureId the structure id 100 * 101 * @return the new relation filter 102 */ 103 public static CmsRelationFilter relationsToStructureId(CmsUUID structureId) { 104 105 return TARGETS.filterStructureId(structureId); 106 } 107 108 /** 109 * @see java.lang.Object#clone() 110 */ 111 @Override 112 public Object clone() { 113 114 CmsRelationFilter filter = new CmsRelationFilter(m_source, m_target); 115 filter.m_structureId = m_structureId; 116 filter.m_types = new HashSet<CmsRelationType>(m_types); 117 filter.m_path = m_path; 118 filter.m_includeSubresources = m_includeSubresources; 119 return filter; 120 } 121 122 /** 123 * Returns an extended filter with defined in content type restriction.<p> 124 * 125 * @return an extended filter with defined in content type restriction 126 */ 127 public CmsRelationFilter filterDefinedInContent() { 128 129 CmsRelationFilter filter = (CmsRelationFilter)clone(); 130 if (filter.m_types.isEmpty()) { 131 filter.m_types.addAll(CmsRelationType.getAllDefinedInContent()); 132 } else { 133 filter.m_types = new HashSet<CmsRelationType>(CmsRelationType.filterDefinedInContent(filter.m_types)); 134 } 135 return filter; 136 } 137 138 /** 139 * Returns an extended filter that will extend the result to the given path and all its subresources.<p> 140 * 141 * @return an extended filter with including subresources 142 */ 143 public CmsRelationFilter filterIncludeChildren() { 144 145 CmsRelationFilter filter = (CmsRelationFilter)clone(); 146 filter.m_includeSubresources = true; 147 return filter; 148 } 149 150 /** 151 * Returns an extended filter with internal type restriction.<p> 152 * 153 * @return an extended filter with internal type restriction 154 */ 155 public CmsRelationFilter filterInternal() { 156 157 CmsRelationFilter filter = (CmsRelationFilter)clone(); 158 if (filter.m_types.isEmpty()) { 159 filter.m_types.addAll(CmsRelationType.getAllInternal()); 160 } else { 161 filter.m_types = new HashSet<CmsRelationType>(CmsRelationType.filterInternal(filter.m_types)); 162 } 163 return filter; 164 } 165 166 /** 167 * Returns an extended filter with not defined in content type restriction.<p> 168 * 169 * @return an extended filter with not defined in content type restriction 170 */ 171 public CmsRelationFilter filterNotDefinedInContent() { 172 173 CmsRelationFilter filter = (CmsRelationFilter)clone(); 174 if (filter.m_types.isEmpty()) { 175 filter.m_types.addAll(CmsRelationType.getAllNotDefinedInContent()); 176 } else { 177 filter.m_types = new HashSet<CmsRelationType>(CmsRelationType.filterNotDefinedInContent(filter.m_types)); 178 } 179 return filter; 180 } 181 182 /** 183 * Returns an extended filter with the given source relation path restriction.<p> 184 * 185 * @param path the source relation path to filter 186 * 187 * @return an extended filter with the given source relation path restriction 188 */ 189 public CmsRelationFilter filterPath(String path) { 190 191 CmsRelationFilter filter = (CmsRelationFilter)clone(); 192 filter.m_path = path; 193 return filter; 194 } 195 196 /** 197 * Returns an extended filter with the given resource (path and id) restriction.<p> 198 * 199 * @param resource the resource to filter 200 * 201 * @return an extended filter with the given resource (path and id) restriction 202 */ 203 public CmsRelationFilter filterResource(CmsResource resource) { 204 205 CmsRelationFilter filter = filterStructureId(resource.getStructureId()); 206 filter = filterPath(resource.getRootPath()); 207 return filter; 208 } 209 210 /** 211 * Returns an extended filter with strong type restriction.<p> 212 * 213 * @return an extended filter with strong type restriction 214 */ 215 public CmsRelationFilter filterStrong() { 216 217 CmsRelationFilter filter = (CmsRelationFilter)clone(); 218 if (filter.m_types.isEmpty()) { 219 filter.m_types.addAll(CmsRelationType.getAllStrong()); 220 } else { 221 filter.m_types = new HashSet<CmsRelationType>(CmsRelationType.filterStrong(filter.m_types)); 222 } 223 return filter; 224 } 225 226 /** 227 * Returns an extended filter with the given structure id restriction.<p> 228 * 229 * @param structureId the structure id to filter 230 * 231 * @return an extended filter with the given structure id restriction 232 */ 233 public CmsRelationFilter filterStructureId(CmsUUID structureId) { 234 235 CmsRelationFilter filter = (CmsRelationFilter)clone(); 236 filter.m_structureId = structureId; 237 return filter; 238 } 239 240 /** 241 * Returns an extended filter with the given type restriction.<p> 242 * 243 * @param type the relation type to filter 244 * 245 * @return an extended filter with the given type restriction 246 */ 247 public CmsRelationFilter filterType(CmsRelationType type) { 248 249 CmsRelationFilter filter = (CmsRelationFilter)clone(); 250 filter.m_types.add(type); 251 return filter; 252 } 253 254 /** 255 * Returns an extended filter with user defined type restriction.<p> 256 * 257 * @return an extended filter with user defined type restriction 258 */ 259 public CmsRelationFilter filterUserDefined() { 260 261 CmsRelationFilter filter = (CmsRelationFilter)clone(); 262 if (filter.m_types.isEmpty()) { 263 filter.m_types.addAll(CmsRelationType.getAllUserDefined()); 264 } else { 265 filter.m_types = new HashSet<CmsRelationType>(CmsRelationType.filterUserDefined(filter.m_types)); 266 } 267 return filter; 268 } 269 270 /** 271 * Returns an extended filter with weak type restriction.<p> 272 * 273 * @return an extended filter with weak type restriction 274 */ 275 public CmsRelationFilter filterWeak() { 276 277 CmsRelationFilter filter = (CmsRelationFilter)clone(); 278 if (filter.m_types.isEmpty()) { 279 filter.m_types.addAll(CmsRelationType.getAllWeak()); 280 } else { 281 filter.m_types = new HashSet<CmsRelationType>(CmsRelationType.filterWeak(filter.m_types)); 282 } 283 return filter; 284 } 285 286 /** 287 * Returns the source relation path restriction.<p> 288 * 289 * @return the source relation path restriction 290 */ 291 public String getPath() { 292 293 return m_path; 294 } 295 296 /** 297 * Returns the structure Id of the resource to filter.<p> 298 * 299 * @return the structure Id of the resource to filter 300 */ 301 public CmsUUID getStructureId() { 302 303 return m_structureId; 304 } 305 306 /** 307 * Returns the types to filter.<p> 308 * 309 * @return the types to filter 310 */ 311 public Set<CmsRelationType> getTypes() { 312 313 return Collections.unmodifiableSet(m_types); 314 } 315 316 /** 317 * Checks if this filter includes relations defined in the content.<p> 318 * 319 * @return <code>true</code> if this filter includes relations defined in the content 320 */ 321 public boolean includesDefinedInContent() { 322 323 if ((m_types == null) || m_types.isEmpty()) { 324 return true; 325 } 326 Iterator<CmsRelationType> itTypes = m_types.iterator(); 327 while (itTypes.hasNext()) { 328 CmsRelationType type = itTypes.next(); 329 if (type.isDefinedInContent()) { 330 return true; 331 } 332 } 333 return false; 334 } 335 336 /** 337 * Returns the include subresources flag.<p> 338 * 339 * @return if set the filter extends the result to the given path and all its subresources 340 */ 341 public boolean isIncludeSubresources() { 342 343 return m_includeSubresources; 344 } 345 346 /** 347 * Returns the source flag.<p> 348 * 349 * @return if set the filter looks for matching targets 350 */ 351 public boolean isSource() { 352 353 return m_source; 354 } 355 356 /** 357 * Returns the target flag.<p> 358 * 359 * @return if set the filter looks for matching sources 360 */ 361 public boolean isTarget() { 362 363 return m_target; 364 } 365 366 /** 367 * Returns <code>true</code> if the given relation type matches this filter.<p> 368 * 369 * @param type the relation type to test 370 * 371 * @return if the given relation type matches this filter 372 */ 373 public boolean matchType(CmsRelationType type) { 374 375 if (m_types.isEmpty()) { 376 return true; 377 } 378 return m_types.contains(type); 379 } 380 381 /** 382 * @see java.lang.Object#toString() 383 */ 384 @Override 385 public String toString() { 386 387 StringBuffer str = new StringBuffer(128); 388 str.append("["); 389 String mode = null; 390 if (m_source) { 391 if (m_target) { 392 mode = "both"; 393 } else { 394 mode = "source"; 395 } 396 } else { 397 if (m_target) { 398 mode = "target"; 399 } else { 400 mode = "none"; 401 } 402 } 403 str.append(mode).append("=").append(m_structureId).append(", "); 404 str.append("path").append("=").append(m_path).append(", "); 405 str.append("types").append("=").append(m_types).append(", "); 406 str.append("subresources").append("=").append(m_includeSubresources); 407 str.append("]"); 408 return str.toString(); 409 } 410}