001    /**
002     * Copyright 2005-2013 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     */
016    package org.kuali.rice.kew.document;
017    
018    import org.kuali.rice.core.api.uif.RemotableAttributeError;
019    import org.kuali.rice.core.api.util.RiceKeyConstants;
020    import org.kuali.rice.kew.api.KEWPropertyConstants;
021    import org.kuali.rice.kew.api.KewApiConstants;
022    import org.kuali.rice.kew.api.KewApiServiceLocator;
023    import org.kuali.rice.kew.api.rule.RuleTemplate;
024    import org.kuali.rice.kew.api.rule.RuleTemplateAttribute;
025    import org.kuali.rice.kew.doctype.service.DocumentTypeService;
026    import org.kuali.rice.kew.rule.GroupRuleResponsibility;
027    import org.kuali.rice.kew.rule.PersonRuleResponsibility;
028    import org.kuali.rice.kew.rule.RuleBaseValues;
029    import org.kuali.rice.kew.rule.RuleResponsibilityBo;
030    import org.kuali.rice.kew.rule.WorkflowRuleAttributeRows;
031    import org.kuali.rice.kew.rule.bo.RuleAttribute;
032    import org.kuali.rice.kew.rule.web.WebRuleUtils;
033    import org.kuali.rice.kew.service.KEWServiceLocator;
034    import org.kuali.rice.kns.document.MaintenanceDocument;
035    import org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase;
036    import org.kuali.rice.krad.bo.PersistableBusinessObject;
037    
038    import java.util.List;
039    import java.util.Map;
040    
041    /**
042     * This is a description of what this class does - Garey don't forget to fill this in.
043     *
044     * @author Kuali Rice Team (rice.collab@kuali.org)
045     *
046     */
047    public class RoutingRuleMaintainableBusRule extends MaintenanceDocumentRuleBase {
048    
049            /**
050             * This overridden method ...
051             *
052             * @see org.kuali.rice.krad.rules.MaintenanceDocumentRuleBase#processCustomSaveDocumentBusinessRules(org.kuali.rice.krad.maintenance.MaintenanceDocument)
053             */
054            @Override
055            protected boolean processCustomSaveDocumentBusinessRules(
056                            MaintenanceDocument document) {
057    
058                    boolean isValid = true;
059    
060                    RuleBaseValues ruleBaseValues = this.getRuleBaseValues(document);
061                    RuleBaseValues oldRuleBaseValues = this.getOldRuleBaseValues(document);
062                    
063                    isValid &= this.populateErrorMap(ruleBaseValues);
064    
065    
066                    return isValid;
067            }
068    
069            protected RuleBaseValues getRuleBaseValues(MaintenanceDocument document){
070                    return (RuleBaseValues)document.getNewMaintainableObject().getBusinessObject();
071            }
072            
073            protected RuleBaseValues getOldRuleBaseValues(MaintenanceDocument document){
074                    return (RuleBaseValues)document.getOldMaintainableObject().getBusinessObject();
075            }
076            
077    
078            protected void populateErrorMap(Map<String,String> errorMap){
079                    for(Map.Entry<String, String> entry : errorMap.entrySet()){
080                            this.putFieldError(entry.getKey(), entry.getValue());
081                    }
082            }
083    
084            /**
085             * This overridden method ...
086             *
087             * @see org.kuali.rice.krad.rules.MaintenanceDocumentRuleBase#processCustomAddCollectionLineBusinessRules(org.kuali.rice.krad.maintenance.MaintenanceDocument, java.lang.String, org.kuali.rice.krad.bo.PersistableBusinessObject)
088             */
089            @Override
090            public boolean processCustomAddCollectionLineBusinessRules(
091                            MaintenanceDocument document, String collectionName,
092                            PersistableBusinessObject line) {
093    
094                    boolean isValid = true;
095    
096                    if(getPersonSectionName().equals(collectionName)){
097                            PersonRuleResponsibility pr = (PersonRuleResponsibility)line;
098                            String name = pr.getPrincipalName();
099    
100                            if(!personExists(name)){
101                                    isValid &= false;
102                                    this.putFieldError(getPersonSectionName(), "error.document.personResponsibilities.principleDoesNotExist");
103                            }
104                    }else if(getGroupSectionName().equals(collectionName)){
105                            GroupRuleResponsibility gr = (GroupRuleResponsibility)line;
106                            if(!groupExists(gr.getNamespaceCode(), gr.getName())){
107                                    isValid &= false;
108                                    this.putFieldError(getGroupSectionName(), "error.document.personResponsibilities.groupDoesNotExist");
109                            }
110                    }
111    
112                    return isValid;
113            }
114    
115            protected String getPersonSectionName(){
116                    return KEWPropertyConstants.PERSON_RESP_SECTION;
117            }
118            protected String getGroupSectionName(){
119                    return KEWPropertyConstants.GROUP_RESP_SECTION;
120            }
121    
122            protected boolean personExists(String principalName){
123                    boolean bRet = false;
124                    try{
125                            KEWServiceLocator.getIdentityHelperService().getIdForPrincipalName(principalName);
126                            bRet = true;
127                    }catch(Exception ex){
128                            bRet = false;
129                            //ex.printStackTrace();
130                    }
131    
132                    return bRet;
133            }
134    
135            protected boolean groupExists(String namespaceCode, String groupName){
136                    boolean bRet = false;
137                    try{
138                            KEWServiceLocator.getIdentityHelperService().getGroupByName(namespaceCode, groupName);
139                            bRet = true;
140                    }catch(Exception ex){
141                            bRet = false;
142                            //ex.printStackTrace();
143                    }
144                    return bRet;
145            }
146    
147            protected boolean populateErrorMap(RuleBaseValues ruleBaseValues){
148    
149                    boolean isValid = true;
150    
151                    if (getDocumentTypeService().findByName(ruleBaseValues.getDocTypeName()) == null) {
152                this.putFieldError("docTypeName", "doctype.documenttypeservice.doctypename.required");
153                isValid &= false;
154            }
155            if(ruleBaseValues.getName() != null){
156                    if(ruleExists(ruleBaseValues)){
157                            this.putFieldError("name", "routetemplate.ruleservice.name.unique");
158                    isValid &= false;
159                    }
160            }
161    
162            /*
163             * Logic: If both from and to dates exist, make sure toDate is after fromDate
164             */
165            if(ruleBaseValues.getToDateValue() != null && ruleBaseValues.getFromDateValue() != null){
166                    if (ruleBaseValues.getToDateValue().before(ruleBaseValues.getFromDateValue())) {
167                            this.putFieldError("toDate", "error.document.maintainableItems.toDate");
168                            isValid &= false;
169                }
170            }
171    
172                    if(!setRuleAttributeErrors(ruleBaseValues)){
173                            isValid &= false;
174                    }
175    
176                    // This doesn't map directly to a single field. It's either the person or the group tab
177            if (ruleBaseValues.getRuleResponsibilities().isEmpty()) {
178                    this.putFieldError("Responsibilities", "error.document.responsibility.required");
179                    isValid &= false;
180            } else {
181                for (RuleResponsibilityBo responsibility : ruleBaseValues.getRuleResponsibilities()) {
182                    if (responsibility.getRuleResponsibilityName() != null && KewApiConstants.RULE_RESPONSIBILITY_GROUP_ID.equals(responsibility.getRuleResponsibilityType())) {
183                        if (getGroupService().getGroup(responsibility.getRuleResponsibilityName()) == null) {
184                            this.putFieldError("Groups", "routetemplate.ruleservice.workgroup.invalid");
185                            isValid &= false;
186                        }
187                    } else if (responsibility.getPrincipal() == null && responsibility.getRole() == null) {
188                            this.putFieldError("Persons", "routetemplate.ruleservice.user.invalid");
189                            isValid &= false;
190                    }
191                }
192            }
193    
194            return isValid;
195            }
196    
197            protected boolean ruleExists(RuleBaseValues rule){
198                    boolean bRet = false;
199    
200                    RuleBaseValues tmp = KEWServiceLocator.getRuleService().getRuleByName(rule.getName());
201    
202                    if(tmp != null) {
203                        if ((rule.getPreviousRuleId() == null)
204                             || (rule.getPreviousRuleId() != null
205                                && !rule.getPreviousRuleId().equals(tmp.getId()))) {
206                                bRet = true;
207                        }
208                    }
209    
210                    return bRet;
211            }
212    
213            protected DocumentTypeService getDocumentTypeService() {
214            return (DocumentTypeService) KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_TYPE_SERVICE);
215        }
216    
217    
218            protected boolean setRuleAttributeErrors(RuleBaseValues rule){
219    
220                    boolean isValid = true;
221    
222                    RuleTemplate ruleTemplate = KewApiServiceLocator.getRuleService().getRuleTemplate(rule.getRuleTemplateId());
223    
224                    /** Populate rule extension values * */
225                    for (RuleTemplateAttribute ruleTemplateAttribute : ruleTemplate.getActiveRuleTemplateAttributes()) {
226                if (!RuleAttribute.isWorkflowAttribute(ruleTemplateAttribute.getRuleAttribute().getType())) {
227                    continue;
228                }
229                Map<String, String> parameterMap = WebRuleUtils.getFieldMapForRuleTemplateAttribute(rule, ruleTemplateAttribute);
230                WorkflowRuleAttributeRows rows =
231                        KEWServiceLocator.getWorkflowRuleAttributeMediator().getRuleRows(parameterMap, ruleTemplateAttribute);
232    
233                            // TODO hook validation of rule data into PreRules
234                List<RemotableAttributeError> errors = rows.getValidationErrors();
235                            if (!errors.isEmpty()) {
236                    isValid = false;
237                                    for(RemotableAttributeError error: errors){
238                                        this.putFieldError("RuleAttributes", RiceKeyConstants.ERROR_CUSTOM, error.getMessage());
239                                    }
240                            }
241                    }
242                    return isValid;
243    
244            }
245    
246    }