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.collections.CollectionUtils;
026import org.apache.commons.lang.StringUtils;
027import org.kuali.rice.core.api.criteria.CriteriaLookupService;
028import org.kuali.rice.core.api.criteria.GenericQueryResults;
029import org.kuali.rice.core.api.criteria.Predicate;
030import org.kuali.rice.core.api.criteria.QueryByCriteria;
031import org.kuali.rice.krad.service.BusinessObjectService;
032import org.kuali.rice.krad.service.KRADServiceLocator;
033import org.kuali.rice.krms.api.repository.type.KrmsAttributeDefinition;
034import org.kuali.rice.krms.impl.util.KrmsImplConstants;
035
036import static org.kuali.rice.core.api.criteria.PredicateFactory.*;
037
038public final class KrmsAttributeDefinitionServiceImpl implements KrmsAttributeDefinitionService {
039
040    private BusinessObjectService businessObjectService;
041    private CriteriaLookupService criteriaLookupService;
042
043        @Override
044        /**
045        * @see org.kuali.rice.krms.impl.repository.KrmsAttributeDefinitionService#convertAttributeKeys()
046        */
047        public Map<String,String> convertAttributeKeys(Map<String,String> attributesByName, String namespace) {
048                Map<String,String> attributesById = new HashMap<String,String>();
049                if(attributesByName != null) {
050                        for(Map.Entry<String, String> attr : attributesByName.entrySet()) {
051                                String newKey = getKrmsAttributeId(attr.getKey(), namespace);
052                                if(StringUtils.isNotEmpty(newKey)) {
053                                        attributesById.put(newKey, attr.getValue());
054                                }
055                        }
056                }
057                return attributesById;
058        }
059   
060        @Override
061        /**
062        * @see org.kuali.rice.krms.impl.repository.KrmsAttributeDefinitionService#getKrmsAttributeId()
063        */
064        public String getKrmsAttributeId( String attributeName, String namespace) {
065                String returnId = null;
066                KrmsAttributeDefinitionBo bo = getKrmsAttributeBo(attributeName, namespace);
067                if (bo != null){
068                        returnId = bo.getId();
069                }
070                return returnId;
071        }
072    
073        @Override
074        /**
075        * @see org.kuali.rice.krms.impl.repository.KrmsAttributeDefinitionService#getKrmsAttributeBo()
076        */
077        public KrmsAttributeDefinitionBo getKrmsAttributeBo( String attributeName, String namespace) {
078                KrmsAttributeDefinitionBo result = null;
079                Map<String,Object> criteria = new HashMap<String,Object>( 3 );
080                criteria.put( "name", attributeName );
081                criteria.put( "namespace", namespace );
082        criteria.put( "active", Boolean.TRUE );
083                Collection<KrmsAttributeDefinitionBo> defs = getBusinessObjectService().findMatching( KrmsAttributeDefinitionBo.class, criteria );
084                if(CollectionUtils.isNotEmpty(defs)) {
085                        if (defs.size() > 1){
086                                throw new IllegalStateException("Multiple KrmsAttributeDefinitions found with same name and namespace");
087                        }
088                        result = defs.iterator().next();
089                }
090                return result;
091        }
092    
093        @Override
094        /**
095        * @see org.kuali.rice.krms.impl.repository.KrmsAttributeDefinitionService#createAttributeDefinition()
096        */
097        public KrmsAttributeDefinition createAttributeDefinition(KrmsAttributeDefinition attributeDefinition) {
098                if (attributeDefinition == null){
099                throw new IllegalArgumentException("attributeDefinition is null");
100                }
101                final String nameKey = attributeDefinition.getName();
102                final String namespaceKey = attributeDefinition.getNamespace();
103                final KrmsAttributeDefinition existing = getAttributeDefinitionByNameAndNamespace(nameKey, namespaceKey);
104                if (existing != null && existing.getName().equals(nameKey) && existing.getNamespace().equals(namespaceKey)){
105            throw new IllegalStateException("the krms attribute definition to create already exists: " + attributeDefinition);                  
106                }
107                
108                KrmsAttributeDefinitionBo bo = KrmsAttributeDefinitionBo.from(attributeDefinition);
109                getBusinessObjectService().save(bo);
110                return KrmsAttributeDefinitionBo.to(bo);
111        }
112
113        @Override
114        /**
115        * @see org.kuali.rice.krms.impl.repository.KrmsAttributeDefinitionService#updateAttributeDefinition()
116        */
117        public void updateAttributeDefinition(KrmsAttributeDefinition attributeDefinition) {
118                if (attributeDefinition == null){
119                throw new IllegalArgumentException("attributeDefinition is null");
120                }
121                final String idKey = attributeDefinition.getId();
122                final KrmsAttributeDefinitionBo existing = getBusinessObjectService().findBySinglePrimaryKey(KrmsAttributeDefinitionBo.class, idKey);
123                if (existing == null){
124            throw new IllegalStateException("the krms attribute definition does not exist: " + attributeDefinition);                    
125                }
126                final KrmsAttributeDefinition toUpdate;
127                if (!existing.getId().equals(attributeDefinition.getId())){
128                        final KrmsAttributeDefinition.Builder builder = KrmsAttributeDefinition.Builder.create(attributeDefinition);
129                        builder.setId(existing.getId());
130                        toUpdate = builder.build();
131                } else {
132                        toUpdate = attributeDefinition;
133                }
134                KrmsAttributeDefinitionBo bo = KrmsAttributeDefinitionBo.from(toUpdate);
135                getBusinessObjectService().save(bo);
136        }
137
138        @Override
139        /**
140        * @see org.kuali.rice.krms.impl.repository.KrmsAttributeDefinitionService#getAttributeDefinitionById()
141        */
142    public KrmsAttributeDefinition getAttributeDefinitionById(final String id) {
143        if (StringUtils.isBlank(id)) {
144            throw new IllegalArgumentException("id is blank");
145        }
146        KrmsAttributeDefinitionBo bo = getBusinessObjectService().findBySinglePrimaryKey(KrmsAttributeDefinitionBo.class, id);
147        return KrmsAttributeDefinitionBo.to(bo);
148    }
149
150    @Override
151        /**
152        * @see org.kuali.rice.krms.impl.repository.KrmsAttributeDefinitionService#getAttributeDefinitionByNameAndNamespace()
153        */
154    public KrmsAttributeDefinition getAttributeDefinitionByNameAndNamespace(final String name, final String namespace) {
155        if (StringUtils.isBlank(name)) {
156            throw new IllegalArgumentException("name is blank");
157        }
158        if (StringUtils.isBlank(namespace)) {
159            throw new IllegalArgumentException("namespace is blank");
160        }
161        KrmsAttributeDefinitionBo bo = getKrmsAttributeBo(name, namespace);
162        if (bo == null) 
163                return null;
164        return KrmsAttributeDefinitionBo.to(bo);
165    }
166
167    @Override
168        /**
169        * @see org.kuali.rice.krms.impl.repository.KrmsAttributeDefinitionService#findAttributeDefinitionsByNamespace()
170        */
171    public List<KrmsAttributeDefinition> findAttributeDefinitionsByNamespace(final String namespace) {
172        final Map<String, Object> map = new HashMap<String, Object>();
173        map.put("namespace", namespace);
174        map.put("active", Boolean.TRUE);
175        Collection<KrmsAttributeDefinitionBo> krmsAttributeDefinitionBos = getBusinessObjectService().findMatching(KrmsAttributeDefinitionBo.class, Collections.unmodifiableMap(map));
176        return convertListOfBosToImmutables(krmsAttributeDefinitionBos);
177    }
178
179    @Override
180        /**
181        * @see org.kuali.rice.krms.impl.repository.KrmsAttributeDefinitionService#findAttributeDefinitionsByType()
182        */
183    public List<KrmsAttributeDefinition> findAttributeDefinitionsByType(final String typeId) {
184
185        List<KrmsAttributeDefinition> results = Collections.emptyList();
186
187        final Map<String, Object> map = new HashMap<String, Object>();
188        map.put("typeId", typeId);
189        map.put("active", Boolean.TRUE);
190        Collection<KrmsTypeAttributeBo> krmsTypeAttributeBos = getBusinessObjectService().findMatching(KrmsTypeAttributeBo.class, Collections.unmodifiableMap(map));
191
192        if (!CollectionUtils.isEmpty(krmsTypeAttributeBos)) {
193            String [] inList = new String[krmsTypeAttributeBos.size()];
194            int inListIdex = 0;
195            for (KrmsTypeAttributeBo krmsTypeAttributeBo : krmsTypeAttributeBos) {
196                inList[inListIdex] = krmsTypeAttributeBo.getAttributeDefinitionId();
197                ++inListIdex; // don't forget to increment our index
198            }
199
200            QueryByCriteria.Builder qBuilder = QueryByCriteria.Builder.create();
201            qBuilder.setPredicates(in("id", inList));
202            results = convertListOfBosToImmutables(getCriteriaLookupService().lookup(KrmsAttributeDefinitionBo.class, qBuilder.build()).getResults());
203        }
204
205        return results;
206    }
207
208
209    @Override
210        /**
211        * @see org.kuali.rice.krms.impl.repository.KrmsAttributeDefinitionService#findAllAttributeDefinitions()
212        */
213    public List<KrmsAttributeDefinition> findAllAttributeDefinitions() {
214        final Map<String, Object> map = new HashMap<String, Object>();
215        map.put("active", Boolean.TRUE);
216        
217        Collection<KrmsAttributeDefinitionBo> krmsAttributeDefinitionBos = getBusinessObjectService().findMatching(KrmsAttributeDefinitionBo.class, Collections.unmodifiableMap(map));
218        return convertListOfBosToImmutables(krmsAttributeDefinitionBos);
219    }
220
221    /**
222     * Sets the businessObjectService attribute value.
223     *
224     * @param businessObjectService The businessObjectService to set.
225     */
226    public void setBusinessObjectService(final BusinessObjectService businessObjectService) {
227        this.businessObjectService = businessObjectService;
228    }
229
230    /**
231     * This method returns a reference to the businessObjectService.
232     * If the businessObjectService is not set, get it from the KRADServiceLocator.
233     * @return businessObjectService
234     */
235    protected BusinessObjectService getBusinessObjectService() {
236                if ( businessObjectService == null ) {
237                        businessObjectService = KRADServiceLocator.getBusinessObjectService();
238                }
239                return businessObjectService;
240        }
241
242    /**
243     * Converts a List<KrmsAttributeDefinitionBo> to an Unmodifiable List<KrmsAttributeDefinition>
244     *
245     * @param krmsAttributeDefinitionBos a mutable List<KrmsAttributeDefinitionBo> to made completely immutable.
246     * @return An unmodifiable List<KrmsAttributeDefinition>
247     */
248    public List<KrmsAttributeDefinition> convertListOfBosToImmutables(final Collection<KrmsAttributeDefinitionBo> krmsAttributeDefinitionBos) {
249        ArrayList<KrmsAttributeDefinition> krmsAttributeDefinitions = new ArrayList<KrmsAttributeDefinition>();
250        for (KrmsAttributeDefinitionBo bo : krmsAttributeDefinitionBos) {
251            KrmsAttributeDefinition krmsAttributeDefinition = KrmsAttributeDefinitionBo.to(bo);
252            krmsAttributeDefinitions.add(krmsAttributeDefinition);
253        }
254        return Collections.unmodifiableList(krmsAttributeDefinitions);
255    }
256
257        /**
258     * Sets the criteriaLookupService attribute value.
259     *
260     * @param criteriaLookupService The criteriaLookupService to set.
261     */
262    public void setCriteriaLookupService(final CriteriaLookupService criteriaLookupService) {
263        this.criteriaLookupService = criteriaLookupService;
264    }
265
266    protected CriteriaLookupService getCriteriaLookupService() {
267        return criteriaLookupService;
268    }
269
270}