001/**
002 * Copyright 2005-2012 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.core.api.exception.RiceIllegalStateException;
020import org.kuali.rice.krad.service.BusinessObjectService;
021import org.kuali.rice.krms.api.repository.language.NaturalLanguageTemplate;
022import org.kuali.rice.krms.api.repository.language.NaturalLanguageTemplaterContract;
023import org.kuali.rice.krms.api.repository.type.KrmsAttributeDefinition;
024import org.kuali.rice.krms.impl.util.KrmsImplConstants;
025
026import java.util.Collection;
027import java.util.Collections;
028import java.util.HashMap;
029import java.util.HashSet;
030import java.util.LinkedList;
031import java.util.List;
032import java.util.Map;
033import java.util.Set;
034import org.kuali.rice.krms.impl.repository.language.SimpleNaturalLanguageTemplater;
035
036/**
037 * Implementation of the @{link NaturalLanguageTemplateBoService} interface for accessing  {@link NaturalLanguageTemplateBo} related business objects.
038 * 
039 * @author Kuali Rice Team (rice.collab@kuali.org)
040 * 
041 */
042public final class NaturalLanguageTemplateBoServiceImpl
043    implements NaturalLanguageTemplateBoService
044{
045
046    private BusinessObjectService businessObjectService;
047    private KrmsAttributeDefinitionService attributeDefinitionService;
048    private NaturalLanguageTemplaterContract naturalLanguageTemplater = new SimpleNaturalLanguageTemplater ();
049
050    /**
051     * Sets the value of BusinessObjectService to the given value.
052     * 
053     * @param businessObjectService the BusinessObjectService value to set.
054     * 
055     */
056    public void setBusinessObjectService(BusinessObjectService businessObjectService) {
057        this.businessObjectService = businessObjectService;
058    }
059
060    public void setAttributeDefinitionService(KrmsAttributeDefinitionService attributeDefinitionService) {
061        this.attributeDefinitionService = attributeDefinitionService;
062    }
063
064    public KrmsAttributeDefinitionService getAttributeDefinitionService() {
065        if (attributeDefinitionService == null) {
066            attributeDefinitionService = KrmsRepositoryServiceLocator.getKrmsAttributeDefinitionService();
067        }
068        return attributeDefinitionService;
069    }
070
071    public NaturalLanguageTemplaterContract getNaturalLanguageTemplater() {
072        return naturalLanguageTemplater;
073    }
074
075    public void setNaturalLanguageTemplater(NaturalLanguageTemplaterContract naturalLanguageTemplater) {
076        this.naturalLanguageTemplater = naturalLanguageTemplater;
077    }
078
079    @Override
080    public NaturalLanguageTemplate createNaturalLanguageTemplate(NaturalLanguageTemplate naturalLanguageTemplate) {
081        incomingParamCheck(naturalLanguageTemplate , "naturalLanguageTemplate");
082        final String naturalLanguageTemplateIdKey = naturalLanguageTemplate.getId();
083        final NaturalLanguageTemplate existing = getNaturalLanguageTemplate(naturalLanguageTemplateIdKey);
084        if (existing != null){ throw new IllegalStateException("the NaturalLanguageTemplate to create already exists: " + naturalLanguageTemplate);     }
085        NaturalLanguageTemplateBo bo = (NaturalLanguageTemplateBo)businessObjectService.save(from(naturalLanguageTemplate));
086        return NaturalLanguageTemplateBo.to(bo);
087    }
088
089    @Override
090    public NaturalLanguageTemplate getNaturalLanguageTemplate(String naturalLanguageTemplateId) {
091        incomingParamCheck(naturalLanguageTemplateId , "naturalLanguageTemplateId");
092        NaturalLanguageTemplateBo bo = businessObjectService.findBySinglePrimaryKey(NaturalLanguageTemplateBo.class, naturalLanguageTemplateId);
093        return NaturalLanguageTemplateBo.to(bo);
094    }
095
096    @Override
097    public void updateNaturalLanguageTemplate(NaturalLanguageTemplate naturalLanguageTemplate) {
098        incomingParamCheck(naturalLanguageTemplate , "naturalLanguageTemplate");
099        final NaturalLanguageTemplate existing = getNaturalLanguageTemplate(naturalLanguageTemplate.getId());
100        if (existing == null){ throw new IllegalStateException("the NaturalLanguageTemplate to update does not exists: " + naturalLanguageTemplate);}
101        final NaturalLanguageTemplate toUpdate;
102        if (!existing.getId().equals(naturalLanguageTemplate.getId())){
103            // if passed in id does not match existing id, correct it
104            final NaturalLanguageTemplate.Builder builder = NaturalLanguageTemplate.Builder.create(naturalLanguageTemplate);
105            builder.setId(existing.getId());
106            toUpdate = builder.build();
107        } else {
108            toUpdate = naturalLanguageTemplate;
109        }
110
111        // copy all updateable fields to bo
112        NaturalLanguageTemplateBo boToUpdate = from(toUpdate);
113
114        // delete any old, existing attributes
115        Map<String,String> fields = new HashMap<String,String>(1);
116        fields.put(KrmsImplConstants.PropertyNames.NaturalLanguageTemplate.NATURAL_LANGUAGE_TEMPLATE_ID, toUpdate.getId()); // TODO verify PropertyNames.NaturalLanguageTemplate.NATURAL_LANGUAGE_TEMPLATE_ID
117        businessObjectService.deleteMatching(NaturalLanguageTemplateAttributeBo.class, fields);
118
119        // update the rule and create new attributes
120         businessObjectService.save(boToUpdate);
121    }
122
123    @Override
124    public void deleteNaturalLanguageTemplate(String naturalLanguageTemplateId) {
125        incomingParamCheck(naturalLanguageTemplateId , "naturalLanguageTemplateId");
126        final NaturalLanguageTemplate existing = getNaturalLanguageTemplate(naturalLanguageTemplateId);
127        if (existing == null){ throw new IllegalStateException("the NaturalLanguageTemplate to delete does not exists: " + naturalLanguageTemplateId);}
128        businessObjectService.delete(from(existing));
129    }
130
131    @Override
132    public List<NaturalLanguageTemplate> findNaturalLanguageTemplatesByAttributes(Map attributes) {
133        if (attributes == null) {
134            throw new IllegalArgumentException("attributes is null");
135        }
136        final Map<String, Object> map = new HashMap<String, Object>();
137        map.put("attributes", attributes);
138        List<NaturalLanguageTemplateBo> bos = (List<NaturalLanguageTemplateBo>) businessObjectService.findMatching(NaturalLanguageTemplateBo.class, map);
139        return convertBosToImmutables(bos);
140    }
141
142    @Override
143    public List<NaturalLanguageTemplate> findNaturalLanguageTemplatesByLanguageCode(String languageCode) {
144        if (org.apache.commons.lang.StringUtils.isBlank(languageCode)) {
145            throw new IllegalArgumentException("languageCode is null or blank");
146        }
147        final Map<String, Object> map = new HashMap<String, Object>();
148        map.put("languageCode", languageCode);
149        List<NaturalLanguageTemplateBo> bos = (List<NaturalLanguageTemplateBo>) businessObjectService.findMatching(NaturalLanguageTemplateBo.class, map);
150        return convertBosToImmutables(bos);
151    }
152
153    @Override
154    public NaturalLanguageTemplate findNaturalLanguageTemplateByLanguageCodeTypeIdAndNluId(String languageCode, String typeId, String naturalLanguageUsageId) {
155        if (org.apache.commons.lang.StringUtils.isBlank(languageCode)) {
156            throw new IllegalArgumentException("languageCode is null or blank");
157        }
158        final Map<String, Object> map = new HashMap<String, Object>();
159        map.put("languageCode", languageCode);
160        map.put("naturalLanguageUsageId", naturalLanguageUsageId);
161        map.put("typeId", typeId);
162        List<NaturalLanguageTemplateBo> bos = (List<NaturalLanguageTemplateBo>) businessObjectService.findMatching(NaturalLanguageTemplateBo.class, map);
163        return convertBosToImmutables(bos).get(0);
164    }
165
166    @Override
167    public List<NaturalLanguageTemplate> findNaturalLanguageTemplatesByNaturalLanguageUsage(String naturalLanguageUsageId) {
168        if (org.apache.commons.lang.StringUtils.isBlank(naturalLanguageUsageId)) {
169            throw new IllegalArgumentException("naturalLanguageUsageId is null or blank");
170        }
171        final Map<String, Object> map = new HashMap<String, Object>();
172        map.put("naturalLanguageUsageId", naturalLanguageUsageId);
173        List<NaturalLanguageTemplateBo> bos = (List<NaturalLanguageTemplateBo>) businessObjectService.findMatching(NaturalLanguageTemplateBo.class, map);
174        return convertBosToImmutables(bos);
175    }
176
177    @Override
178    public List<NaturalLanguageTemplate> findNaturalLanguageTemplatesByType(String typeId) {
179        if (org.apache.commons.lang.StringUtils.isBlank(typeId)) {
180            throw new IllegalArgumentException("typeId is null or blank");
181        }
182        final Map<String, Object> map = new HashMap<String, Object>();
183        map.put("typeId", typeId);
184        List<NaturalLanguageTemplateBo> bos = (List<NaturalLanguageTemplateBo>) businessObjectService.findMatching(NaturalLanguageTemplateBo.class, map);
185        return convertBosToImmutables(bos);
186    }
187
188    @Override
189    public List<NaturalLanguageTemplate> findNaturalLanguageTemplatesByTemplate(String template) {
190        if (org.apache.commons.lang.StringUtils.isBlank(template)) {
191            throw new IllegalArgumentException("template is null or blank");
192        }
193        final Map<String, Object> map = new HashMap<String, Object>();
194        map.put("template", template);
195        List<NaturalLanguageTemplateBo> bos = (List<NaturalLanguageTemplateBo>) businessObjectService.findMatching(NaturalLanguageTemplateBo.class, map);
196        return convertBosToImmutables(bos);
197    }
198
199    public List<NaturalLanguageTemplate> convertBosToImmutables(final Collection<NaturalLanguageTemplateBo> naturalLanguageTemplateBos) {
200        List<NaturalLanguageTemplate> immutables = new LinkedList<NaturalLanguageTemplate>();
201        if (naturalLanguageTemplateBos != null) {
202            NaturalLanguageTemplate immutable = null;
203            for (NaturalLanguageTemplateBo bo : naturalLanguageTemplateBos ) {
204                immutable = to(bo);
205                immutables.add(immutable);
206            }
207        }
208        return Collections.unmodifiableList(immutables);
209    }
210
211    @Override
212    public NaturalLanguageTemplate to(NaturalLanguageTemplateBo naturalLanguageTemplateBo) {
213        return NaturalLanguageTemplateBo.to(naturalLanguageTemplateBo);
214    }
215
216    public NaturalLanguageTemplateBo from(NaturalLanguageTemplate naturalLanguageTemplate) {
217        return NaturalLanguageTemplateBo.from(naturalLanguageTemplate);
218    }
219
220    private Collection<NaturalLanguageTemplateAttributeBo> buildAttributes(NaturalLanguageTemplate im, Collection<NaturalLanguageTemplateAttributeBo> attributes) {
221        // build a map from attribute name to definition
222        Map<String, KrmsAttributeDefinition> attributeDefinitionMap = new HashMap<String, KrmsAttributeDefinition>();
223
224        List<KrmsAttributeDefinition> attributeDefinitions = getAttributeDefinitionService().findAttributeDefinitionsByType(im.getTypeId());
225
226        for (KrmsAttributeDefinition attributeDefinition : attributeDefinitions) {
227            attributeDefinitionMap.put(attributeDefinition.getName(), attributeDefinition);
228        }
229
230        // for each entry, build a NaturalLanguageTemplateAttributeBo and add it
231        if (im.getAttributes() != null) {
232            for (Map.Entry<String,String> entry  : im.getAttributes().entrySet()) {
233                KrmsAttributeDefinition attrDef = attributeDefinitionMap.get(entry.getKey());
234
235                if (attrDef != null) {
236                    NaturalLanguageTemplateAttributeBo attributeBo = new NaturalLanguageTemplateAttributeBo();
237                    attributeBo.setNaturalLanguageTemplateId( im.getId() );
238                    attributeBo.setAttributeDefinitionId(attrDef.getId());
239                    attributeBo.setValue(entry.getValue());
240                    attributeBo.setAttributeDefinition(KrmsAttributeDefinitionBo.from(attrDef));
241                    attributes.add(attributeBo);
242                } else {
243                    throw new RiceIllegalStateException("there is no attribute definition with the name '" +
244                                 entry.getKey() + "' that is valid for the naturalLanguageTemplate type with id = '" + im.getTypeId() +"'");
245                }
246            }
247        }
248        return attributes;
249    }
250
251    private Set<NaturalLanguageTemplateAttributeBo> buildAttributeBoSet(NaturalLanguageTemplate im) {
252        Set<NaturalLanguageTemplateAttributeBo> attributes = new HashSet<NaturalLanguageTemplateAttributeBo>();
253        return (Set)buildAttributes(im, attributes);
254    }
255
256    private List<NaturalLanguageTemplateAttributeBo> buildAttributeBoList(NaturalLanguageTemplate im) {
257        List<NaturalLanguageTemplateAttributeBo> attributes = new LinkedList<NaturalLanguageTemplateAttributeBo>();
258        return (List)buildAttributes(im, attributes);
259    }
260
261    private void incomingParamCheck(Object object, String name) {
262        if (object == null) {
263            throw new IllegalArgumentException(name + " was null");
264        } else if (object instanceof String
265                && StringUtils.isBlank((String)object)) {
266            throw new IllegalArgumentException(name + " was blank");
267        }
268    }
269
270}