001/**
002 * Copyright 2005-2017 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.krms.impl.rule;
017
018import org.apache.commons.lang.StringUtils;
019import org.kuali.rice.krad.maintenance.MaintenanceDocument;
020import org.kuali.rice.krad.rules.MaintenanceDocumentRuleBase;
021import org.kuali.rice.krms.api.repository.term.TermSpecificationDefinition;
022import org.kuali.rice.krms.impl.repository.CategoryBo;
023import org.kuali.rice.krms.impl.repository.ContextBo;
024import org.kuali.rice.krms.impl.repository.KrmsRepositoryServiceLocator;
025import org.kuali.rice.krms.impl.repository.TermBoService;
026import org.kuali.rice.krms.impl.repository.TermSpecificationBo;
027import org.kuali.rice.krms.impl.util.KRMSPropertyConstants;
028
029import java.util.ArrayList;
030import java.util.HashMap;
031import java.util.List;
032import java.util.Map;
033
034import static org.kuali.rice.krms.impl.repository.BusinessObjectServiceMigrationUtils.findSingleMatching;
035
036public class TermSpecBusRule extends MaintenanceDocumentRuleBase {
037
038    @Override
039    protected boolean processCustomSaveDocumentBusinessRules(MaintenanceDocument document) {
040        boolean isValid = true;
041
042        TermSpecificationBo termSpec = (TermSpecificationBo) document.getNewMaintainableObject().getDataObject();
043        isValid &= validateId(termSpec);
044        isValid &= validateCategory(termSpec);
045        isValid &= validateContext(termSpec);
046        isValid &= validateNameNamespace(termSpec);
047
048        return isValid;
049    }
050
051    private boolean validateCategory(TermSpecificationBo termSpecificationBo) {
052        List<CategoryBo> categories = termSpecificationBo.getCategories();
053        List<String> categoryIds = new ArrayList<String>();
054
055        boolean valid = true;
056        for (CategoryBo category: categories) {
057            if (categoryIds.contains(category.getId())) {
058                this.putFieldError(KRMSPropertyConstants.TermSpecification.CATEGORY, "error.termSpecification.duplicateCategory");
059                valid = false;
060            } else {
061                categoryIds.add(category.getId());
062            }
063        }
064        return valid;
065    }
066    
067    private boolean validateContext(TermSpecificationBo termSpec) {
068        List<ContextBo> termSpecContexts = termSpec.getContexts();
069        List<String> contextIds = new ArrayList<String>();
070        boolean valid = true;
071        for (ContextBo context: termSpecContexts) {
072            if (contextIds.contains(context.getId())) {
073                this.putFieldError(KRMSPropertyConstants.TermSpecification.CONTEXT, "error.termSpecification.duplicateContext");
074                valid = false;
075            } else {
076                contextIds.add(context.getId());
077            }
078        }
079        return valid;
080    }
081
082    private boolean validateId(TermSpecificationBo termSpec) {
083        if (StringUtils.isNotBlank(termSpec.getId())) {
084            TermSpecificationDefinition termSpecInDatabase = getTermBoService().getTermSpecificationById(termSpec.getId());
085            if ((termSpecInDatabase  != null) && (!StringUtils.equals(termSpecInDatabase.getId(), termSpec.getId()))) {
086                this.putFieldError(KRMSPropertyConstants.TermSpecification.TERM_SPECIFICATION_ID, "error.termSpecification.duplicateId");
087                return false;
088            }
089        }
090
091        return true;
092    }
093
094    /**
095     * Check if the name-namespace pair already exist.
096     * @param termSpec
097     * @return true if the name-namespace pair is unique, false otherwise
098     */
099    private boolean validateNameNamespace(TermSpecificationBo termSpec) {
100        if (StringUtils.isNotBlank(termSpec.getName()) && StringUtils.isNotBlank(
101                termSpec.getNamespace())) {
102
103            Map<String, String> criteria = new HashMap<String, String>();
104
105            criteria.put("name", termSpec.getName());
106            criteria.put("namespace", termSpec.getNamespace());
107
108            TermSpecificationBo termSpecInDatabase =
109                    findSingleMatching(getDataObjectService(), TermSpecificationBo.class, criteria);
110
111            if((termSpecInDatabase != null) && (!StringUtils.equals(termSpecInDatabase.getId(), termSpec.getId()))) {
112                this.putFieldError(KRMSPropertyConstants.TermSpecification.NAME, "error.term.duplicateNameNamespace");
113                return false;
114            }
115        }
116
117        return true;
118    }
119
120    public TermBoService getTermBoService() {
121        return KrmsRepositoryServiceLocator.getTermBoService();
122    }
123}