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