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