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