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 java.util.ArrayList;
019import java.util.Collection;
020import java.util.Collections;
021import java.util.HashMap;
022import java.util.List;
023import java.util.Map;
024
025import org.apache.commons.lang.StringUtils;
026import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
027import org.kuali.rice.krad.service.BusinessObjectService;
028import org.kuali.rice.krms.api.repository.term.TermDefinition;
029import org.kuali.rice.krms.api.repository.term.TermResolverDefinition;
030import org.kuali.rice.krms.api.repository.term.TermSpecificationDefinition;
031import org.kuali.rice.krms.impl.util.KrmsImplConstants;
032import org.kuali.rice.krms.impl.repository.ContextValidTermBo;
033import org.kuali.rice.krms.impl.repository.TermSpecificationBo;
034import org.springframework.util.CollectionUtils;
035
036/**
037 * Implementation of {@link TermBoService}
038 *
039 * @author Kuali Rice Team (rice.collab@kuali.org)
040 */
041public class TermBoServiceImpl implements TermBoService {
042
043    private BusinessObjectService businessObjectService;
044
045    /**
046     * @param businessObjectService the businessObjectService to set
047     */
048    public void setBusinessObjectService(BusinessObjectService businessObjectService) {
049        this.businessObjectService = businessObjectService;
050    }
051
052    /**
053     * @see org.kuali.rice.krms.impl.repository.TermBoService#getTermSpecificationById(java.lang.String)
054     */
055    @Override
056    public TermSpecificationDefinition getTermSpecificationById(String id) {
057        TermSpecificationDefinition result = null;
058
059        if (StringUtils.isBlank(id)) {
060            throw new RiceIllegalArgumentException("id must not be blank or null");
061        }
062
063        TermSpecificationBo termSpecificationBo = businessObjectService.findBySinglePrimaryKey(
064                TermSpecificationBo.class, id);
065
066        if (termSpecificationBo != null) {
067            if (termSpecificationBo.getContextIds() != null
068                    && termSpecificationBo.getContextIds().isEmpty()
069                    && termSpecificationBo.getContexts() != null
070                    && !termSpecificationBo.getContexts().isEmpty()) {
071                List<String> contextIds = new ArrayList<String>();
072                for (ContextBo context : termSpecificationBo.getContexts()) {
073                    contextIds.add(context.getId());
074                }
075                termSpecificationBo.setContextIds(contextIds);
076            }
077
078            result = TermSpecificationDefinition.Builder.create(termSpecificationBo).build();
079        }
080
081        return result;
082    }
083
084    /**
085     * @see org.kuali.rice.krms.impl.repository.TermBoService#createTermSpecification(org.kuali.rice.krms.api.repository.term.TermSpecificationDefinition)
086     */
087    @Override
088    public TermSpecificationDefinition createTermSpecification(TermSpecificationDefinition termSpec) {
089        if (!StringUtils.isBlank(termSpec.getId())) {
090            throw new RiceIllegalArgumentException("for creation, TermSpecification.id must be null");
091        }
092
093        TermSpecificationBo termSpecBo = TermSpecificationBo.from(termSpec);
094
095        termSpecBo = businessObjectService.save(termSpecBo);
096
097        // save relations to the contexts on the BO
098        if (!CollectionUtils.isEmpty(termSpec.getContextIds())) {
099            for (String contextId : termSpec.getContextIds()) {
100                ContextValidTermBo contextValidTerm = new ContextValidTermBo();
101                contextValidTerm.setContextId(contextId);
102                contextValidTerm.setTermSpecificationId(termSpecBo.getId());
103                businessObjectService.save(contextValidTerm);
104            }
105        }
106
107        return TermSpecificationBo.to(termSpecBo);
108    }
109
110    @Override
111    public void updateTermSpecification(TermSpecificationDefinition termSpec) throws RiceIllegalArgumentException {
112        if (termSpec == null) {
113            throw new IllegalArgumentException("term specification is null");
114        }
115
116        // must already exist to be able to update
117        final String termSpecificationId = termSpec.getId();
118        final TermSpecificationBo existing = businessObjectService.findBySinglePrimaryKey(TermSpecificationBo.class,
119                termSpecificationId);
120
121        if (existing == null) {
122            throw new IllegalStateException("the term specification does not exist: " + termSpec);
123        }
124
125        final TermSpecificationDefinition toUpdate;
126
127        if (!existing.getId().equals(termSpec.getId())) {
128            // if passed in id does not match existing id, correct it
129            final TermSpecificationDefinition.Builder builder = TermSpecificationDefinition.Builder.create(termSpec);
130            builder.setId(existing.getId());
131            toUpdate = builder.build();
132        } else {
133            toUpdate = termSpec;
134        }
135
136        // copy all updateable fields to bo
137        TermSpecificationBo boToUpdate = TermSpecificationBo.from(toUpdate);
138
139        //        // delete any old, existing attributes DOES NOT HAVE ANY
140        //        Map<String, String> fields = new HashMap<String, String>(1);
141        //        fields.put(KrmsImplConstants.PropertyNames.TermSpecification.TERM_SPECIFICATION_ID, toUpdate.getId());
142        //        businessObjectService.deleteMatching(TermSpecificationAttributeBo.class, fields);
143
144        // update the rule and create new attributes
145        businessObjectService.save(boToUpdate);
146
147    }
148
149    @Override
150    public void deleteTermSpecification(String id) throws RiceIllegalArgumentException {
151        if (id == null) {
152            throw new RiceIllegalArgumentException("agendaId is null");
153        }
154
155        final TermSpecificationBo existing = businessObjectService.findBySinglePrimaryKey(TermSpecificationBo.class,
156                id);
157
158        if (existing == null) {
159            throw new IllegalStateException("the TermSpecification to delete does not exists: " + id);
160        }
161
162        businessObjectService.delete(existing);
163    }
164
165    /**
166     * @see org.kuali.rice.krms.impl.repository.TermBoService#createTerm(org.kuali.rice.krms.api.repository.term.TermDefinition)
167     */
168    @Override
169    public TermDefinition createTerm(TermDefinition termDef) {
170        if (!StringUtils.isBlank(termDef.getId())) {
171            throw new RiceIllegalArgumentException("for creation, TermDefinition.id must be null");
172        }
173
174        TermBo termBo = TermBo.from(termDef);
175
176        businessObjectService.save(termBo);
177
178        return TermBo.to(termBo);
179    }
180
181    @Override
182    public void updateTerm(TermDefinition term) throws RiceIllegalArgumentException {
183        if (term == null) {
184            throw new IllegalArgumentException("term is null");
185        }
186
187        // must already exist to be able to update
188        final String termId = term.getId();
189        final TermBo existing = businessObjectService.findBySinglePrimaryKey(TermBo.class, termId);
190
191        if (existing == null) {
192            throw new IllegalStateException("the term resolver does not exist: " + term);
193        }
194
195        final TermDefinition toUpdate;
196
197        if (!existing.getId().equals(term.getId())) {
198            // if passed in id does not match existing id, correct it
199            final TermDefinition.Builder builder = TermDefinition.Builder.create(term);
200            builder.setId(existing.getId());
201            toUpdate = builder.build();
202        } else {
203            toUpdate = term;
204        }
205
206        // copy all updateable fields to bo
207        TermBo boToUpdate = TermBo.from(toUpdate);
208
209        // delete any old, existing parameters
210        Map<String, String> fields = new HashMap<String, String>(1);
211        fields.put(KrmsImplConstants.PropertyNames.Term.TERM_ID, toUpdate.getId());
212        businessObjectService.deleteMatching(TermParameterBo.class, fields);
213
214        // update the rule and create new attributes
215        businessObjectService.save(boToUpdate);
216    }
217
218    @Override
219    public void deleteTerm(String id) throws RiceIllegalArgumentException {
220        if (id == null) {
221            throw new RiceIllegalArgumentException("termId is null");
222        }
223
224        TermBo existing = businessObjectService.findBySinglePrimaryKey(TermBo.class, id);
225
226        if (existing == null) {
227            throw new IllegalStateException("the term to delete does not exists: " + id);
228        }
229
230        businessObjectService.delete(existing);
231    }
232
233    /**
234     * @see org.kuali.rice.krms.impl.repository.TermBoService#createTermResolver(org.kuali.rice.krms.api.repository.term.TermResolverDefinition)
235     */
236    @Override
237    public TermResolverDefinition createTermResolver(TermResolverDefinition termResolver) {
238        if (!StringUtils.isBlank(termResolver.getId())) {
239            throw new RiceIllegalArgumentException("for creation, TermResolverDefinition.id must be null");
240        }
241
242        TermResolverBo termResolverBo = TermResolverBo.from(termResolver);
243
244        termResolverBo = (TermResolverBo) businessObjectService.save(termResolverBo);
245
246        return TermResolverBo.to(termResolverBo);
247    }
248
249    @Override
250    public void updateTermResolver(TermResolverDefinition termResolver) throws RiceIllegalArgumentException {
251        if (termResolver == null) {
252            throw new IllegalArgumentException("term resolver is null");
253        }
254
255        // must already exist to be able to update
256        final String termResolverId = termResolver.getId();
257        final TermResolverBo existing = businessObjectService.findBySinglePrimaryKey(TermResolverBo.class,
258                termResolverId);
259
260        if (existing == null) {
261            throw new IllegalStateException("the term resolver does not exist: " + termResolver);
262        }
263
264        final TermResolverDefinition toUpdate;
265
266        if (!existing.getId().equals(termResolver.getId())) {
267            // if passed in id does not match existing id, correct it
268            final TermResolverDefinition.Builder builder = TermResolverDefinition.Builder.create(termResolver);
269            builder.setId(existing.getId());
270            toUpdate = builder.build();
271        } else {
272            toUpdate = termResolver;
273        }
274
275        // copy all updateable fields to bo
276        TermResolverBo boToUpdate = TermResolverBo.from(toUpdate);
277
278        // delete any old, existing attributes
279        Map<String, String> fields = new HashMap<String, String>(1);
280        fields.put(KrmsImplConstants.PropertyNames.TermResolver.TERM_RESOLVER_ID, toUpdate.getId());
281        businessObjectService.deleteMatching(TermResolverAttributeBo.class, fields);
282
283        // update the rule and create new attributes
284        businessObjectService.save(boToUpdate);
285    }
286
287    @Override
288    public void deleteTermResolver(String id) throws RiceIllegalArgumentException {
289        if (id == null) {
290            throw new RiceIllegalArgumentException("agendaId is null");
291        }
292
293        TermSpecificationBo existing = businessObjectService.findBySinglePrimaryKey(TermSpecificationBo.class, id);
294
295        if (existing == null) {
296            throw new IllegalStateException("the TermResolver to delete does not exists: " + id);
297        }
298
299        businessObjectService.delete(existing);
300    }
301
302    /**
303     * @see org.kuali.rice.krms.impl.repository.TermBoService#getTerm(java.lang.String)
304     */
305    @Override
306    public TermDefinition getTerm(String id) {
307        TermDefinition result = null;
308
309        if (StringUtils.isBlank(id)) {
310            throw new RiceIllegalArgumentException("id must not be blank or null");
311        }
312
313        TermBo termBo = businessObjectService.findBySinglePrimaryKey(TermBo.class, id);
314
315        if (termBo != null) {
316            result = TermBo.to(termBo);
317        }
318
319        return result;
320    }
321
322    /**
323     * @see org.kuali.rice.krms.impl.repository.TermBoService#getTermResolverById(java.lang.String)
324     */
325    @Override
326    public TermResolverDefinition getTermResolverById(String id) {
327        TermResolverDefinition result = null;
328
329        if (StringUtils.isBlank(id)) {
330            throw new RiceIllegalArgumentException("id must not be blank or null");
331        }
332
333        TermResolverBo termResolverBo = businessObjectService.findBySinglePrimaryKey(TermResolverBo.class, id);
334
335        if (termResolverBo != null) {
336            result = TermResolverBo.to(termResolverBo);
337        }
338
339        return result;
340    }
341
342    @Override
343    public List<TermResolverDefinition> findTermResolversByOutputId(String id, String namespace) {
344        List<TermResolverDefinition> results = null;
345
346        if (StringUtils.isBlank(id)) {
347            throw new RiceIllegalArgumentException("id must not be blank or null");
348        }
349
350        if (StringUtils.isBlank(namespace)) {
351            throw new RiceIllegalArgumentException("namespace must not be blank or null");
352        }
353
354        Map<String, String> criteria = new HashMap<String, String>(2);
355
356        criteria.put("outputId", id);
357        criteria.put("namespace", namespace);
358
359        Collection<TermResolverBo> termResolverBos = businessObjectService.findMatching(TermResolverBo.class, criteria);
360
361        if (!CollectionUtils.isEmpty(termResolverBos)) {
362            results = new ArrayList<TermResolverDefinition>(termResolverBos.size());
363
364            for (TermResolverBo termResolverBo : termResolverBos) {
365                results.add(TermResolverBo.to(termResolverBo));
366            }
367        } else {
368            results = Collections.emptyList();
369        }
370
371        return results;
372    }
373
374    @Override
375    public List<TermResolverDefinition> findTermResolversByNamespace(String namespace) {
376        List<TermResolverDefinition> results = null;
377
378        if (StringUtils.isBlank(namespace)) {
379            throw new RiceIllegalArgumentException("namespace must not be blank or null");
380        }
381
382        Map fieldValues = new HashMap();
383        fieldValues.put("namespace", namespace);
384
385        Collection<TermResolverBo> termResolverBos = businessObjectService.findMatching(TermResolverBo.class,
386                fieldValues);
387
388        if (!CollectionUtils.isEmpty(termResolverBos)) {
389            results = new ArrayList<TermResolverDefinition>(termResolverBos.size());
390
391            for (TermResolverBo termResolverBo : termResolverBos) {
392                if (termResolverBo != null) {
393                    results.add(TermResolverBo.to(termResolverBo));
394                }
395            }
396        } else {
397            results = Collections.emptyList();
398        }
399
400        return results;
401    }
402
403    @Override
404    public TermResolverDefinition getTermResolverByNameAndNamespace(String name,
405            String namespace) throws RiceIllegalArgumentException {
406        if (StringUtils.isBlank(name)) {
407            throw new IllegalArgumentException("name is null or blank");
408        }
409
410        if (StringUtils.isBlank(namespace)) {
411            throw new IllegalArgumentException("namespace is null or blank");
412        }
413
414        final Map<String, Object> map = new HashMap<String, Object>();
415        map.put("name", name);
416        map.put("namespace", namespace);
417        TermResolverBo bo = businessObjectService.findByPrimaryKey(TermResolverBo.class, map);
418
419        return TermResolverBo.to(bo);
420    }
421
422    @Override
423    public TermSpecificationDefinition getTermSpecificationByNameAndNamespace(String name,
424            String namespace) throws RiceIllegalArgumentException {
425        if (StringUtils.isBlank(name)) {
426            throw new IllegalArgumentException("name is null or blank");
427        }
428
429        if (StringUtils.isBlank(namespace)) {
430            throw new IllegalArgumentException("namespace is null or blank");
431        }
432
433        final Map<String, Object> map = new HashMap<String, Object>();
434        map.put("name", name);
435        map.put("namespace", namespace);
436        TermSpecificationBo bo = businessObjectService.findByPrimaryKey(TermSpecificationBo.class, map);
437
438        return TermSpecificationBo.to(bo);
439    }
440
441    @Override
442    public List<TermSpecificationDefinition> findAllTermSpecificationsByContextId(String contextId) {
443        List<TermSpecificationDefinition> results = null;
444
445        if (StringUtils.isBlank(contextId)) {
446            throw new RiceIllegalArgumentException("contextId must not be blank or null");
447        }
448
449        Collection<ContextValidTermBo> contextValidTerms = businessObjectService.findMatching(ContextValidTermBo.class,
450                Collections.singletonMap("contextId", contextId));
451
452        if (!CollectionUtils.isEmpty(contextValidTerms)) {
453            results = new ArrayList<TermSpecificationDefinition>(contextValidTerms.size());
454            for (ContextValidTermBo validTerm : contextValidTerms) {
455                results.add(TermSpecificationBo.to(validTerm.getTermSpecification()));
456            }
457        } else {
458            results = Collections.emptyList();
459        }
460
461        return results;
462    }
463}