001/**
002 * Copyright 2005-2017 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.core.api.mo.common.Versioned;
021import org.kuali.rice.krad.data.jpa.PortableSequenceGenerator;
022import org.kuali.rice.krad.data.jpa.converters.BooleanYNConverter;
023import org.kuali.rice.krms.api.repository.language.NaturalLanguageTemplate;
024import org.kuali.rice.krms.api.repository.language.NaturalLanguageTemplateContract;
025import org.kuali.rice.krms.api.repository.type.KrmsAttributeDefinition;
026import org.kuali.rice.krms.api.repository.type.KrmsTypeDefinition;
027import org.kuali.rice.krms.api.repository.type.KrmsTypeRepositoryService;
028
029import javax.persistence.CascadeType;
030import javax.persistence.Column;
031import javax.persistence.Convert;
032import javax.persistence.Entity;
033import javax.persistence.GeneratedValue;
034import javax.persistence.Id;
035import javax.persistence.JoinColumn;
036import javax.persistence.OneToMany;
037import javax.persistence.Table;
038import javax.persistence.Transient;
039import javax.persistence.Version;
040import java.io.Serializable;
041import java.util.Collection;
042import java.util.Collections;
043import java.util.HashMap;
044import java.util.HashSet;
045import java.util.LinkedList;
046import java.util.List;
047import java.util.Map;
048import java.util.Set;
049
050/**
051 * The mutable implementation of the @{link NaturalLanguageTemplateContract} interface, the counterpart to the immutable implementation {@link NaturalLanguageTemplate}.
052 * @author Kuali Rice Team (rice.collab@kuali.org)
053 * 
054 */
055@Entity
056@Table(name = "KRMS_NL_TMPL_T")
057public class NaturalLanguageTemplateBo implements NaturalLanguageTemplateContract, Versioned, Serializable {
058
059    private static final long serialVersionUID = 1l;
060
061    @Transient
062    private Map<String, String> attributes;
063
064    @Column(name = "LANG_CD")
065    private String languageCode;
066
067    @Column(name = "NL_USAGE_ID")
068    private String naturalLanguageUsageId;
069
070    @Column(name = "TYP_ID")
071    private String typeId;
072
073    @Column(name = "TMPL")
074    private String template;
075
076    @PortableSequenceGenerator(name = "KRMS_NL_TMPL_S")
077    @GeneratedValue(generator = "KRMS_NL_TMPL_S")
078    @Id
079    @Column(name = "NL_TMPL_ID")
080    private String id;
081
082    @Column(name = "ACTV")
083    @Convert(converter = BooleanYNConverter.class)
084    private boolean active = true;
085
086    @Column(name = "VER_NBR")
087    @Version
088    private Long versionNumber;
089
090    @OneToMany(targetEntity = NaturalLanguageTemplateAttributeBo.class, orphanRemoval = true, cascade = { CascadeType.REFRESH, CascadeType.REMOVE, CascadeType.PERSIST })
091    @JoinColumn(name = "NL_TMPL_ID", referencedColumnName = "NL_TMPL_ID", insertable = false, updatable = false)
092    private Set<NaturalLanguageTemplateAttributeBo> attributeBos;
093
094    private static KrmsAttributeDefinitionService attributeDefinitionService;
095
096    private static KrmsTypeRepositoryService typeRepositoryService;
097
098    /**
099     * Default Constructor
100     * 
101     */
102    public NaturalLanguageTemplateBo() {
103    }
104
105    @Override
106    public String getLanguageCode() {
107        return this.languageCode;
108    }
109
110    @Override
111    public String getNaturalLanguageUsageId() {
112        return this.naturalLanguageUsageId;
113    }
114
115    @Override
116    public String getTypeId() {
117        return this.typeId;
118    }
119
120    @Override
121    public String getTemplate() {
122        return this.template;
123    }
124
125    @Override
126    public String getId() {
127        return this.id;
128    }
129
130    @Override
131    public boolean isActive() {
132        return this.active;
133    }
134
135    @Override
136    public Long getVersionNumber() {
137        return this.versionNumber;
138    }
139
140    /**
141     * Sets the value of languageCode on this builder to the given value.
142     * 
143     * @param languageCode the languageCode value to set.
144     * 
145     */
146    public void setLanguageCode(String languageCode) {
147        this.languageCode = languageCode;
148    }
149
150    /**
151     * Sets the value of naturalLanguageUsageId on this builder to the given value.
152     * 
153     * @param naturalLanguageUsageId the naturalLanguageUsageId value to set.
154     * 
155     */
156    public void setNaturalLanguageUsageId(String naturalLanguageUsageId) {
157        this.naturalLanguageUsageId = naturalLanguageUsageId;
158    }
159
160    /**
161     * Sets the value of typeId on this builder to the given value.
162     * 
163     * @param typeId the typeId value to set.
164     * 
165     */
166    public void setTypeId(String typeId) {
167        this.typeId = typeId;
168    }
169
170    /**
171     * Sets the value of template on this builder to the given value.
172     * 
173     * @param template the template value to set.
174     * 
175     */
176    public void setTemplate(String template) {
177        this.template = template;
178    }
179
180    /**
181     * Sets the value of id on this builder to the given value.
182     * 
183     * @param id the id value to set.
184     * 
185     */
186    public void setId(String id) {
187        this.id = id;
188    }
189
190    /**
191     * Sets the value of active on this builder to the given value.
192     * 
193     * @param active the active value to set.
194     * 
195     */
196    public void setActive(boolean active) {
197        this.active = active;
198    }
199
200    /**
201     * Sets the value of versionNumber on this builder to the given value.
202     * 
203     * @param versionNumber the versionNumber value to set.
204     * 
205     */
206    public void setVersionNumber(Long versionNumber) {
207        this.versionNumber = versionNumber;
208    }
209
210    /**
211     * Sets the value of AttributeBos on this builder to the given value.
212     * 
213     * @param attributeBos the AttributeBos value to set.
214     * 
215     */
216    public void setAttributeBos(List<NaturalLanguageTemplateAttributeBo> attributeBos) {
217        this.attributeBos = new HashSet<NaturalLanguageTemplateAttributeBo>(attributeBos);
218    }
219
220    /**
221     * Sets the value of AttributeBos on this builder to the given value.
222     * 
223     * @param attributeBos the AttributeBos value to set.
224     * 
225     */
226    public void setAttributeBos(Set<NaturalLanguageTemplateAttributeBo> attributeBos) {
227        this.attributeBos = new HashSet<NaturalLanguageTemplateAttributeBo>(attributeBos);
228    }
229
230    /**
231     * Converts a mutable {@link NaturalLanguageTemplateBo} to its immutable counterpart, {@link NaturalLanguageTemplate}.
232     * @param naturalLanguageTemplateBo the mutable business object.
233     * @return a {@link NaturalLanguageTemplate} the immutable object.
234     * 
235     */
236    public static NaturalLanguageTemplate to(NaturalLanguageTemplateBo naturalLanguageTemplateBo) {
237        if (naturalLanguageTemplateBo == null) {
238            return null;
239        }
240
241        return NaturalLanguageTemplate.Builder.create(naturalLanguageTemplateBo).build();
242    }
243
244    /**
245     * Converts a immutable {@link NaturalLanguageTemplate} to its mutable {@link NaturalLanguageTemplateBo} counterpart.
246     * @param naturalLanguageTemplate the immutable object.
247     * @return a {@link NaturalLanguageTemplateBo} the mutable NaturalLanguageTemplateBo.
248     * 
249     */
250    public static org.kuali.rice.krms.impl.repository.NaturalLanguageTemplateBo from(NaturalLanguageTemplate naturalLanguageTemplate) {
251        if (naturalLanguageTemplate == null) {
252            return null;
253        }
254
255        NaturalLanguageTemplateBo naturalLanguageTemplateBo = new NaturalLanguageTemplateBo();
256        naturalLanguageTemplateBo.setLanguageCode(naturalLanguageTemplate.getLanguageCode());
257        naturalLanguageTemplateBo.setNaturalLanguageUsageId(naturalLanguageTemplate.getNaturalLanguageUsageId());
258        naturalLanguageTemplateBo.setTypeId(naturalLanguageTemplate.getTypeId());
259        naturalLanguageTemplateBo.setTemplate(naturalLanguageTemplate.getTemplate());
260        naturalLanguageTemplateBo.setId(naturalLanguageTemplate.getId());
261        naturalLanguageTemplateBo.setActive(naturalLanguageTemplate.isActive());
262        naturalLanguageTemplateBo.setVersionNumber(naturalLanguageTemplate.getVersionNumber());
263        if (StringUtils.isNotBlank(naturalLanguageTemplate.getId())) {
264           naturalLanguageTemplateBo.setAttributeBos(buildAttributeBoSet(naturalLanguageTemplate));
265        }
266        return naturalLanguageTemplateBo;
267    }
268
269    @Override
270    public Map<String, String> getAttributes() {
271        if (attributeBos == null) {
272            return Collections.emptyMap();
273        }
274
275        HashMap<String, String> attributes = new HashMap<String, String>(attributeBos.size());
276
277        for (NaturalLanguageTemplateAttributeBo attr : attributeBos) {
278            attributes.put(attr.getAttributeDefinition().getName(), attr.getValue());
279        }
280
281        return attributes;
282    }
283
284    /**
285     * TODO
286     * 
287     */
288    public void setAttributes(Map<String, String> attributes) {
289        this.attributeBos = new HashSet<NaturalLanguageTemplateAttributeBo>();
290
291        if (!org.apache.commons.lang.StringUtils.isBlank(this.typeId)) {
292            List<KrmsAttributeDefinition> attributeDefinitions = KrmsRepositoryServiceLocator.getKrmsAttributeDefinitionService().findAttributeDefinitionsByType(this.getTypeId());
293            Map<String, KrmsAttributeDefinition> attributeDefinitionsByName = new HashMap<String, KrmsAttributeDefinition>(attributeDefinitions.size());
294
295            if (attributeDefinitions != null) for (KrmsAttributeDefinition attributeDefinition : attributeDefinitions) {
296                attributeDefinitionsByName.put(attributeDefinition.getName(), attributeDefinition);
297            }
298
299            for (Map.Entry<String, String> attr : attributes.entrySet()) {
300                KrmsAttributeDefinition attributeDefinition = attributeDefinitionsByName.get(attr.getKey());
301                NaturalLanguageTemplateAttributeBo attributeBo = new NaturalLanguageTemplateAttributeBo();
302                attributeBo.setNaturalLanguageTemplateId(this.getId());
303                attributeBo.setAttributeDefinitionId((attributeDefinition == null) ? null : attributeDefinition.getId());
304                attributeBo.setValue(attr.getValue());
305                attributeBo.setAttributeDefinition(KrmsAttributeDefinitionBo.from(attributeDefinition));
306                attributeBos.add(attributeBo);
307            }
308        }
309    }
310
311    private static Collection<NaturalLanguageTemplateAttributeBo> buildAttributes(NaturalLanguageTemplate im, Collection<NaturalLanguageTemplateAttributeBo> attributes) {
312        KrmsTypeDefinition krmsTypeDefinition = getTypeRepositoryService().getTypeById(im.getTypeId());
313
314        // for each entry, build a NaturalLanguageTemplateAttributeBo and add it 
315        if (im.getAttributes() != null) {
316            for (Map.Entry<String, String> entry : im.getAttributes().entrySet()) {
317                KrmsAttributeDefinition attrDef = getAttributeDefinitionService().getAttributeDefinitionByNameAndNamespace(entry.getKey(), krmsTypeDefinition.getNamespace());
318
319                if (attrDef != null) {
320                    NaturalLanguageTemplateAttributeBo attributeBo = new NaturalLanguageTemplateAttributeBo();
321                    attributeBo.setNaturalLanguageTemplateId(im.getId());
322                    attributeBo.setAttributeDefinitionId(attrDef.getId());
323                    attributeBo.setValue(entry.getValue());
324                    attributeBo.setAttributeDefinition(KrmsAttributeDefinitionBo.from(attrDef));
325                    attributes.add(attributeBo);
326                } else {
327                    throw new RiceIllegalStateException("there is no attribute definition with the name '" + entry.getKey() + "' that is valid for the naturalLanguageTemplate type with id = '" + im.getTypeId() + "'");
328                }
329            }
330        }
331
332        return attributes;
333    }
334
335    private static Set<NaturalLanguageTemplateAttributeBo> buildAttributeBoSet(NaturalLanguageTemplate im) {
336        Set<NaturalLanguageTemplateAttributeBo> attributes = new HashSet<NaturalLanguageTemplateAttributeBo>();
337
338        return (Set) buildAttributes(im, attributes);
339    }
340
341    private static List<NaturalLanguageTemplateAttributeBo> buildAttributeBoList(NaturalLanguageTemplate im) {
342        List<NaturalLanguageTemplateAttributeBo> attributes = new LinkedList<NaturalLanguageTemplateAttributeBo>();
343
344        return (List) buildAttributes(im, attributes);
345    }
346
347    public static void setAttributeDefinitionService(KrmsAttributeDefinitionService attributeDefinitionService) {
348        NaturalLanguageTemplateBo.attributeDefinitionService = attributeDefinitionService;
349    }
350
351    public static KrmsTypeRepositoryService getTypeRepositoryService() {
352        if (typeRepositoryService == null) {
353            typeRepositoryService = KrmsRepositoryServiceLocator.getKrmsTypeRepositoryService();
354        }
355
356        return typeRepositoryService;
357    }
358
359    public static void setTypeRepositoryService(KrmsTypeRepositoryService typeRepositoryService) {
360        NaturalLanguageTemplateBo.typeRepositoryService = typeRepositoryService;
361    }
362
363    public static KrmsAttributeDefinitionService getAttributeDefinitionService() {
364        if (attributeDefinitionService == null) {
365            attributeDefinitionService = KrmsRepositoryServiceLocator.getKrmsAttributeDefinitionService();
366        }
367
368        return attributeDefinitionService;
369    }
370}