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.lock; 029 030import org.opencms.file.CmsUser; 031import org.opencms.util.CmsUUID; 032 033import java.util.Collections; 034import java.util.HashSet; 035import java.util.Set; 036 037/** 038 * A filter to retrieve the locks.<p> 039 * 040 * @since 6.5.4 041 */ 042public final class CmsLockFilter implements Cloneable { 043 044 /** To filter all locks. */ 045 public static final CmsLockFilter FILTER_ALL = new CmsLockFilter(true).filterIncludeChildren(); 046 047 /** To filter all inherited locks. */ 048 public static final CmsLockFilter FILTER_INHERITED = new CmsLockFilter(true); 049 050 /** To filter all non inherited locks. */ 051 public static final CmsLockFilter FILTER_NON_INHERITED = new CmsLockFilter(false); 052 053 /** If set the filter restricts the result excluding locks owned by the given user. */ 054 private CmsUUID m_notOwnedByUserId; 055 056 /** If set the filter extends the result to non inherited locks. */ 057 private boolean m_includeChildren; 058 059 /** If set the filter restricts the result including only locks owned by the given user. */ 060 private CmsUUID m_ownedByUserId; 061 062 /** If set the filter extends the result to inherited locks. */ 063 private boolean m_includeParents; 064 065 /** If set the filter restricts the result to the given project. */ 066 private CmsUUID m_projectId; 067 068 /** If set the filter also matches shared exclusive locks. */ 069 private boolean m_sharedExclusive; 070 071 /** The types to filter. */ 072 private Set<CmsLockType> m_types = new HashSet<CmsLockType>(); 073 074 /** If set the filter restricts the result excluding locks not lockable by the given user. */ 075 private CmsUser m_notLockableByUser; 076 077 /** If set the filter restricts the result including only locks lockable by the given user. */ 078 private CmsUser m_lockableByUser; 079 080 /** 081 * Private constructor.<p> 082 * 083 * @param inherited if the this lock filter should checks inherited locks or not 084 */ 085 private CmsLockFilter(boolean inherited) { 086 087 m_includeChildren = !inherited; 088 m_includeParents = inherited; 089 } 090 091 /** 092 * @see java.lang.Object#clone() 093 */ 094 @Override 095 public Object clone() { 096 097 CmsLockFilter filter = new CmsLockFilter(false); 098 filter.m_includeChildren = m_includeChildren; 099 filter.m_includeParents = m_includeParents; 100 filter.m_types = new HashSet<CmsLockType>(m_types); 101 filter.m_ownedByUserId = m_ownedByUserId; 102 filter.m_notOwnedByUserId = m_notOwnedByUserId; 103 filter.m_projectId = m_projectId; 104 filter.m_notLockableByUser = m_notLockableByUser; 105 filter.m_lockableByUser = m_lockableByUser; 106 return filter; 107 } 108 109 /** 110 * Returns an extended filter with the given user restriction.<p> 111 * 112 * @param userId the user id to filter 113 * 114 * @return an extended filter with the given user restriction 115 */ 116 public CmsLockFilter filterNotOwnedByUserId(CmsUUID userId) { 117 118 CmsLockFilter filter = (CmsLockFilter)clone(); 119 filter.m_notOwnedByUserId = userId; 120 return filter; 121 } 122 123 /** 124 * Returns an extended filter with the given user restriction.<p> 125 * 126 * @param user the user to filter 127 * 128 * @return an extended filter with the given user restriction 129 */ 130 public CmsLockFilter filterNotLockableByUser(CmsUser user) { 131 132 CmsLockFilter filter = (CmsLockFilter)clone(); 133 filter.m_notLockableByUser = user; 134 return filter; 135 } 136 137 /** 138 * Returns an extended filter with the given user restriction.<p> 139 * 140 * @param user the user to filter 141 * 142 * @return an extended filter with the given user restriction 143 */ 144 public CmsLockFilter filterLockableByUser(CmsUser user) { 145 146 CmsLockFilter filter = (CmsLockFilter)clone(); 147 filter.m_lockableByUser = user; 148 return filter; 149 } 150 151 /** 152 * Returns an extended filter that will extend the result to the given path and all its children.<p> 153 * 154 * @return an extended filter to search the subresources of the given path 155 */ 156 public CmsLockFilter filterIncludeChildren() { 157 158 CmsLockFilter filter = (CmsLockFilter)clone(); 159 filter.m_includeChildren = true; 160 return filter; 161 } 162 163 /** 164 * Returns an extended filter with the given user restriction.<p> 165 * 166 * @param userId the user id to filter 167 * 168 * @return an extended filter with the given user restriction 169 */ 170 public CmsLockFilter filterOwnedByUserId(CmsUUID userId) { 171 172 CmsLockFilter filter = (CmsLockFilter)clone(); 173 filter.m_ownedByUserId = userId; 174 return filter; 175 } 176 177 /** 178 * Returns an extended filter that will extend the result to the given path and all its parents.<p> 179 * 180 * @return an extended filter to search the subresources of the given path 181 */ 182 public CmsLockFilter filterIncludeParents() { 183 184 CmsLockFilter filter = (CmsLockFilter)clone(); 185 filter.m_includeParents = true; 186 return filter; 187 } 188 189 /** 190 * Returns an extended filter with the given project restriction.<p> 191 * 192 * @param projectId the project to filter the locks with 193 * 194 * @return an extended filter with the given project restriction 195 */ 196 public CmsLockFilter filterProject(CmsUUID projectId) { 197 198 CmsLockFilter filter = (CmsLockFilter)clone(); 199 filter.m_projectId = projectId; 200 return filter; 201 } 202 203 /** 204 * Returns an extended filter that also matches shared exclusive locks (siblings).<p> 205 * 206 * @return an extended filter that also matches shared exclusive locks 207 */ 208 public CmsLockFilter filterSharedExclusive() { 209 210 CmsLockFilter filter = (CmsLockFilter)clone(); 211 filter.m_sharedExclusive = true; 212 return filter; 213 } 214 215 /** 216 * Returns an extended filter with the given type restriction.<p> 217 * 218 * @param type the lock type to filter 219 * 220 * @return an extended filter with the given type restriction 221 */ 222 public CmsLockFilter filterType(CmsLockType type) { 223 224 CmsLockFilter filter = (CmsLockFilter)clone(); 225 filter.m_types.add(type); 226 return filter; 227 } 228 229 /** 230 * Returns the user that has to own the locks.<p> 231 * 232 * @return the user that has to own the locks 233 */ 234 public CmsUUID getOwnedByUserId() { 235 236 return m_ownedByUserId; 237 } 238 239 /** 240 * Returns the user that has not to own the locks.<p> 241 * 242 * @return the user that has not to own the locks 243 */ 244 public CmsUUID getNotOwnedByUserId() { 245 246 return m_notOwnedByUserId; 247 } 248 249 /** 250 * Returns the user that can overwrite the locks.<p> 251 * 252 * @return the user that can overwrite the locks 253 */ 254 public CmsUser getLockableByUserId() { 255 256 return m_lockableByUser; 257 } 258 259 /** 260 * Returns the user that can not overwrite the locks.<p> 261 * 262 * @return the user that can not overwrite the locks 263 */ 264 public CmsUser getNotLockableByUserId() { 265 266 return m_notLockableByUser; 267 } 268 269 /** 270 * Returns the project restriction.<p> 271 * 272 * @return the project restriction 273 */ 274 public CmsUUID getProjectId() { 275 276 return m_projectId; 277 } 278 279 /** 280 * Returns the types to filter.<p> 281 * 282 * @return the types to filter 283 */ 284 public Set<CmsLockType> getTypes() { 285 286 return Collections.unmodifiableSet(m_types); 287 } 288 289 /** 290 * Returns the include children flag.<p> 291 * 292 * @return if set the filter extends the result to the given path and all its children 293 */ 294 public boolean isIncludeChildren() { 295 296 return m_includeChildren; 297 } 298 299 /** 300 * Returns the include parents flag.<p> 301 * 302 * @return if set the filter extends the result to the given path and all its parents 303 */ 304 public boolean isIncludeParent() { 305 306 return m_includeParents; 307 } 308 309 /** 310 * Returns the <code>true</code> if this filter also matches shared exclusive locks.<p> 311 * 312 * @return the <code>true</code> if this filter also matches shared exclusive locks 313 */ 314 public boolean isSharedExclusive() { 315 316 return m_sharedExclusive; 317 } 318 319 /** 320 * Matches the given lock against this filter and the given path.<p> 321 * 322 * @param rootPath the path to match the lock against 323 * @param lock the lock to match 324 * 325 * @return <code>true</code> if the given lock matches 326 */ 327 public boolean match(String rootPath, CmsLock lock) { 328 329 boolean match = false; 330 if (m_includeChildren) { 331 // safe since rootPath always ends with slash if a folder 332 match = lock.getResourceName().startsWith(rootPath); 333 } 334 if (!match && m_includeParents) { 335 // since parents can only be folders, check it only for folders 336 if (lock.getResourceName().endsWith("/")) { 337 match = rootPath.startsWith(lock.getResourceName()); 338 } 339 } 340 if (match && (m_projectId != null) && !m_projectId.isNullUUID() && (lock.getProjectId() != null)) { 341 match = lock.getProjectId().equals(m_projectId); 342 } 343 if (match && (m_ownedByUserId != null) && !m_ownedByUserId.isNullUUID()) { 344 match = lock.getUserId().equals(m_ownedByUserId); 345 } 346 if (match && (m_notOwnedByUserId != null) && !m_notOwnedByUserId.isNullUUID()) { 347 match = !lock.getUserId().equals(m_notOwnedByUserId); 348 } 349 if (match && (m_lockableByUser != null)) { 350 match = lock.isLockableBy(m_lockableByUser); 351 } 352 if (match && (m_notLockableByUser != null)) { 353 match = !lock.isLockableBy(m_notLockableByUser); 354 } 355 if (match && !m_types.isEmpty()) { 356 match = m_types.contains(lock.getType()); 357 match = match || (m_includeParents && lock.isInherited()); 358 } 359 // check the related lock if available 360 if (!match && !lock.getRelatedLock().isNullLock()) { 361 match = match(rootPath, lock.getRelatedLock()); 362 } 363 return match; 364 } 365 366 /** 367 * @see java.lang.Object#toString() 368 */ 369 @Override 370 public String toString() { 371 372 StringBuffer str = new StringBuffer(128); 373 str.append("["); 374 str.append("children").append("=").append(m_includeChildren).append(", "); 375 str.append("parents").append("=").append(m_includeParents).append(", "); 376 str.append("types").append("=").append(m_types).append(", "); 377 str.append("includedUser").append("=").append(m_ownedByUserId).append(", "); 378 str.append("excludedUser").append("=").append(m_notOwnedByUserId).append(", "); 379 str.append("project").append("=").append(m_projectId).append(", "); 380 str.append("lockableBy").append("=").append(m_lockableByUser).append(", "); 381 str.append("notLockableBy").append("=").append(m_notLockableByUser).append(", "); 382 str.append("includeShared").append("=").append(m_sharedExclusive); 383 str.append("]"); 384 return str.toString(); 385 } 386}