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.collections.CollectionUtils;
019import org.apache.commons.lang.StringUtils;
020import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
021import org.kuali.rice.core.api.exception.RiceIllegalStateException;
022import org.kuali.rice.krad.data.DataObjectService;
023import org.kuali.rice.krad.data.PersistenceOption;
024import org.kuali.rice.krms.api.repository.type.KrmsAttributeDefinition;
025import org.kuali.rice.krms.api.repository.type.KrmsTypeBoService;
026import org.kuali.rice.krms.api.repository.type.KrmsTypeDefinition;
027
028import javax.jws.WebParam;
029import java.util.ArrayList;
030import java.util.Collection;
031import java.util.Collections;
032import java.util.HashMap;
033import java.util.List;
034import java.util.Map;
035
036import static org.kuali.rice.krms.impl.repository.BusinessObjectServiceMigrationUtils.findMatching;
037import static org.kuali.rice.krms.impl.repository.BusinessObjectServiceMigrationUtils.findMatchingOrderBy;
038import static org.kuali.rice.krms.impl.repository.BusinessObjectServiceMigrationUtils.findSingleMatching;
039
040public final class KrmsTypeBoServiceImpl implements KrmsTypeBoService {
041    private DataObjectService dataObjectService;
042
043    /**
044     * This overridden method creates a KrmsType if it does not
045     * already exist in the repository.
046     *
047     * @see org.kuali.rice.krms.api.repository.type.KrmsTypeRepositoryService#createKrmsType(org.kuali.rice.krms.api.repository.type.KrmsTypeDefinition)
048     */
049    @Override
050    public KrmsTypeDefinition createKrmsType(KrmsTypeDefinition krmsType) {
051        if (krmsType == null) {
052            throw new RiceIllegalArgumentException("krmsType is null");
053        }
054
055        final String nameKey = krmsType.getName();
056        final String namespaceKey = krmsType.getNamespace();
057        final KrmsTypeDefinition existing = getTypeByName(namespaceKey, nameKey);
058
059        if (existing != null && existing.getName().equals(nameKey) && existing.getNamespace().equals(namespaceKey)) {
060            throw new RiceIllegalStateException("the KRMS Type to create already exists: " + krmsType);
061        }
062
063        KrmsTypeBo bo = dataObjectService.save(KrmsTypeBo.from(krmsType), PersistenceOption.FLUSH);
064
065        return KrmsTypeBo.to(bo);
066    }
067
068    /**
069     * This overridden method updates an existing KrmsType
070     *
071     * @see org.kuali.rice.krms.api.repository.type.KrmsTypeRepositoryService#updateKrmsType(org.kuali.rice.krms.api.repository.type.KrmsTypeDefinition)
072     */
073    @Override
074    public KrmsTypeDefinition updateKrmsType(KrmsTypeDefinition krmsType) {
075        if (krmsType == null) {
076            throw new RiceIllegalArgumentException("krmsType is null");
077        }
078
079        final String idKey = krmsType.getId();
080        final KrmsTypeBo existing = dataObjectService.find(KrmsTypeBo.class, idKey);
081
082        if (existing == null) {
083            throw new RiceIllegalStateException("the KRMS type does not exist: " + krmsType);
084        }
085
086        final KrmsTypeDefinition toUpdate;
087
088        if (!existing.getId().equals(krmsType.getId())) {
089            final KrmsTypeDefinition.Builder builder = KrmsTypeDefinition.Builder.create(krmsType);
090            builder.setId(existing.getId());
091            toUpdate = builder.build();
092        } else {
093            toUpdate = krmsType;
094        }
095
096        return KrmsTypeBo.to(dataObjectService.save(KrmsTypeBo.from(toUpdate), PersistenceOption.FLUSH));
097    }
098
099    @Override
100    public KrmsTypeDefinition getTypeById(final String id) {
101        if (StringUtils.isBlank(id)) {
102            throw new RiceIllegalArgumentException("id was a null or blank value");
103        }
104
105        KrmsTypeBo krmsTypeBo = dataObjectService.find(KrmsTypeBo.class, id);
106
107        return KrmsTypeBo.to(krmsTypeBo);
108    }
109
110    @Override
111    public KrmsTypeDefinition getTypeByName(final String namespaceCode, final String name) {
112        if (StringUtils.isBlank(namespaceCode)) {
113            throw new RiceIllegalArgumentException("namespaceCode was a null or blank value");
114        }
115
116        if (StringUtils.isBlank(name)) {
117            throw new RiceIllegalArgumentException("name was a null or blank value");
118        }
119
120        final Map<String, Object> map = new HashMap<String, Object>();
121        map.put("namespace", namespaceCode);
122        map.put("name", name);
123
124        KrmsTypeBo myType = findSingleMatching(dataObjectService, KrmsTypeBo.class, Collections.unmodifiableMap(map));
125
126        return KrmsTypeBo.to(myType);
127    }
128
129    @Override
130    public List<KrmsTypeDefinition> findAllTypesByNamespace(final String namespaceCode) {
131        if (StringUtils.isBlank(namespaceCode)) {
132            throw new RiceIllegalArgumentException("namespaceCode was a null or blank value");
133        }
134
135        final Map<String, Object> map = new HashMap<String, Object>();
136        map.put("namespace", namespaceCode);
137        map.put("active", Boolean.TRUE);
138
139        Collection<KrmsTypeBo> krmsTypeBos = findMatching(dataObjectService, KrmsTypeBo.class,
140                Collections.unmodifiableMap(map));
141
142        return convertListOfBosToImmutables(krmsTypeBos);
143    }
144
145    @Override
146    public List<KrmsTypeDefinition> findAllTypesByServiceName(String serviceName) throws RiceIllegalArgumentException {
147        if (StringUtils.isBlank(serviceName)) {
148            throw new RiceIllegalArgumentException("serviceName was a null or blank value");
149        }
150
151        final Map<String, Object> map = new HashMap<String, Object>();
152        map.put("serviceName", serviceName);
153        map.put("active", Boolean.TRUE);
154
155        Collection<KrmsTypeBo> krmsTypeBos = findMatching(dataObjectService, KrmsTypeBo.class,
156                Collections.unmodifiableMap(map));
157
158        return convertListOfBosToImmutables(krmsTypeBos);
159    }
160
161    @Override
162    public List<KrmsTypeDefinition> findAllTypes() {
163        final Map<String, Object> map = new HashMap<String, Object>();
164        map.put("active", Boolean.TRUE);
165
166        Collection<KrmsTypeBo> krmsTypeBos = findMatching(dataObjectService, KrmsTypeBo.class,
167                Collections.unmodifiableMap(map));
168
169        return convertListOfBosToImmutables(krmsTypeBos);
170    }
171
172    @Override
173    public List<KrmsTypeDefinition> findAllAgendaTypesByContextId(String contextId) {
174        if (StringUtils.isBlank(contextId)) {
175            throw new RiceIllegalArgumentException("contextId was a null or blank value");
176        }
177
178        final Map<String, Object> map = new HashMap<String, Object>();
179        map.put("contextId", contextId);
180        Collection<ContextValidAgendaBo> contextValidAgendaBos = findMatchingOrderBy(dataObjectService,
181                ContextValidAgendaBo.class, Collections.unmodifiableMap(map), "agendaType.name", true);
182        List<KrmsTypeDefinition> agendaTypes = new ArrayList<KrmsTypeDefinition>();
183
184        for (ContextValidAgendaBo contextValidAgendaBo : contextValidAgendaBos) {
185            agendaTypes.add(KrmsTypeBo.to(contextValidAgendaBo.getAgendaType()));
186        }
187
188        return agendaTypes;
189    }
190
191    @Override
192    public KrmsTypeDefinition getAgendaTypeByAgendaTypeIdAndContextId(String agendaTypeId, String contextId) {
193        if (StringUtils.isBlank(agendaTypeId)) {
194            throw new RiceIllegalArgumentException("agendaTypeId was a null or blank value");
195        }
196
197        if (StringUtils.isBlank(contextId)) {
198            throw new RiceIllegalArgumentException("contextId was a null or blank value");
199        }
200
201        final Map<String, Object> map = new HashMap<String, Object>();
202        map.put("agendaTypeId", agendaTypeId);
203        map.put("contextId", contextId);
204        ContextValidAgendaBo contextValidAgendaBo = findSingleMatching(dataObjectService, ContextValidAgendaBo.class,
205                Collections.unmodifiableMap(map));
206
207        return KrmsTypeBo.to(contextValidAgendaBo.getAgendaType());
208    }
209
210    @Override
211    public List<KrmsTypeDefinition> findAllRuleTypesByContextId(String contextId) {
212        if (StringUtils.isBlank(contextId)) {
213            throw new RiceIllegalArgumentException("contextId was a null or blank value");
214        }
215
216        final Map<String, Object> map = new HashMap<String, Object>();
217        map.put("contextId", contextId);
218        Collection<ContextValidRuleBo> contextValidRuleBos = findMatchingOrderBy(dataObjectService,
219                ContextValidRuleBo.class, Collections.unmodifiableMap(map), "ruleType.name", true);
220        List<KrmsTypeDefinition> ruleTypes = new ArrayList<KrmsTypeDefinition>();
221
222        for (ContextValidRuleBo contextValidRuleBo : contextValidRuleBos) {
223            ruleTypes.add(KrmsTypeBo.to(contextValidRuleBo.getRuleType()));
224        }
225
226        return ruleTypes;
227    }
228
229    @Override
230    public KrmsTypeDefinition getRuleTypeByRuleTypeIdAndContextId(String ruleTypeId, String contextId) {
231        if (StringUtils.isBlank(ruleTypeId)) {
232            throw new RiceIllegalArgumentException("ruleTypeId was a null or blank value");
233        }
234
235        if (StringUtils.isBlank(contextId)) {
236            throw new RiceIllegalArgumentException("contextId was a null or blank value");
237        }
238
239        final Map<String, Object> map = new HashMap<String, Object>();
240        map.put("ruleTypeId", ruleTypeId);
241        map.put("contextId", contextId);
242        ContextValidRuleBo contextValidRuleBo = findSingleMatching(dataObjectService, ContextValidRuleBo.class,
243                Collections.unmodifiableMap(map));
244
245        return KrmsTypeBo.to(contextValidRuleBo.getRuleType());
246    }
247
248    @Override
249    public List<KrmsTypeDefinition> findAllActionTypesByContextId(String contextId) {
250        if (StringUtils.isBlank(contextId)) {
251            throw new RiceIllegalArgumentException("contextId was a null or blank value");
252        }
253
254        final Map<String, Object> map = new HashMap<String, Object>();
255        map.put("contextId", contextId);
256        Collection<ContextValidActionBo> contextValidActionBos = findMatchingOrderBy(dataObjectService,
257                ContextValidActionBo.class, Collections.unmodifiableMap(map), "actionType.name", true);
258        List<KrmsTypeDefinition> actionTypes = new ArrayList<KrmsTypeDefinition>();
259
260        for (ContextValidActionBo contextValidActionBo : contextValidActionBos) {
261            actionTypes.add(KrmsTypeBo.to(contextValidActionBo.getActionType()));
262        }
263
264        return actionTypes;
265    }
266
267    @Override
268    public KrmsTypeDefinition getActionTypeByActionTypeIdAndContextId(String actionTypeId, String contextId) {
269        if (StringUtils.isBlank(actionTypeId)) {
270            throw new RiceIllegalArgumentException("actionTypeId was a null or blank value");
271        }
272
273        if (StringUtils.isBlank(contextId)) {
274            throw new RiceIllegalArgumentException("contextId was a null or blank value");
275        }
276
277        final Map<String, Object> map = new HashMap<String, Object>();
278        map.put("actionTypeId", actionTypeId);
279        map.put("contextId", contextId);
280        ContextValidActionBo contextValidActionBo = findSingleMatching(dataObjectService, ContextValidActionBo.class,
281                Collections.unmodifiableMap(map));
282
283        return KrmsTypeBo.to(contextValidActionBo.getActionType());
284    }
285
286    @Override
287    public KrmsAttributeDefinition getAttributeDefinitionById(String attributeDefinitionId) {
288        if (StringUtils.isBlank(attributeDefinitionId)) {
289            throw new RiceIllegalArgumentException("attributeDefinitionId was a null or blank value");
290        }
291
292        KrmsAttributeDefinitionBo krmsAttributeDefinitionBo = dataObjectService.find(KrmsAttributeDefinitionBo.class,
293                attributeDefinitionId);
294
295        return KrmsAttributeDefinitionBo.to(krmsAttributeDefinitionBo);
296    }
297
298    @Override
299    public KrmsAttributeDefinition getAttributeDefinitionByName(@WebParam(name = "namespaceCode") String namespaceCode,
300            @WebParam(name = "name") String name) {
301        if (StringUtils.isBlank(namespaceCode)) {
302            throw new RiceIllegalArgumentException("namespaceCode was a null or blank value");
303        }
304
305        if (StringUtils.isBlank(name)) {
306            throw new RiceIllegalArgumentException("name was a null or blank value");
307        }
308
309        final Map<String, Object> criteria = new HashMap<String, Object>();
310        criteria.put("name", name);
311        criteria.put("namespace", namespaceCode);
312
313        Collection<KrmsAttributeDefinitionBo> attributeDefinitionBos = findMatching(dataObjectService,
314                KrmsAttributeDefinitionBo.class, criteria);
315
316        if (CollectionUtils.isEmpty(attributeDefinitionBos)) {
317            return null;
318        }
319
320        return KrmsAttributeDefinitionBo.to(attributeDefinitionBos.iterator().next());
321    }
322
323    /**
324     * Converts a immutable {@link KrmsTypeDefinition} to its mutable {@link KrmsTypeBo} counterpart.
325     *
326     * @param krmsType the immutable object.
327     * @return a {@link KrmsTypeBo} the mutable KrmsTypeBo.
328     */
329    public KrmsTypeBo from(KrmsTypeDefinition krmsType) {
330        if (krmsType == null) {
331            return null;
332        }
333
334        KrmsTypeBo krmsTypeBo = new KrmsTypeBo();
335        krmsTypeBo.setName(krmsType.getName());
336        krmsTypeBo.setNamespace(krmsType.getNamespace());
337        krmsTypeBo.setServiceName(krmsType.getServiceName());
338        krmsTypeBo.setId(krmsType.getId());
339        krmsTypeBo.setActive(krmsType.isActive());
340        krmsTypeBo.setVersionNumber(krmsType.getVersionNumber());
341
342        return krmsTypeBo;
343    }
344
345    /**
346     * Sets the dataObjectService attribute value.
347     *
348     * @param dataObjectService The dataObjectService to set.
349     */
350    public void setDataObjectService(final DataObjectService dataObjectService) {
351        this.dataObjectService = dataObjectService;
352    }
353
354    /**
355     * Converts a List<KrmsTypeBo> to an Unmodifiable List<KrmsType>
356     *
357     * @param krmsTypeBos a mutable List<KrmsTypeBo> to made completely immutable.
358     * @return An unmodifiable List<KrmsType>
359     */
360    protected List<KrmsTypeDefinition> convertListOfBosToImmutables(final Collection<KrmsTypeBo> krmsTypeBos) {
361        ArrayList<KrmsTypeDefinition> krmsTypes = new ArrayList<KrmsTypeDefinition>();
362
363        for (KrmsTypeBo bo : krmsTypeBos) {
364            KrmsTypeDefinition krmsType = KrmsTypeBo.to(bo);
365            krmsTypes.add(krmsType);
366        }
367
368        return Collections.unmodifiableList(krmsTypes);
369    }
370}