001/**
002 * Copyright 2005-2014 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.collections.CollectionUtils;
019import org.apache.commons.lang.StringUtils;
020import org.kuali.rice.core.api.criteria.QueryByCriteria;
021import org.kuali.rice.core.api.criteria.QueryResults;
022import org.kuali.rice.krad.data.DataObjectService;
023import org.kuali.rice.krad.maintenance.MaintenanceDocument;
024import org.kuali.rice.krad.rules.MaintenanceDocumentRuleBase;
025import org.kuali.rice.krad.service.KRADServiceLocator;
026import org.kuali.rice.krms.api.repository.term.TermDefinition;
027import org.kuali.rice.krms.api.repository.term.TermSpecificationDefinition;
028import org.kuali.rice.krms.impl.repository.KrmsRepositoryServiceLocator;
029import org.kuali.rice.krms.impl.repository.TermBo;
030import org.kuali.rice.krms.impl.repository.TermBoService;
031import org.kuali.rice.krms.impl.util.KRMSPropertyConstants;
032
033import java.util.HashMap;
034import java.util.Map;
035
036public class TermBusRule extends MaintenanceDocumentRuleBase {
037
038    private DataObjectService dataObjectService;
039
040    @Override
041    protected boolean processCustomSaveDocumentBusinessRules(MaintenanceDocument document) {
042        boolean isValid = true;
043
044        TermBo term = (TermBo) document.getNewMaintainableObject().getDataObject();
045        isValid &= validateId(term);
046        isValid &= validateDescriptionNamespace(term);
047        isValid &= validateTermSpecId(term);
048
049        return isValid;
050    }
051
052    private boolean validateTermSpecId(TermBo term) {
053        if (StringUtils.isBlank(term.getSpecificationId())) {
054            this.putFieldError(KRMSPropertyConstants.Term.TERM_SPECIFICATION_ID, "error.term.invalidTermSpecification");
055
056            return false;
057        }
058
059        TermSpecificationDefinition termSpec =
060                KrmsRepositoryServiceLocator.getTermBoService().getTermSpecificationById(term.getSpecificationId());
061
062        if (termSpec == null) {
063            this.putFieldError(KRMSPropertyConstants.Term.TERM_SPECIFICATION_ID, "error.term.invalidTermSpecification");
064
065            return false;
066        }
067
068        return true;
069    }
070
071    private boolean validateId(TermBo term) {
072        if (StringUtils.isNotBlank(term.getId())) {
073            TermDefinition termInDatabase = getTermBoService().getTerm(term.getId());
074            if ((termInDatabase  != null) && (!StringUtils.equals(termInDatabase.getId(), term.getId()))) {
075                this.putFieldError(KRMSPropertyConstants.Term.TERM_ID, "error.term.duplicateId");
076
077                return false;
078            }
079        }
080
081        return true;
082    }
083
084    /**
085     * Check if the name-namespace pair already exist.
086     * @param term
087     * @return true if the name-namespace pair is unique, false otherwise
088     */
089    private boolean validateDescriptionNamespace(TermBo term) {
090        if (term.getSpecification() != null && StringUtils.isNotBlank(term.getDescription()) && StringUtils.isNotBlank(
091                term.getSpecification().getNamespace())) {
092
093            Map<String, String> critMap = new HashMap<String, String>();
094
095            critMap.put("description", term.getDescription());
096            critMap.put("specification.namespace", term.getSpecification().getNamespace());
097            QueryByCriteria criteria = QueryByCriteria.Builder.andAttributes(critMap).build();
098            QueryResults<TermBo> queryResults = getDataObjectService().findMatching(TermBo.class, criteria);
099
100            TermBo termInDatabase = null;
101
102            if (!CollectionUtils.isEmpty(queryResults.getResults()) && queryResults.getResults().size() == 1) {
103                termInDatabase = queryResults.getResults().get(0);
104            }
105
106            if((termInDatabase != null) && (!StringUtils.equals(termInDatabase.getId(), term.getId()))) {
107                this.putFieldError(KRMSPropertyConstants.Term.DESCRIPTION, "error.term.duplicateNameNamespace");
108
109                return false;
110            }
111        }
112
113        return true;
114    }
115
116    public TermBoService getTermBoService() {
117        return KrmsRepositoryServiceLocator.getTermBoService();
118    }
119
120    public DataObjectService getDataObjectService() {
121        if(dataObjectService == null){
122            return KRADServiceLocator.getDataObjectService();
123        }
124
125        return dataObjectService;
126    }
127
128    public void setBoService(DataObjectService dataObjectService) {
129        this.dataObjectService = dataObjectService;
130    }
131
132}