View Javadoc
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 }