001/** 002 * Copyright 2005-2018 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.rice.krad.document; 017 018import org.kuali.rice.kim.api.identity.Person; 019import org.kuali.rice.krad.datadictionary.DocumentEntry; 020import org.kuali.rice.krad.document.authorization.PessimisticLock; 021import org.kuali.rice.krad.service.DataDictionaryService; 022import org.kuali.rice.krad.service.KRADServiceLocatorWeb; 023 024/** 025 * Base class for all Transactional Document authorizers. 026 * 027 * @author Kuali Rice Team (rice.collab@kuali.org) 028 */ 029public class TransactionalDocumentAuthorizerBase extends DocumentAuthorizerBase implements TransactionalDocumentAuthorizer { 030 031 private static final long serialVersionUID = 3255133642834256283L; 032 033 private DataDictionaryService dataDictionaryService; 034 035 /** 036 * {@inheritDoc} 037 * 038 * <p> 039 * The {@code user} can only close the {@code document} if it is a transactional document. 040 * </p> 041 */ 042 @Override 043 public boolean canClose(Document document, Person user) { 044 return true; 045 } 046 047 /** 048 * {@inheritDoc} 049 * 050 * <p> 051 * The {@code user} can only save the {@code document} if they have permission and, if pessimistic locking is turned 052 * on for the {@code document}, they can establish a pessimistic lock. 053 * </p> 054 */ 055 @Override 056 public boolean canSave(Document document, Person user) { 057 boolean canSave = super.canSave(document, user); 058 059 if (!isUsingPessimisticLocking(document)) { 060 return canSave; 061 } 062 063 return canSave && canEstablishPessimisticLock(document, user); 064 } 065 066 /** 067 * {@inheritDoc} 068 * 069 * <p> 070 * The {@code user} can only route the {@code document} if they have permission and, if pessimistic locking is 071 * turned on for the {@code document}, they can establish a pessimistic lock. 072 * </p> 073 */ 074 @Override 075 public boolean canRoute(Document document, Person user) { 076 boolean canRoute = super.canRoute(document, user); 077 078 if (!isUsingPessimisticLocking(document)) { 079 return canRoute; 080 } 081 082 return canRoute && canEstablishPessimisticLock(document, user); 083 } 084 085 /** 086 * {@inheritDoc} 087 * 088 * <p> 089 * The {@code user} can only cancel the {@code document} if they have permission and, if pessimistic locking is 090 * turned on for the {@code document}, they can establish a pessimistic lock. 091 * </p> 092 */ 093 @Override 094 public boolean canCancel(Document document, Person user) { 095 boolean canCancel = super.canCancel(document, user); 096 097 if (!isUsingPessimisticLocking(document)) { 098 return canCancel; 099 } 100 101 return canCancel && canEstablishPessimisticLock(document, user); 102 } 103 104 /** 105 * {@inheritDoc} 106 * 107 * <p> 108 * The {@code user} can only blanket approve the {@code document} if they have permission and, if pessimistic 109 * locking is turned on for the {@code document}, they can establish a pessimistic lock. 110 * </p> 111 */ 112 @Override 113 public boolean canBlanketApprove(Document document, Person user) { 114 boolean canBlanketApprove = super.canBlanketApprove(document, user); 115 116 if (!isUsingPessimisticLocking(document)) { 117 return canBlanketApprove; 118 } 119 120 return canBlanketApprove && canEstablishPessimisticLock(document, user); 121 } 122 123 /** 124 * Returns whether the {@code document} is using pessimistic locking. 125 * 126 * @param document the document to check for using pessimistic locking 127 * 128 * @return true if the {@code document} is using pessimistic locking, false otherwise. 129 */ 130 protected boolean isUsingPessimisticLocking(Document document) { 131 String documentClassName = document.getClass().getName(); 132 DocumentEntry documentEntry = getDataDictionaryService().getDataDictionary().getDocumentEntry(documentClassName); 133 134 return documentEntry.getUsePessimisticLocking(); 135 } 136 137 /** 138 * Returns whether {@code user} can establish a pessimistic lock on the document. 139 * 140 * <p> 141 * The {@code user} can only establish a pessimistic lock on the document {@code document} if there are no existing 142 * locks or if they already have a lock on the {@code document}. 143 * </p> 144 * 145 * @param document the document to check for pessimistic locks 146 * @param user the user to check for pessimistic locks 147 * 148 * @return true if the {@code user} can establish a pessimistic lock on the document, false otherwise 149 */ 150 protected boolean canEstablishPessimisticLock(Document document, Person user) { 151 if (document.getPessimisticLocks().isEmpty()) { 152 return true; 153 } 154 155 for (PessimisticLock pessimisticLock : document.getPessimisticLocks()) { 156 if (pessimisticLock.isOwnedByUser(user)) { 157 return true; 158 } 159 } 160 161 return false; 162 } 163 164 protected DataDictionaryService getDataDictionaryService() { 165 if (dataDictionaryService == null) { 166 dataDictionaryService = KRADServiceLocatorWeb.getDataDictionaryService(); 167 } 168 169 return dataDictionaryService; 170 } 171 172 protected void setDataDictionaryService(DataDictionaryService dataDictionaryService) { 173 this.dataDictionaryService = dataDictionaryService; 174 } 175 176}