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.db; 029 030import org.opencms.file.CmsGroup; 031import org.opencms.file.CmsObject; 032import org.opencms.file.CmsResource; 033import org.opencms.file.CmsResourceFilter; 034import org.opencms.file.CmsUser; 035import org.opencms.file.history.I_CmsHistoryResource; 036import org.opencms.main.CmsException; 037import org.opencms.main.CmsRuntimeException; 038import org.opencms.main.OpenCms; 039import org.opencms.security.CmsPrincipal; 040import org.opencms.security.CmsRole; 041import org.opencms.security.CmsRoleViolationException; 042import org.opencms.util.CmsStringUtil; 043 044import java.util.List; 045 046/** 047 * Manager that provides methods to subscribe resources to users, read subscribed or unvisited resources and more.<p> 048 * 049 * @since 8.0 050 */ 051public class CmsSubscriptionManager { 052 053 /** The default maximum number of visited resources to store per user. */ 054 private static final int DEFAULT_MAX_VISITEDCOUNT = 1000; 055 056 /** The security manager to access the cms. */ 057 protected CmsSecurityManager m_securityManager; 058 059 /** Indicates if the subscription functionality is enabled. */ 060 private boolean m_enabled; 061 062 /** Indicates if the configuration can be modified. */ 063 private boolean m_frozen; 064 065 /** The maximum number of visited resources to store per user. */ 066 private int m_maxVisitedCount; 067 068 /** The name of the database pool to use. */ 069 private String m_poolName; 070 071 /** 072 * Initializes a new CmsSubscriptionManager, called from the configuration.<p> 073 */ 074 public CmsSubscriptionManager() { 075 076 m_frozen = false; 077 } 078 079 /** 080 * Returns the date when the resource was last visited by the user.<p> 081 * 082 * @param cms the current users context 083 * @param user the user to check the date 084 * @param resource the resource to check the date 085 * 086 * @return the date when the resource was last visited by the user 087 * 088 * @throws CmsException if something goes wrong 089 */ 090 public long getDateLastVisitedBy(CmsObject cms, CmsUser user, CmsResource resource) throws CmsException { 091 092 return m_securityManager.getDateLastVisitedBy(cms.getRequestContext(), getPoolName(), user, resource); 093 } 094 095 /** 096 * Returns the date when the resource was last visited by the user.<p> 097 * 098 * @param cms the current users context 099 * @param user the user to check the date 100 * @param resourcePath the name of the resource to check the date 101 * 102 * @return the date when the resource was last visited by the user 103 * 104 * @throws CmsException if something goes wrong 105 */ 106 public long getDateLastVisitedBy(CmsObject cms, CmsUser user, String resourcePath) throws CmsException { 107 108 CmsResource resource = cms.readResource(resourcePath, CmsResourceFilter.ALL); 109 return m_securityManager.getDateLastVisitedBy(cms.getRequestContext(), getPoolName(), user, resource); 110 } 111 112 /** 113 * Returns the maximum number of visited resources to store per user.<p> 114 * 115 * @return the maximum number of visited resources to store per user 116 */ 117 public int getMaxVisitedCount() { 118 119 if (m_maxVisitedCount < 1) { 120 m_maxVisitedCount = DEFAULT_MAX_VISITEDCOUNT; 121 } 122 return m_maxVisitedCount; 123 } 124 125 /** 126 * Returns the name of the database pool to use.<p> 127 * 128 * @return the name of the database pool to use 129 */ 130 public String getPoolName() { 131 132 if (CmsStringUtil.isEmpty(m_poolName)) { 133 // use default pool as pool name 134 m_poolName = OpenCms.getSqlManager().getDefaultDbPoolName(); 135 } 136 return m_poolName; 137 } 138 139 /** 140 * Initializes this subscription manager with the OpenCms system configuration.<p> 141 * 142 * @param cms an OpenCms context object that must have been initialized with "Admin" permissions 143 * 144 * @throws CmsRoleViolationException in case the given opencms object does not have <code>{@link CmsRole#ROOT_ADMIN}</code> permissions 145 */ 146 public void initialize(CmsObject cms) throws CmsRoleViolationException { 147 148 OpenCms.getRoleManager().checkRole(cms, CmsRole.ROOT_ADMIN); 149 m_frozen = true; 150 } 151 152 /** 153 * Returns if the subscription functionality is enabled.<p> 154 * 155 * @return <code>true</code> if the subscription functionality is enabled, otherwise <code>false</code> 156 */ 157 public boolean isEnabled() { 158 159 return m_enabled && (m_securityManager != null) && m_securityManager.isSubscriptionDriverAvailable(); 160 } 161 162 /** 163 * Mark the given resource as visited by the user.<p> 164 * 165 * @param cms the current users context 166 * @param resource the resource to mark as visited 167 * @param user the user that visited the resource 168 * 169 * @throws CmsException if something goes wrong 170 */ 171 public void markResourceAsVisitedBy(CmsObject cms, CmsResource resource, CmsUser user) throws CmsException { 172 173 if (!isEnabled()) { 174 throw new CmsRuntimeException(Messages.get().container(Messages.ERR_SUBSCRIPTION_MANAGER_DISABLED_0)); 175 } 176 m_securityManager.markResourceAsVisitedBy(cms.getRequestContext(), getPoolName(), resource, user); 177 } 178 179 /** 180 * Mark the given resource as visited by the user.<p> 181 * 182 * @param cms the current users context 183 * @param resourcePath the name of the resource to mark as visited 184 * @param user the user that visited the resource 185 * 186 * @throws CmsException if something goes wrong 187 */ 188 public void markResourceAsVisitedBy(CmsObject cms, String resourcePath, CmsUser user) throws CmsException { 189 190 CmsResource resource = cms.readResource(resourcePath, CmsResourceFilter.ALL); 191 markResourceAsVisitedBy(cms, resource, user); 192 } 193 194 /** 195 * Returns all resources subscribed by the given user or group.<p> 196 * 197 * @param cms the current users context 198 * @param principal the principal to read the subscribed resources 199 * 200 * @return all resources subscribed by the given user or group 201 * 202 * @throws CmsException if something goes wrong 203 */ 204 public List<CmsResource> readAllSubscribedResources(CmsObject cms, CmsPrincipal principal) throws CmsException { 205 206 return m_securityManager.readAllSubscribedResources(cms.getRequestContext(), getPoolName(), principal); 207 } 208 209 /** 210 * Returns the resources that were visited by a user set in the filter.<p> 211 * 212 * @param cms the current users context 213 * @param filter the filter that is used to get the visited resources 214 * 215 * @return the resources that were visited by a user set in the filter 216 * 217 * @throws CmsException if something goes wrong 218 */ 219 public List<CmsResource> readResourcesVisitedBy(CmsObject cms, CmsVisitedByFilter filter) throws CmsException { 220 221 return m_securityManager.readResourcesVisitedBy(cms.getRequestContext(), getPoolName(), filter); 222 } 223 224 /** 225 * Returns the subscribed history resources that were deleted.<p> 226 * 227 * @param cms the current users context 228 * @param user the user that subscribed to the resource 229 * @param includeGroups indicates if the users groups should also be checked for subscribed deleted resources 230 * @param folderPath the folder path of the deleted resources, if <code>null</code> all deleted resources will be returned 231 * @param includeSubFolders indicates if the sub folders of the specified folder path should be considered, too 232 * @param deletedFrom the time stamp from which the resources should have been deleted 233 * 234 * @return the subscribed history resources that were deleted 235 * 236 * @throws CmsException if something goes wrong 237 */ 238 public List<I_CmsHistoryResource> readSubscribedDeletedResources( 239 CmsObject cms, 240 CmsUser user, 241 boolean includeGroups, 242 String folderPath, 243 boolean includeSubFolders, 244 long deletedFrom) throws CmsException { 245 246 List<CmsGroup> groups = null; 247 if (includeGroups) { 248 try { 249 groups = cms.getGroupsOfUser(user.getName(), false); 250 } catch (CmsException e) { 251 // failed to set user groups 252 } 253 } 254 CmsResource resource = null; 255 if (CmsStringUtil.isNotEmpty(folderPath)) { 256 resource = cms.readResource(folderPath, CmsResourceFilter.ALL); 257 } 258 return m_securityManager.readSubscribedDeletedResources( 259 cms.getRequestContext(), 260 getPoolName(), 261 user, 262 groups, 263 resource, 264 includeSubFolders, 265 deletedFrom); 266 } 267 268 /** 269 * Returns the resources that were subscribed by a user or group set in the filter.<p> 270 * 271 * @param cms the current users context 272 * @param filter the filter that is used to get the subscribed resources 273 * 274 * @return the resources that were subscribed by a user or group set in the filter 275 * 276 * @throws CmsException if something goes wrong 277 */ 278 public List<CmsResource> readSubscribedResources(CmsObject cms, CmsSubscriptionFilter filter) throws CmsException { 279 280 return m_securityManager.readSubscribedResources(cms.getRequestContext(), getPoolName(), filter); 281 } 282 283 /** 284 * Sets if the subscription functionality is enabled.<p> 285 * 286 * @param enabled the flag indicating if the subscription functionality is enabled 287 */ 288 public void setEnabled(boolean enabled) { 289 290 if (m_frozen) { 291 throw new CmsRuntimeException(Messages.get().container(Messages.ERR_CONFIG_SUBSCRIPTIONMANAGER_FROZEN_0)); 292 } 293 m_enabled = enabled; 294 } 295 296 /** 297 * Sets if the subscription functionality is enabled.<p> 298 * 299 * @param enabled the flag indicating if the subscription functionality is enabled 300 */ 301 public void setEnabled(String enabled) { 302 303 if (m_frozen) { 304 throw new CmsRuntimeException(Messages.get().container(Messages.ERR_CONFIG_SUBSCRIPTIONMANAGER_FROZEN_0)); 305 } 306 m_enabled = Boolean.valueOf(enabled).booleanValue(); 307 } 308 309 /** 310 * Sets the maximum number of visited resources to store per user.<p> 311 * 312 * @param maxVisitedCount the maximum number of visited resources to store per user 313 */ 314 public void setMaxVisitedCount(String maxVisitedCount) { 315 316 if (m_frozen) { 317 throw new CmsRuntimeException(Messages.get().container(Messages.ERR_CONFIG_SUBSCRIPTIONMANAGER_FROZEN_0)); 318 } 319 try { 320 int intValue = Integer.parseInt(maxVisitedCount); 321 m_maxVisitedCount = (intValue > 0) ? intValue : DEFAULT_MAX_VISITEDCOUNT; 322 } catch (NumberFormatException e) { 323 // use default value 324 m_maxVisitedCount = DEFAULT_MAX_VISITEDCOUNT; 325 } 326 } 327 328 /** 329 * Sets the name of the database pool to use.<p> 330 * 331 * @param poolName the name of the database pool to use 332 */ 333 public void setPoolName(String poolName) { 334 335 if (m_frozen) { 336 throw new CmsRuntimeException(Messages.get().container(Messages.ERR_CONFIG_SUBSCRIPTIONMANAGER_FROZEN_0)); 337 } 338 m_poolName = poolName; 339 } 340 341 /** 342 * Sets the security manager during initialization.<p> 343 * 344 * @param securityManager the security manager 345 */ 346 public void setSecurityManager(CmsSecurityManager securityManager) { 347 348 if (m_frozen) { 349 throw new CmsRuntimeException(Messages.get().container(Messages.ERR_CONFIG_SUBSCRIPTIONMANAGER_FROZEN_0)); 350 } 351 m_securityManager = securityManager; 352 } 353 354 /** 355 * Marks a subscribed resource as deleted.<p> 356 * 357 * @param cms the current users context 358 * @param resource the subscribed resource to mark as deleted 359 * 360 * @throws CmsException if something goes wrong 361 */ 362 public void setSubscribedResourceAsDeleted(CmsObject cms, CmsResource resource) throws CmsException { 363 364 if (!isEnabled()) { 365 throw new CmsRuntimeException(Messages.get().container(Messages.ERR_SUBSCRIPTION_MANAGER_DISABLED_0)); 366 } 367 m_securityManager.setSubscribedResourceAsDeleted(cms.getRequestContext(), getPoolName(), resource); 368 } 369 370 /** 371 * Subscribes the user or group to the resource.<p> 372 * 373 * @param cms the current users context 374 * @param principal the principal that subscribes to the resource 375 * @param resource the resource to subscribe to 376 * 377 * @throws CmsException if something goes wrong 378 */ 379 public void subscribeResourceFor(CmsObject cms, CmsPrincipal principal, CmsResource resource) throws CmsException { 380 381 if (!isEnabled()) { 382 throw new CmsRuntimeException(Messages.get().container(Messages.ERR_SUBSCRIPTION_MANAGER_DISABLED_0)); 383 } 384 m_securityManager.subscribeResourceFor(cms.getRequestContext(), getPoolName(), principal, resource); 385 } 386 387 /** 388 * Subscribes the user or group to the resource.<p> 389 * 390 * @param cms the current users context 391 * @param principal the principal that subscribes to the resource 392 * @param resourcePath the name of the resource to subscribe to 393 * 394 * @throws CmsException if something goes wrong 395 */ 396 public void subscribeResourceFor(CmsObject cms, CmsPrincipal principal, String resourcePath) throws CmsException { 397 398 CmsResource resource = cms.readResource(resourcePath, CmsResourceFilter.ALL); 399 subscribeResourceFor(cms, principal, resource); 400 } 401 402 /** 403 * Unsubscribes all deleted resources that were deleted before the specified time stamp.<p> 404 * 405 * @param cms the current users context 406 * @param deletedTo the time stamp to which the resources have been deleted 407 * 408 * @throws CmsException if something goes wrong 409 */ 410 public void unsubscribeAllDeletedResources(CmsObject cms, long deletedTo) throws CmsException { 411 412 if (!isEnabled()) { 413 throw new CmsRuntimeException(Messages.get().container(Messages.ERR_SUBSCRIPTION_MANAGER_DISABLED_0)); 414 } 415 m_securityManager.unsubscribeAllDeletedResources(cms.getRequestContext(), getPoolName(), deletedTo); 416 } 417 418 /** 419 * Unsubscribes the user or group from all resources.<p> 420 * 421 * @param cms the current users context 422 * @param principal the principal that unsubscribes from all resources 423 * 424 * @throws CmsException if something goes wrong 425 */ 426 public void unsubscribeAllResourcesFor(CmsObject cms, CmsPrincipal principal) throws CmsException { 427 428 if (!isEnabled()) { 429 throw new CmsRuntimeException(Messages.get().container(Messages.ERR_SUBSCRIPTION_MANAGER_DISABLED_0)); 430 } 431 m_securityManager.unsubscribeAllResourcesFor(cms.getRequestContext(), getPoolName(), principal); 432 } 433 434 /** 435 * Unsubscribes the principal from the resource.<p> 436 * 437 * @param cms the current users context 438 * @param principal the principal that unsubscribes from the resource 439 * @param resource the resource to unsubscribe from 440 * 441 * @throws CmsException if something goes wrong 442 */ 443 public void unsubscribeResourceFor(CmsObject cms, CmsPrincipal principal, CmsResource resource) 444 throws CmsException { 445 446 if (!isEnabled()) { 447 throw new CmsRuntimeException(Messages.get().container(Messages.ERR_SUBSCRIPTION_MANAGER_DISABLED_0)); 448 } 449 m_securityManager.unsubscribeResourceFor(cms.getRequestContext(), getPoolName(), principal, resource); 450 } 451 452 /** 453 * Unsubscribes the principal from the resource.<p> 454 * 455 * @param cms the current users context 456 * @param principal the principal that unsubscribes from the resource 457 * @param resourcePath the name of the resource to unsubscribe from 458 * 459 * @throws CmsException if something goes wrong 460 */ 461 public void unsubscribeResourceFor(CmsObject cms, CmsPrincipal principal, String resourcePath) throws CmsException { 462 463 CmsResource resource = cms.readResource(resourcePath, CmsResourceFilter.ALL); 464 unsubscribeResourceFor(cms, principal, resource); 465 } 466 467 /** 468 * Unsubscribes all groups and users from the resource.<p> 469 * 470 * @param cms the current users context 471 * @param resource the resource to unsubscribe all groups and users from 472 * 473 * @throws CmsException if something goes wrong 474 */ 475 public void unsubscribeResourceForAll(CmsObject cms, CmsResource resource) throws CmsException { 476 477 if (!isEnabled()) { 478 throw new CmsRuntimeException(Messages.get().container(Messages.ERR_SUBSCRIPTION_MANAGER_DISABLED_0)); 479 } 480 m_securityManager.unsubscribeResourceForAll(cms.getRequestContext(), getPoolName(), resource); 481 } 482 483 /** 484 * Unsubscribes all groups and users from the resource.<p> 485 * 486 * @param cms the current users context 487 * @param resourcePath the name of the resource to unsubscribe all groups and users from 488 * 489 * @throws CmsException if something goes wrong 490 */ 491 public void unsubscribeResourceForAll(CmsObject cms, String resourcePath) throws CmsException { 492 493 CmsResource resource = cms.readResource(resourcePath, CmsResourceFilter.ALL); 494 unsubscribeResourceForAll(cms, resource); 495 } 496 497}