001/**
002 * Copyright 2005-2016 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.repository;
017
018
019import java.util.Collection;
020import java.util.Collections;
021import java.util.HashMap;
022import java.util.HashSet;
023import java.util.List;
024import java.util.Map;
025import java.util.Set;
026
027import org.apache.commons.lang.StringUtils;
028import org.kuali.rice.krad.service.BusinessObjectService;
029import org.kuali.rice.krms.api.repository.proposition.PropositionDefinition;
030import org.kuali.rice.krms.api.repository.proposition.PropositionParameter;
031
032/**
033 * Implementation of the interface for accessing KRMS repository Proposition related
034 * business objects.
035 *
036 * @author Kuali Rice Team (rice.collab@kuali.org)
037 *
038 */
039public final class PropositionBoServiceImpl implements PropositionBoService {
040
041    private BusinessObjectService businessObjectService;
042
043        /**
044         * This overridden method creates a Proposition if it does not 
045         * already exist in the repository.
046         * 
047         * @see org.kuali.rice.krms.impl.repository.PropositionBoService#createProposition(org.kuali.rice.krms.api.repository.proposition.PropositionDefinition)
048         */
049        @Override
050        public PropositionDefinition createProposition(PropositionDefinition prop) {
051                if (prop == null){
052                throw new IllegalArgumentException("proposition is null");
053                }
054                if (null != prop.getId()) {
055                    throw new IllegalStateException("for creation, PropositionDefinition.id must be null");
056            }
057                
058                PropositionBo propositionBo = PropositionBo.from(prop);
059                businessObjectService.save(propositionBo);
060                return PropositionBo.to(propositionBo);
061        }
062
063        /**
064         * This overridden method updates an existing proposition
065         * 
066         * @see org.kuali.rice.krms.impl.repository.PropositionBoService#updateProposition(org.kuali.rice.krms.api.repository.proposition.PropositionDefinition)
067         */
068        @Override
069        public void updateProposition(PropositionDefinition prop) {
070        if (prop == null) {
071            throw new IllegalArgumentException("proposition is null");
072        }
073                final String propIdKey = prop.getId();
074                final PropositionDefinition existing = getPropositionById(propIdKey);
075        if (existing == null) {
076            throw new IllegalStateException("the proposition does not exist: " + prop);
077        }
078        final PropositionDefinition toUpdate;
079        if (!existing.getId().equals(prop.getId())){
080                final PropositionDefinition.Builder builder = PropositionDefinition.Builder.create(prop);
081                builder.setId(existing.getId());
082                toUpdate = builder.build();
083        } else {
084                toUpdate = prop;
085        }
086        
087        businessObjectService.save(PropositionBo.from(toUpdate));
088        }
089
090        /**
091         * This overridden method retrieves a proposition by the give proposition id.
092         * 
093         * @see org.kuali.rice.krms.impl.repository.PropositionBoService#getPropositionById(java.lang.String)
094         */
095        @Override
096        public PropositionDefinition getPropositionById(String propId) {
097                if (StringUtils.isBlank(propId)){
098            throw new IllegalArgumentException("propId is null or blank");                      
099                }
100                PropositionBo bo = businessObjectService.findBySinglePrimaryKey(PropositionBo.class, propId);
101                return PropositionBo.to(bo);
102        }
103
104    @Override
105    public Set<PropositionDefinition> getPropositionsByType(String typeId) {
106        if (org.apache.commons.lang.StringUtils.isBlank(typeId)) {
107            throw new IllegalArgumentException("typeId is null or blank");
108        }
109
110        final Map<String, Object> map = new HashMap<String, Object>();
111        map.put("typeId", typeId);
112        Collection<PropositionBo> bos = (Collection<PropositionBo>) businessObjectService.findMatching(PropositionBo.class, map);
113
114        return convertBosToImmutables(bos);
115    }
116
117    @Override
118    public Set<PropositionDefinition> getPropositionsByRule(String ruleId) {
119        if (org.apache.commons.lang.StringUtils.isBlank(ruleId)) {
120            throw new IllegalArgumentException("ruleId is null or blank");
121        }
122
123        final Map<String, Object> map = new HashMap<String, Object>();
124        map.put("ruleId", ruleId);
125        Collection<PropositionBo> bos = (Collection<PropositionBo>) businessObjectService.findMatching(PropositionBo.class, map);
126
127        return convertBosToImmutables(bos);
128    }
129
130    public Set<PropositionDefinition> convertBosToImmutables(final Collection<PropositionBo> propositionBos) {
131        Set<PropositionDefinition> immutables = new HashSet<PropositionDefinition>();
132        if (propositionBos != null) {
133            PropositionDefinition immutable = null;
134            for (PropositionBo bo : propositionBos ) {
135                immutable = to(bo);
136                immutables.add(immutable);
137            }
138        }
139        return Collections.unmodifiableSet(immutables);
140    }
141
142    public PropositionDefinition to(PropositionBo propositionBo) {
143        return PropositionBo.to(propositionBo);
144    }
145
146        /**
147         * This overridden method creates a PropositionParameter if it does not 
148         * already exist in the repository.
149         * 
150         * @see org.kuali.rice.krms.impl.repository.PropositionBoService#createParameter(org.kuali.rice.krms.api.repository.proposition.PropositionParameter)
151         */
152        @Override
153        public void createParameter(PropositionParameter parameter) {
154                if (parameter == null){
155                throw new IllegalArgumentException("parameter is null");
156                }
157                final String propIdKey = parameter.getPropId();
158                final Integer seqNoKey = parameter.getSequenceNumber();
159                final PropositionParameter existing = getParameterByPropIdAndSequenceNumber(propIdKey, seqNoKey);
160                if (existing != null && existing.getPropId().equals(propIdKey) && existing.getSequenceNumber().equals(seqNoKey)){
161            throw new IllegalStateException("the parameter to create already exists: " + parameter);                    
162                }
163                
164                businessObjectService.save(PropositionParameterBo.from(parameter));
165        }
166
167        /**
168         * This overridden method updates an existing proposition parameter
169         * 
170         * @see org.kuali.rice.krms.impl.repository.PropositionBoService#updateParameter(org.kuali.rice.krms.api.repository.proposition.PropositionParameter)
171         */
172        @Override
173        public void updateParameter(PropositionParameter parameter) {
174        if (parameter == null) {
175            throw new IllegalArgumentException("parameter is null");
176        }
177                final String propIdKey = parameter.getPropId();
178                final Integer seqNoKey = parameter.getSequenceNumber();
179                final PropositionParameter existing = getParameterByPropIdAndSequenceNumber(propIdKey, seqNoKey);
180        if (existing == null) {
181            throw new IllegalStateException("the parameter does not exist: " + parameter);
182        }
183        final PropositionParameter toUpdate;
184        if (!existing.getId().equals(parameter.getId())){
185                final PropositionParameter.Builder builder = PropositionParameter.Builder.create(parameter);
186                builder.setId(existing.getId());
187                toUpdate = builder.build();
188        } else {
189                toUpdate = parameter;
190        }
191        
192        businessObjectService.save(PropositionParameterBo.from(toUpdate));
193        }
194
195    @Override
196    public void deleteProposition(String propId) {
197        if (propId == null){ throw new IllegalArgumentException("propId is null"); }
198        final PropositionDefinition existing = getPropositionById(propId);
199        if (existing == null){ throw new IllegalStateException("the Proposition to delete does not exists: " + propId);}
200
201        List<PropositionParameter> propositionParameters = existing.getParameters();
202        for( PropositionParameter prop : propositionParameters) {
203            businessObjectService.delete(PropositionParameterBo.from(prop));
204        }
205
206        businessObjectService.delete(from(existing));
207    }
208    
209        /**
210         * This overridden method retrieves a list of parameters for a given proposition
211         * 
212         * @see org.kuali.rice.krms.impl.repository.PropositionBoService#getParameters(java.lang.Long)
213         */
214        @Override
215        public List<PropositionParameter> getParameters(String propId) {
216                if (StringUtils.isBlank(propId)) {
217            throw new IllegalArgumentException("propId is null or blank");
218                }
219        final Map<String, Object> map = new HashMap<String, Object>();
220        map.put("propId", propId);
221                List<PropositionParameterBo> bos = (List<PropositionParameterBo>) businessObjectService.findMatchingOrderBy(PropositionParameterBo.class, map, "sequenceNumber", true);
222                return PropositionParameterBo.to(bos);
223        }
224
225        /**
226         * This overridden method gets a parameter by the parameter id
227         * 
228         * @see org.kuali.rice.krms.impl.repository.PropositionBoService#getParameterById(java.lang.String)
229         */
230        @Override
231        public PropositionParameter getParameterById(String id) {
232                if (StringUtils.isBlank(id)) {
233            throw new IllegalArgumentException("id is null or blank");
234                }
235                PropositionParameterBo bo = businessObjectService.findBySinglePrimaryKey(PropositionParameterBo.class, id);
236                return PropositionParameterBo.to(bo);
237        }
238
239        /**
240         * This overridden method gets a parameter by the Proposition Id and Sequence Number
241         * 
242         * @see org.kuali.rice.krms.impl.repository.PropositionBoService#getParameterByPropIdAndSequenceNumber(java.lang.String, java.lang.String)
243         */
244        @Override
245        public PropositionParameter getParameterByPropIdAndSequenceNumber(
246                        String propId, Integer sequenceNumber) {
247                if (StringUtils.isBlank(propId)) {
248            throw new IllegalArgumentException("propId is null or blank");
249                }
250                if (sequenceNumber == null) {
251            throw new IllegalArgumentException("sequenceNumber is null");
252                }
253        final Map<String, Object> map = new HashMap<String, Object>();
254        map.put("propId", propId);
255        map.put("sequenceNumber", sequenceNumber);
256                PropositionParameterBo bo = businessObjectService.findByPrimaryKey(PropositionParameterBo.class, map);
257                return PropositionParameterBo.to(bo);
258        }
259    /**
260     * Converts a immutable {@link PropositionDefinition} to its mutable {@link PropositionBo} counterpart.
261     * @param proposition the immutable object.
262     * @return a {@link PropositionBo} the mutable PropositionBo.
263     *
264     */
265    public PropositionBo from(PropositionDefinition proposition) {
266        if (proposition == null) { return null; }
267        PropositionBo propositionBo = new PropositionBo();
268        propositionBo.setDescription(proposition.getDescription());
269        propositionBo.setTypeId(proposition.getTypeId());
270        propositionBo.setRuleId(proposition.getRuleId());
271        propositionBo.setPropositionTypeCode(proposition.getPropositionTypeCode());
272        propositionBo.setCompoundOpCode(proposition.getCompoundOpCode());
273        propositionBo.setId(proposition.getId());
274        propositionBo.setVersionNumber(proposition.getVersionNumber());
275        return propositionBo;
276    }
277
278    /**
279     * Sets the businessObjectService attribute value.
280     *
281     * @param businessObjectService The businessObjectService to set.
282     */
283    public void setBusinessObjectService(BusinessObjectService businessObjectService) {
284        this.businessObjectService = businessObjectService;
285    }
286
287}