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