1 /**
2 * Copyright 2005-2016 The Kuali Foundation
3 *
4 * Licensed under the Educational Community License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.opensource.org/licenses/ecl2.php
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.kuali.rice.krad.document;
17
18 import org.kuali.rice.kim.api.identity.Person;
19 import org.kuali.rice.krad.datadictionary.DocumentEntry;
20 import org.kuali.rice.krad.document.authorization.PessimisticLock;
21 import org.kuali.rice.krad.service.DataDictionaryService;
22 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
23
24 /**
25 * Base class for all Transactional Document authorizers.
26 *
27 * @author Kuali Rice Team (rice.collab@kuali.org)
28 */
29 public class TransactionalDocumentAuthorizerBase extends DocumentAuthorizerBase implements TransactionalDocumentAuthorizer {
30
31 private static final long serialVersionUID = 3255133642834256283L;
32
33 private DataDictionaryService dataDictionaryService;
34
35 /**
36 * {@inheritDoc}
37 *
38 * <p>
39 * The {@code user} can only close the {@code document} if it is a transactional document.
40 * </p>
41 */
42 @Override
43 public boolean canClose(Document document, Person user) {
44 return true;
45 }
46
47 /**
48 * {@inheritDoc}
49 *
50 * <p>
51 * The {@code user} can only save the {@code document} if they have permission and, if pessimistic locking is turned
52 * on for the {@code document}, they can establish a pessimistic lock.
53 * </p>
54 */
55 @Override
56 public boolean canSave(Document document, Person user) {
57 boolean canSave = super.canSave(document, user);
58
59 if (!isUsingPessimisticLocking(document)) {
60 return canSave;
61 }
62
63 return canSave && canEstablishPessimisticLock(document, user);
64 }
65
66 /**
67 * {@inheritDoc}
68 *
69 * <p>
70 * The {@code user} can only route the {@code document} if they have permission and, if pessimistic locking is
71 * turned on for the {@code document}, they can establish a pessimistic lock.
72 * </p>
73 */
74 @Override
75 public boolean canRoute(Document document, Person user) {
76 boolean canRoute = super.canRoute(document, user);
77
78 if (!isUsingPessimisticLocking(document)) {
79 return canRoute;
80 }
81
82 return canRoute && canEstablishPessimisticLock(document, user);
83 }
84
85 /**
86 * {@inheritDoc}
87 *
88 * <p>
89 * The {@code user} can only cancel the {@code document} if they have permission and, if pessimistic locking is
90 * turned on for the {@code document}, they can establish a pessimistic lock.
91 * </p>
92 */
93 @Override
94 public boolean canCancel(Document document, Person user) {
95 boolean canCancel = super.canCancel(document, user);
96
97 if (!isUsingPessimisticLocking(document)) {
98 return canCancel;
99 }
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 }