View Javadoc
1   /**
2    * Copyright 2005-2016 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.krms.impl.repository;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
20  import org.kuali.rice.core.api.exception.RiceIllegalStateException;
21  import org.kuali.rice.krad.data.DataObjectService;
22  import org.kuali.rice.krad.data.PersistenceOption;
23  import org.kuali.rice.krms.api.repository.language.NaturalLanguageTemplate;
24  import org.kuali.rice.krms.api.repository.language.NaturalLanguageTemplaterContract;
25  import org.kuali.rice.krms.api.repository.type.KrmsAttributeDefinition;
26  import org.kuali.rice.krms.impl.repository.language.SimpleNaturalLanguageTemplater;
27  import org.kuali.rice.krms.impl.util.KrmsImplConstants;
28  
29  import java.util.Collection;
30  import java.util.Collections;
31  import java.util.HashMap;
32  import java.util.HashSet;
33  import java.util.LinkedList;
34  import java.util.List;
35  import java.util.Map;
36  import java.util.Set;
37  
38  import static org.kuali.rice.krms.impl.repository.BusinessObjectServiceMigrationUtils.deleteMatching;
39  import static org.kuali.rice.krms.impl.repository.BusinessObjectServiceMigrationUtils.findMatching;
40  
41  /**
42   * Implementation of the @{link NaturalLanguageTemplateBoService} interface for accessing  {@link
43   * NaturalLanguageTemplateBo} related business objects.
44   *
45   * @author Kuali Rice Team (rice.collab@kuali.org)
46   */
47  public class NaturalLanguageTemplateBoServiceImpl implements NaturalLanguageTemplateBoService {
48  
49      private DataObjectService dataObjectService;
50      private KrmsAttributeDefinitionService attributeDefinitionService;
51      private NaturalLanguageTemplaterContract naturalLanguageTemplater = new SimpleNaturalLanguageTemplater();
52  
53      /**
54       * Sets the value of DataObjectService to the given value.
55       *
56       * @param dataObjectService the DataObjectService value to set.
57       */
58      public void setDataObjectService(DataObjectService dataObjectService) {
59          this.dataObjectService = dataObjectService;
60      }
61  
62      public void setAttributeDefinitionService(KrmsAttributeDefinitionService attributeDefinitionService) {
63          this.attributeDefinitionService = attributeDefinitionService;
64      }
65  
66      public KrmsAttributeDefinitionService getAttributeDefinitionService() {
67          if (attributeDefinitionService == null) {
68              attributeDefinitionService = KrmsRepositoryServiceLocator.getKrmsAttributeDefinitionService();
69          }
70  
71          return attributeDefinitionService;
72      }
73  
74      public NaturalLanguageTemplaterContract getNaturalLanguageTemplater() {
75          return naturalLanguageTemplater;
76      }
77  
78      public void setNaturalLanguageTemplater(NaturalLanguageTemplaterContract naturalLanguageTemplater) {
79          this.naturalLanguageTemplater = naturalLanguageTemplater;
80      }
81  
82      @Override
83      public NaturalLanguageTemplate createNaturalLanguageTemplate(NaturalLanguageTemplate naturalLanguageTemplate) {
84          incomingParamCheck(naturalLanguageTemplate, "naturalLanguageTemplate");
85          NaturalLanguageTemplateBo bo;
86          NaturalLanguageTemplate naturalLanguageTemplateUpdated;
87  
88          if (StringUtils.isNotBlank(naturalLanguageTemplate.getId())) {
89              final String naturalLanguageTemplateIdKey = naturalLanguageTemplate.getId();
90              final NaturalLanguageTemplate existing = getNaturalLanguageTemplate(naturalLanguageTemplateIdKey);
91  
92              if (existing != null) {
93                  throw new IllegalStateException(
94                          "the NaturalLanguageTemplate to create already exists: " + naturalLanguageTemplate);
95              }
96  
97              bo = dataObjectService.save(from(naturalLanguageTemplate), PersistenceOption.FLUSH);
98  
99              naturalLanguageTemplateUpdated = NaturalLanguageTemplateBo.to(bo);
100         } else {
101             Map<String, String> attributes = new HashMap<String, String>(naturalLanguageTemplate.getAttributes());
102 
103             bo = dataObjectService.save(from(naturalLanguageTemplate), PersistenceOption.FLUSH);
104 
105             NaturalLanguageTemplate.Builder naturalLanguageTemplateBuilder = NaturalLanguageTemplate.Builder.create(
106                     bo.getLanguageCode(), bo.getNaturalLanguageUsageId(), bo.getTemplate(), bo.getTypeId());
107             naturalLanguageTemplateBuilder.setActive(bo.isActive());
108             naturalLanguageTemplateBuilder.setId(bo.getId());
109             naturalLanguageTemplateBuilder.setVersionNumber(bo.getVersionNumber());
110             naturalLanguageTemplateBuilder.setAttributes(attributes);
111             naturalLanguageTemplateUpdated = naturalLanguageTemplateBuilder.build();
112             updateNaturalLanguageTemplate(naturalLanguageTemplateUpdated);
113         }
114 
115         return naturalLanguageTemplateUpdated;
116     }
117 
118     @Override
119     public NaturalLanguageTemplate getNaturalLanguageTemplate(String naturalLanguageTemplateId) {
120         incomingParamCheck(naturalLanguageTemplateId, "naturalLanguageTemplateId");
121         NaturalLanguageTemplateBo bo = dataObjectService.find(NaturalLanguageTemplateBo.class,
122                 naturalLanguageTemplateId);
123 
124         return NaturalLanguageTemplateBo.to(bo);
125     }
126 
127     @Override
128     public NaturalLanguageTemplate updateNaturalLanguageTemplate(NaturalLanguageTemplate naturalLanguageTemplate) {
129         incomingParamCheck(naturalLanguageTemplate, "naturalLanguageTemplate");
130         final NaturalLanguageTemplate existing = getNaturalLanguageTemplate(naturalLanguageTemplate.getId());
131 
132         if (existing == null) {
133             throw new IllegalStateException(
134                     "the NaturalLanguageTemplate to update does not exists: " + naturalLanguageTemplate);
135         }
136 
137         final NaturalLanguageTemplate toUpdate;
138 
139         if (!existing.getId().equals(naturalLanguageTemplate.getId())) {
140             // if passed in id does not match existing id, correct it
141             final NaturalLanguageTemplate.Builder builder = NaturalLanguageTemplate.Builder.create(
142                     naturalLanguageTemplate);
143             builder.setId(existing.getId());
144             toUpdate = builder.build();
145         } else {
146             toUpdate = naturalLanguageTemplate;
147         }
148 
149         // copy all updateable fields to bo
150         NaturalLanguageTemplateBo boToUpdate = from(toUpdate);
151 
152         // delete any old, existing attributes
153         Map<String, String> fields = new HashMap<String, String>(1);
154         fields.put(KrmsImplConstants.PropertyNames.NaturalLanguageTemplate.NATURAL_LANGUAGE_TEMPLATE_ID,
155                 toUpdate.getId()); // TODO verify PropertyNames.NaturalLanguageTemplate.NATURAL_LANGUAGE_TEMPLATE_ID
156         deleteMatching(dataObjectService, NaturalLanguageTemplateAttributeBo.class, fields);
157 
158         // update the rule and create new attributes
159         NaturalLanguageTemplateBo updatedData = dataObjectService.save(boToUpdate, PersistenceOption.FLUSH);
160 
161         return to(updatedData);
162     }
163 
164     @Override
165     public void deleteNaturalLanguageTemplate(String naturalLanguageTemplateId) {
166         incomingParamCheck(naturalLanguageTemplateId, "naturalLanguageTemplateId");
167         final NaturalLanguageTemplate existing = getNaturalLanguageTemplate(naturalLanguageTemplateId);
168 
169         if (existing == null) {
170             throw new IllegalStateException(
171                     "the NaturalLanguageTemplate to delete does not exists: " + naturalLanguageTemplateId);
172         }
173 
174         // delete any existing attributes
175         Map<String, String> fields = new HashMap<String, String>(1);
176         fields.put(KrmsImplConstants.PropertyNames.NaturalLanguageTemplate.NATURAL_LANGUAGE_TEMPLATE_ID,
177                 existing.getId());
178         deleteMatching(dataObjectService, NaturalLanguageTemplateAttributeBo.class, fields);
179 
180         dataObjectService.delete(from(existing));
181     }
182 
183     @Override
184     public List<NaturalLanguageTemplate> findNaturalLanguageTemplatesByAttributes(Map attributes) {
185         if (attributes == null) {
186             throw new IllegalArgumentException("attributes is null");
187         }
188 
189         final Map<String, Object> map = new HashMap<String, Object>();
190         map.put("attributes", attributes);
191         List<NaturalLanguageTemplateBo> bos = findMatching(dataObjectService, NaturalLanguageTemplateBo.class, map);
192 
193         return convertBosToImmutables(bos);
194     }
195 
196     @Override
197     public List<NaturalLanguageTemplate> findNaturalLanguageTemplatesByLanguageCode(String languageCode) {
198         if (org.apache.commons.lang.StringUtils.isBlank(languageCode)) {
199             throw new IllegalArgumentException("languageCode is null or blank");
200         }
201 
202         final Map<String, Object> map = new HashMap<String, Object>();
203         map.put("languageCode", languageCode);
204         List<NaturalLanguageTemplateBo> bos = findMatching(dataObjectService, NaturalLanguageTemplateBo.class, map);
205 
206         return convertBosToImmutables(bos);
207     }
208 
209     @Override
210     public NaturalLanguageTemplate findNaturalLanguageTemplateByLanguageCodeTypeIdAndNluId(String languageCode,
211             String typeId, String naturalLanguageUsageId) {
212         if (org.apache.commons.lang.StringUtils.isBlank(languageCode)) {
213             throw new IllegalArgumentException("languageCode is null or blank");
214         }
215 
216         final Map<String, Object> map = new HashMap<String, Object>();
217         map.put("languageCode", languageCode);
218         map.put("naturalLanguageUsageId", naturalLanguageUsageId);
219         map.put("typeId", typeId);
220         List<NaturalLanguageTemplateBo> bos = findMatching(dataObjectService, NaturalLanguageTemplateBo.class, map);
221 
222         if (bos.isEmpty()) {
223             return null;
224         }
225 
226         if (bos.size() > 1) {
227             throw new RiceIllegalArgumentException(
228                     languageCode + typeId + naturalLanguageUsageId + " is supposed to be unique");
229         }
230 
231         return convertBosToImmutables(bos).get(0);
232     }
233 
234     @Override
235     public List<NaturalLanguageTemplate> findNaturalLanguageTemplatesByNaturalLanguageUsage(
236             String naturalLanguageUsageId) {
237         if (org.apache.commons.lang.StringUtils.isBlank(naturalLanguageUsageId)) {
238             throw new IllegalArgumentException("naturalLanguageUsageId is null or blank");
239         }
240 
241         final Map<String, Object> map = new HashMap<String, Object>();
242         map.put("naturalLanguageUsageId", naturalLanguageUsageId);
243         List<NaturalLanguageTemplateBo> bos = findMatching(dataObjectService, NaturalLanguageTemplateBo.class, map);
244 
245         return convertBosToImmutables(bos);
246     }
247 
248     @Override
249     public List<NaturalLanguageTemplate> findNaturalLanguageTemplatesByType(String typeId) {
250         if (org.apache.commons.lang.StringUtils.isBlank(typeId)) {
251             throw new IllegalArgumentException("typeId is null or blank");
252         }
253 
254         final Map<String, Object> map = new HashMap<String, Object>();
255         map.put("typeId", typeId);
256         List<NaturalLanguageTemplateBo> bos = findMatching(dataObjectService, NaturalLanguageTemplateBo.class, map);
257 
258         return convertBosToImmutables(bos);
259     }
260 
261     @Override
262     public List<NaturalLanguageTemplate> findNaturalLanguageTemplatesByTemplate(String template) {
263         if (org.apache.commons.lang.StringUtils.isBlank(template)) {
264             throw new IllegalArgumentException("template is null or blank");
265         }
266 
267         final Map<String, Object> map = new HashMap<String, Object>();
268         map.put("template", template);
269         List<NaturalLanguageTemplateBo> bos = findMatching(dataObjectService, NaturalLanguageTemplateBo.class, map);
270 
271         return convertBosToImmutables(bos);
272     }
273 
274     public List<NaturalLanguageTemplate> convertBosToImmutables(
275             final Collection<NaturalLanguageTemplateBo> naturalLanguageTemplateBos) {
276         List<NaturalLanguageTemplate> immutables = new LinkedList<NaturalLanguageTemplate>();
277 
278         if (naturalLanguageTemplateBos != null) {
279             NaturalLanguageTemplate immutable = null;
280             for (NaturalLanguageTemplateBo bo : naturalLanguageTemplateBos) {
281                 immutable = to(bo);
282                 immutables.add(immutable);
283             }
284         }
285 
286         return Collections.unmodifiableList(immutables);
287     }
288 
289     @Override
290     public NaturalLanguageTemplate to(NaturalLanguageTemplateBo naturalLanguageTemplateBo) {
291         return NaturalLanguageTemplateBo.to(naturalLanguageTemplateBo);
292     }
293 
294     public NaturalLanguageTemplateBo from(NaturalLanguageTemplate naturalLanguageTemplate) {
295         return NaturalLanguageTemplateBo.from(naturalLanguageTemplate);
296     }
297 
298     private Collection<NaturalLanguageTemplateAttributeBo> buildAttributes(NaturalLanguageTemplate im,
299             Collection<NaturalLanguageTemplateAttributeBo> attributes) {
300         // build a map from attribute name to definition
301         Map<String, KrmsAttributeDefinition> attributeDefinitionMap = new HashMap<String, KrmsAttributeDefinition>();
302 
303         List<KrmsAttributeDefinition> attributeDefinitions =
304                 getAttributeDefinitionService().findAttributeDefinitionsByType(im.getTypeId());
305 
306         for (KrmsAttributeDefinition attributeDefinition : attributeDefinitions) {
307             attributeDefinitionMap.put(attributeDefinition.getName(), attributeDefinition);
308         }
309 
310         // for each entry, build a NaturalLanguageTemplateAttributeBo and add it
311         if (im.getAttributes() != null) {
312             for (Map.Entry<String, String> entry : im.getAttributes().entrySet()) {
313                 KrmsAttributeDefinition attrDef = attributeDefinitionMap.get(entry.getKey());
314 
315                 if (attrDef != null) {
316                     NaturalLanguageTemplateAttributeBo attributeBo = new NaturalLanguageTemplateAttributeBo();
317                     attributeBo.setNaturalLanguageTemplateId(im.getId());
318                     attributeBo.setAttributeDefinitionId(attrDef.getId());
319                     attributeBo.setValue(entry.getValue());
320                     attributeBo.setAttributeDefinition(KrmsAttributeDefinitionBo.from(attrDef));
321                     attributes.add(attributeBo);
322                 } else {
323                     throw new RiceIllegalStateException("there is no attribute definition with the name '" +
324                             entry.getKey() + "' that is valid for the naturalLanguageTemplate type with id = '" + im
325                             .getTypeId() + "'");
326                 }
327             }
328         }
329 
330         return attributes;
331     }
332 
333     private Set<NaturalLanguageTemplateAttributeBo> buildAttributeBoSet(NaturalLanguageTemplate im) {
334         Set<NaturalLanguageTemplateAttributeBo> attributes = new HashSet<NaturalLanguageTemplateAttributeBo>();
335 
336         return (Set) buildAttributes(im, attributes);
337     }
338 
339     private List<NaturalLanguageTemplateAttributeBo> buildAttributeBoList(NaturalLanguageTemplate im) {
340         List<NaturalLanguageTemplateAttributeBo> attributes = new LinkedList<NaturalLanguageTemplateAttributeBo>();
341 
342         return (List) buildAttributes(im, attributes);
343     }
344 
345     private void incomingParamCheck(Object object, String name) {
346         if (object == null) {
347             throw new IllegalArgumentException(name + " was null");
348         } else if (object instanceof String && StringUtils.isBlank((String) object)) {
349             throw new IllegalArgumentException(name + " was blank");
350         }
351     }
352 }