View Javadoc

1   /**
2    * Copyright 2005-2012 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.kim.document.rule;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
20  import org.kuali.rice.core.api.uif.RemotableAttributeError;
21  import org.kuali.rice.core.api.util.RiceKeyConstants;
22  import org.kuali.rice.kim.api.common.template.Template;
23  import org.kuali.rice.kim.api.permission.Permission;
24  import org.kuali.rice.kim.api.services.KimApiServiceLocator;
25  import org.kuali.rice.kim.api.type.KimType;
26  import org.kuali.rice.kim.impl.permission.GenericPermissionBo;
27  import org.kuali.rice.kim.impl.permission.PermissionBo;
28  import org.kuali.rice.kim.impl.permission.PermissionTemplateBo;
29  import org.kuali.rice.kim.framework.permission.PermissionTypeService;
30  import org.kuali.rice.kim.service.KIMServiceLocatorInternal;
31  import org.kuali.rice.kns.document.MaintenanceDocument;
32  import org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase;
33  import org.kuali.rice.krad.util.GlobalVariables;
34  import org.apache.commons.lang.StringUtils;
35  
36  import javax.xml.namespace.QName;
37  import java.util.List;
38  import java.util.Map;
39  import java.util.regex.Matcher;
40  import java.util.regex.Pattern;
41  
42  /**
43   * This is a description of what this class does - kellerj don't forget to fill this in. 
44   * 
45   * @author Kuali Rice Team (rice.collab@kuali.org)
46   *
47   */
48  public class GenericPermissionMaintenanceDocumentRule extends MaintenanceDocumentRuleBase {
49  	protected static final String DETAIL_VALUES_PROPERTY = "detailValues";
50      protected static final String NAMESPACE_CODE_PROPERTY = "namespaceCode";
51  	protected static final String ERROR_MESSAGE_PREFIX = "error.document.kim.genericpermission.";
52  	protected static final String ERROR_MISSING_TEMPLATE = ERROR_MESSAGE_PREFIX + "missingtemplate";
53  	protected static final String ERROR_UNKNOWN_ATTRIBUTE = ERROR_MESSAGE_PREFIX + "unknownattribute";
54  	protected static final String ERROR_ATTRIBUTE_VALIDATION = ERROR_MESSAGE_PREFIX + "attributevalidation";
55      protected static final String ERROR_NAMESPACE_AND_NAME_VALIDATION = ERROR_MESSAGE_PREFIX + "namespaceandnamevalidation";
56  
57  	
58  	@Override
59  	protected boolean processCustomRouteDocumentBusinessRules(MaintenanceDocument document) {
60  		boolean rulesPassed = super.processCustomRouteDocumentBusinessRules( document );
61  		try {
62  			GenericPermissionBo perm = (GenericPermissionBo)getNewBo();
63  			rulesPassed &= validateDetailValuesFormat(perm.getDetailValues());
64              if(StringUtils.isNotBlank(perm.getNamespaceCode()) && StringUtils.isNotBlank(perm.getName()) && StringUtils.isBlank(perm.getId())){
65                  rulesPassed &= validateNamespaceCodeAndName(perm.getNamespaceCode(), perm.getName());
66              }
67  			// detailValues
68  			// get the type from the template for validation
69              Template template = null;
70              if(StringUtils.isNotBlank(perm.getTemplateId())){
71                   template =   KimApiServiceLocator.getPermissionService().getPermissionTemplate(perm.getTemplateId());
72                  if ( template == null ) {
73                      GlobalVariables.getMessageMap().addToErrorPath( MAINTAINABLE_ERROR_PATH );
74                      GlobalVariables.getMessageMap().putError( DETAIL_VALUES_PROPERTY, ERROR_MISSING_TEMPLATE, perm.getTemplateId() );
75                      GlobalVariables.getMessageMap().removeFromErrorPath( MAINTAINABLE_ERROR_PATH );
76                      rulesPassed &= false;
77                  } else {
78                      KimType kimType = KimApiServiceLocator.getKimTypeInfoService().getKimType(template.getKimTypeId());
79                      Map<String, String> details = perm.getDetails();
80                      // check that add passed attributes are defined
81                      for ( String attributeName : details.keySet() ) {
82                          if ( kimType.getAttributeDefinitionByName(attributeName) == null ) {
83                              GlobalVariables.getMessageMap().addToErrorPath( MAINTAINABLE_ERROR_PATH );
84                              GlobalVariables.getMessageMap().putError( DETAIL_VALUES_PROPERTY, ERROR_UNKNOWN_ATTRIBUTE, attributeName, template.getNamespaceCode(), template.getName() );
85                              GlobalVariables.getMessageMap().removeFromErrorPath( MAINTAINABLE_ERROR_PATH );
86                              rulesPassed &= false;
87                          }
88                      }
89                      // if all attributes are known, pass to the service for validation
90                      if ( !GlobalVariables.getMessageMap().hasErrors() ) {
91                          PermissionTypeService service = getPermissionTypeService( kimType.getServiceName() );
92                          if ( service != null ) {
93                              List<RemotableAttributeError> validationErrors = service.validateAttributes( kimType.getId(), details);
94                              if ( validationErrors != null && !validationErrors.isEmpty() ) {
95                                  for ( RemotableAttributeError error : validationErrors ) {
96                                      GlobalVariables.getMessageMap().addToErrorPath( MAINTAINABLE_ERROR_PATH );
97                                      for (String errMsg : error.getErrors()) {
98                                          GlobalVariables.getMessageMap().putError( DETAIL_VALUES_PROPERTY, ERROR_ATTRIBUTE_VALIDATION, error.getAttributeName(), errMsg );
99                                      }
100                                     GlobalVariables.getMessageMap().removeFromErrorPath( MAINTAINABLE_ERROR_PATH );
101                                 }
102                                 rulesPassed &= false;
103                             }
104                         }
105                     }
106 
107                 }
108 
109             }
110 			// check each permission name against the type
111 		} catch ( RuntimeException ex ) {
112 			LOG.error( "Error in processCustomRouteDocumentBusinessRules()", ex );
113 			throw ex;
114 		}
115 		return rulesPassed;
116 	}
117 
118 	protected boolean validateDetailValuesFormat(String permissionDetailValues){
119 		if(permissionDetailValues != null){
120 			String spacesPattern = "[\\s\\t]*";
121 			Pattern pattern = Pattern.compile(".+"+"="+".+");
122 			Matcher matcher;
123 			// ensure that all line delimiters are single linefeeds
124 			permissionDetailValues = permissionDetailValues.replace( "\r\n", "\n" );
125 			permissionDetailValues = permissionDetailValues.replace( '\r', '\n' );
126 			if(StringUtils.isNotBlank(permissionDetailValues)){
127 				String[] values = permissionDetailValues.split( "\n" );
128 				for(String attrib: values){
129 				      matcher = pattern.matcher(attrib);
130 				      if(!matcher.matches()){
131 				    	  GlobalVariables.getMessageMap().putError(MAINTAINABLE_ERROR_PATH+"."+DETAIL_VALUES_PROPERTY, RiceKeyConstants.ERROR_INVALID_FORMAT, new String[]{"Detail Values", permissionDetailValues});
132 				    	  return false;
133 				      }
134 				}
135 			}
136 		}
137 		return true;
138 	}
139     protected boolean validateNamespaceCodeAndName(String namespaceCode,String name){
140         Permission permission = KimApiServiceLocator.getPermissionService().findPermByNamespaceCodeAndName(namespaceCode,name);
141         if(null != permission){
142             GlobalVariables.getMessageMap().putError(MAINTAINABLE_ERROR_PATH+"."+NAMESPACE_CODE_PROPERTY,ERROR_NAMESPACE_AND_NAME_VALIDATION,namespaceCode,name);
143             return false;
144         } else{
145             return true;
146         }
147     }
148 	
149 	protected PermissionTypeService getPermissionTypeService( String serviceName ) {
150     	if ( StringUtils.isBlank( serviceName ) ) {
151     		return null;
152     	}
153     	try {
154 	    	Object service = GlobalResourceLoader.getService(QName.valueOf(serviceName));
155 	    	// if we have a service name, it must exist
156 	    	if ( service == null ) {
157 				LOG.warn("null returned for permission type service for service name: " + serviceName);
158 	    	} else {
159 		    	// whatever we retrieved must be of the correct type
160 		    	if ( !(service instanceof PermissionTypeService)  ) {
161 		    		LOG.warn( "Service " + serviceName + " was not a KimPermissionTypeService.  Was: " + service.getClass().getName() );
162 		    		service = null;
163 		    	}
164 	    	}
165 	    	return (PermissionTypeService)service;
166     	} catch( Exception ex ) {
167     		LOG.error( "Error retrieving service: " + serviceName + " from the KimImplServiceLocator.", ex );
168     	}
169     	return null;
170     }
171 
172 }