001/** 002 * Copyright 2005-2016 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.kew.impl.doctype; 017 018import org.apache.commons.collections.CollectionUtils; 019import org.apache.commons.lang.StringUtils; 020import org.apache.log4j.Logger; 021import org.kuali.rice.core.api.exception.RiceIllegalArgumentException; 022import org.kuali.rice.kew.api.doctype.DocumentType; 023import org.kuali.rice.kew.api.doctype.DocumentTypeService; 024import org.kuali.rice.kew.api.doctype.ProcessDefinition; 025import org.kuali.rice.kew.api.doctype.RoutePath; 026import org.kuali.rice.kew.api.document.node.RouteNodeInstance; 027import org.kuali.rice.kew.doctype.dao.DocumentTypeDAO; 028import org.kuali.rice.kew.engine.node.ProcessDefinitionBo; 029import org.kuali.rice.kew.engine.node.RouteNode; 030import org.kuali.rice.kew.service.KEWServiceLocator; 031 032import java.util.ArrayList; 033import java.util.Collections; 034import java.util.List; 035 036/** 037 * Reference implementation of the {@link DocumentTypeService}. 038 * 039 * @author Kuali Rice Team (rice.collab@kuali.org) 040 * 041 */ 042public class DocumentTypeServiceImpl implements DocumentTypeService { 043 044 private static final Logger LOG = Logger.getLogger(DocumentTypeServiceImpl.class); 045 046 private DocumentTypeDAO documentTypeDao; 047 048 @Override 049 public String getIdByName(String documentTypeName) { 050 if (StringUtils.isBlank(documentTypeName)) { 051 throw new RiceIllegalArgumentException("documentTypeName was null or blank"); 052 } 053 return documentTypeDao.findDocumentTypeIdByName(documentTypeName); 054 } 055 056 @Override 057 public String getNameById(String documentTypeId) { 058 if (StringUtils.isBlank(documentTypeId)) { 059 throw new RiceIllegalArgumentException("documentTypeId was null or blank"); 060 } 061 return documentTypeDao.findDocumentTypeNameById(documentTypeId); 062 } 063 064 @Override 065 public DocumentType getDocumentTypeById(String documentTypeId) { 066 if (StringUtils.isBlank(documentTypeId)) { 067 throw new RiceIllegalArgumentException("documentTypeId was null or blank"); 068 } 069 org.kuali.rice.kew.doctype.bo.DocumentType documentTypeBo = documentTypeDao.findById(documentTypeId); 070 return org.kuali.rice.kew.doctype.bo.DocumentType.to(documentTypeBo); 071 } 072 073 @Override 074 public org.kuali.rice.kew.api.doctype.DocumentType getDocumentTypeByName(String documentTypeName) { 075 if (StringUtils.isBlank(documentTypeName)) { 076 throw new RiceIllegalArgumentException("documentTypeName was null or blank"); 077 } 078 org.kuali.rice.kew.doctype.bo.DocumentType documentTypeBo = documentTypeDao.findByName(documentTypeName); 079 return org.kuali.rice.kew.doctype.bo.DocumentType.to(documentTypeBo); 080 } 081 082 @Override 083 public List<org.kuali.rice.kew.api.doctype.DocumentType> findAllDocumentTypes() { 084 List<org.kuali.rice.kew.doctype.bo.DocumentType> documentTypeBos = documentTypeDao.findAllCurrent(); 085 List<org.kuali.rice.kew.api.doctype.DocumentType> currentDocTypes = new ArrayList<org.kuali.rice.kew.api.doctype.DocumentType>(); 086 for (org.kuali.rice.kew.doctype.bo.DocumentType dt : documentTypeBos) { 087 currentDocTypes.add(org.kuali.rice.kew.doctype.bo.DocumentType.to(dt)); 088 } 089 return Collections.unmodifiableList(currentDocTypes); 090 } 091 092 @Override 093 public boolean isSuperUserForDocumentTypeId(String principalId, String documentTypeId) { 094 if (LOG.isDebugEnabled()) { 095 LOG.debug("Determining super user status [principalId=" + principalId + ", documentTypeId=" 096 + documentTypeId + "]"); 097 } 098 if (StringUtils.isBlank(principalId)) { 099 throw new RiceIllegalArgumentException("principalId was null or blank"); 100 } 101 if (StringUtils.isBlank(documentTypeId)) { 102 throw new RiceIllegalArgumentException("documentTypeId was null or blank"); 103 } 104 org.kuali.rice.kew.doctype.bo.DocumentType documentType = KEWServiceLocator.getDocumentTypeService().findById(documentTypeId); 105 boolean isSuperUser = KEWServiceLocator.getDocumentTypePermissionService().canAdministerRouting(principalId, 106 documentType); 107 if (LOG.isDebugEnabled()) { 108 LOG.debug("Super user status is " + isSuperUser + "."); 109 } 110 return isSuperUser; 111 112 } 113 114 @Override 115 public boolean isSuperUserForDocumentTypeName(String principalId, String documentTypeName) { 116 if (LOG.isDebugEnabled()) { 117 LOG.debug("Determining super user status [principalId=" + principalId + ", documentTypeName=" 118 + documentTypeName + "]"); 119 } 120 if (StringUtils.isBlank(principalId)) { 121 throw new RiceIllegalArgumentException("principalId was null or blank"); 122 } 123 if (StringUtils.isBlank(documentTypeName)) { 124 throw new RiceIllegalArgumentException("documentTypeId was null or blank"); 125 } 126 org.kuali.rice.kew.doctype.bo.DocumentType documentType = KEWServiceLocator.getDocumentTypeService().findByName(documentTypeName); 127 boolean isSuperUser = KEWServiceLocator.getDocumentTypePermissionService().canAdministerRouting(principalId, 128 documentType); 129 if (LOG.isDebugEnabled()) { 130 LOG.debug("Super user status is " + isSuperUser + "."); 131 } 132 return isSuperUser; 133 134 } 135 136 @Override 137 public boolean canSuperUserApproveSingleActionRequest( String principalId, String documentTypeName, List<RouteNodeInstance> routeNodeInstances, String routeStatusCode ) { 138 139 checkSuperUserInput( principalId, documentTypeName ); 140 141 org.kuali.rice.kew.doctype.bo.DocumentType documentType = KEWServiceLocator.getDocumentTypeService().findByName(documentTypeName); 142 List<org.kuali.rice.kew.engine.node.RouteNodeInstance> currentNodeInstances = null; 143 if (routeNodeInstances != null && !routeNodeInstances.isEmpty()) { 144 currentNodeInstances = KEWServiceLocator.getRouteNodeService().getCurrentNodeInstances(routeNodeInstances.get(0).getDocumentId()); 145 } 146 147 boolean isSuperUser = KEWServiceLocator.getDocumentTypePermissionService().canSuperUserApproveSingleActionRequest( principalId, documentType, 148 currentNodeInstances, routeStatusCode); 149 if (LOG.isDebugEnabled()) { 150 LOG.debug("Super user approve single action request status is " + isSuperUser + "."); 151 } 152 return isSuperUser; 153 } 154 155 @Override 156 public boolean canSuperUserApproveDocument( String principalId, String documentTypeName, List<RouteNodeInstance> routeNodeInstances, String routeStatusCode ) { 157 checkSuperUserInput( principalId, documentTypeName ); 158 159 org.kuali.rice.kew.doctype.bo.DocumentType documentType = KEWServiceLocator.getDocumentTypeService().findByName(documentTypeName); 160 List<org.kuali.rice.kew.engine.node.RouteNodeInstance> currentNodeInstances = null; 161 if (routeNodeInstances != null && !routeNodeInstances.isEmpty()) { 162 currentNodeInstances = KEWServiceLocator.getRouteNodeService().getCurrentNodeInstances(routeNodeInstances.get(0).getDocumentId()); 163 } 164 165 boolean isSuperUser = KEWServiceLocator.getDocumentTypePermissionService().canSuperUserApproveDocument( 166 principalId, documentType, currentNodeInstances, routeStatusCode); 167 if (LOG.isDebugEnabled()) { 168 LOG.debug("Super user approve document status is " + isSuperUser + "."); 169 } 170 return isSuperUser; 171 } 172 173 @Override 174 public boolean canSuperUserDisapproveDocument( String principalId, String documentTypeName, List<RouteNodeInstance> routeNodeInstances, String routeStatusCode ) { 175 checkSuperUserInput( principalId, documentTypeName ); 176 177 org.kuali.rice.kew.doctype.bo.DocumentType documentType = KEWServiceLocator.getDocumentTypeService().findByName(documentTypeName); 178 179 List<org.kuali.rice.kew.engine.node.RouteNodeInstance> currentNodeInstances = null; 180 if (routeNodeInstances != null && !routeNodeInstances.isEmpty()) { 181 currentNodeInstances = KEWServiceLocator.getRouteNodeService().getCurrentNodeInstances(routeNodeInstances.get(0).getDocumentId()); 182 } 183 184 boolean isSuperUser = KEWServiceLocator.getDocumentTypePermissionService().canSuperUserDisapproveDocument( principalId, documentType, 185 currentNodeInstances, routeStatusCode); 186 if (LOG.isDebugEnabled()) { 187 LOG.debug("Super user disapprove document status is " + isSuperUser + "."); 188 } 189 return isSuperUser; 190 } 191 192 private void checkSuperUserInput( String principalId, String documentTypeName ) { 193 if (LOG.isDebugEnabled()) { 194 LOG.debug("Determining super user status [principalId=" + principalId + ", documentTypeName=" 195 + documentTypeName + "]"); 196 } 197 if (StringUtils.isBlank(principalId)) { 198 throw new RiceIllegalArgumentException("principalId was null or blank"); 199 } 200 if (StringUtils.isBlank(documentTypeName)) { 201 throw new RiceIllegalArgumentException("documentTypeId was null or blank"); 202 } 203 } 204 205 @Override 206 public boolean hasRouteNodeForDocumentTypeName(String routeNodeName, String documentTypeName) 207 throws RiceIllegalArgumentException { 208 if (StringUtils.isBlank(routeNodeName)) { 209 throw new RiceIllegalArgumentException("routeNodeName was null or blank"); 210 } 211 if (StringUtils.isBlank(documentTypeName)) { 212 throw new RiceIllegalArgumentException("documentTypeName was null or blank"); 213 } 214 215 DocumentType documentType = getDocumentTypeByName(documentTypeName); 216 if (documentType == null) { 217 throw new RiceIllegalArgumentException("Failed to locate a document type for the given name: " + documentTypeName); 218 } 219 RouteNode routeNode = KEWServiceLocator.getRouteNodeService().findRouteNodeByName(documentType.getId(), routeNodeName); 220 221 if (routeNode == null) { 222 if (documentType.getParentId() == null) { 223 return false; 224 } else { 225 return hasRouteNodeForDocumentTypeId(routeNodeName, documentType.getParentId()); 226 } 227 } else { 228 return true; 229 } 230 } 231 232 @Override 233 public boolean hasRouteNodeForDocumentTypeId(String routeNodeName, String documentTypeId) 234 throws RiceIllegalArgumentException { 235 if (StringUtils.isBlank(routeNodeName)) { 236 throw new RiceIllegalArgumentException("routeNodeName was null or blank"); 237 } 238 if (StringUtils.isBlank(documentTypeId)) { 239 throw new RiceIllegalArgumentException("documentTypeId was null or blank"); 240 } 241 242 DocumentType documentType = getDocumentTypeById(documentTypeId); 243 if (documentType == null) { 244 throw new RiceIllegalArgumentException("Failed to locate a document type for the given id: " + documentTypeId); 245 } 246 RouteNode routeNode = KEWServiceLocator.getRouteNodeService().findRouteNodeByName(documentType.getId(), routeNodeName); 247 248 if (routeNode == null) { 249 if (documentType.getParentId() == null) { 250 return false; 251 } else { 252 return hasRouteNodeForDocumentTypeId(routeNodeName, documentType.getParentId()); 253 } 254 } else { 255 return true; 256 } 257 } 258 259 @Override 260 public boolean isActiveById(String documentTypeId) { 261 if (StringUtils.isBlank(documentTypeId)) { 262 throw new RiceIllegalArgumentException("documentTypeId was null or blank"); 263 } 264 org.kuali.rice.kew.doctype.bo.DocumentType docType = KEWServiceLocator.getDocumentTypeService().findById(documentTypeId); 265 return docType != null && docType.isActive(); 266 } 267 268 @Override 269 public boolean isActiveByName(String documentTypeName) { 270 if (StringUtils.isBlank(documentTypeName)) { 271 throw new RiceIllegalArgumentException("documentTypeName was null or blank"); 272 } 273 org.kuali.rice.kew.doctype.bo.DocumentType docType = KEWServiceLocator.getDocumentTypeService().findByName(documentTypeName); 274 return docType != null && docType.isActive(); 275 } 276 277 @Override 278 public RoutePath getRoutePathForDocumentTypeId(String documentTypeId) { 279 if (StringUtils.isBlank(documentTypeId)) { 280 throw new RiceIllegalArgumentException("documentTypeId was null or blank"); 281 } 282 org.kuali.rice.kew.doctype.bo.DocumentType docType = KEWServiceLocator.getDocumentTypeService().findById(documentTypeId); 283 if (docType == null) { 284 return null; 285 } 286 RoutePath.Builder builder = RoutePath.Builder.create(); 287 List<ProcessDefinitionBo> processes = docType.getProcesses(); 288 for (ProcessDefinitionBo process : processes) { 289 builder.getProcessDefinitions().add(ProcessDefinition.Builder.create(process)); 290 } 291 return builder.build(); 292 } 293 294 @Override 295 public RoutePath getRoutePathForDocumentTypeName(String documentTypeName) { 296 if (StringUtils.isBlank(documentTypeName)) { 297 throw new RiceIllegalArgumentException("documentTypeName was null or blank"); 298 } 299 org.kuali.rice.kew.doctype.bo.DocumentType docType = KEWServiceLocator.getDocumentTypeService().findByName(documentTypeName); 300 if (docType == null) { 301 return null; 302 } 303 RoutePath.Builder builder = RoutePath.Builder.create(); 304 List<ProcessDefinitionBo> processes = docType.getProcesses(); 305 for (ProcessDefinitionBo process : processes) { 306 builder.getProcessDefinitions().add(ProcessDefinition.Builder.create(process)); 307 } 308 return builder.build(); 309 310 } 311 312 public void setDocumentTypeDao(DocumentTypeDAO documentTypeDao) { 313 this.documentTypeDao = documentTypeDao; 314 } 315 316}