View Javadoc

1   /**
2    * Copyright 2005-2012 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 java.util.ArrayList;
19  import java.util.Collection;
20  import java.util.Collections;
21  import java.util.HashMap;
22  import java.util.List;
23  import java.util.Map;
24  
25  import org.apache.commons.collections.CollectionUtils;
26  import org.apache.commons.lang.StringUtils;
27  import org.kuali.rice.core.api.criteria.CriteriaLookupService;
28  import org.kuali.rice.core.api.criteria.GenericQueryResults;
29  import org.kuali.rice.core.api.criteria.Predicate;
30  import org.kuali.rice.core.api.criteria.QueryByCriteria;
31  import org.kuali.rice.krad.service.BusinessObjectService;
32  import org.kuali.rice.krad.service.KRADServiceLocator;
33  import org.kuali.rice.krms.api.repository.type.KrmsAttributeDefinition;
34  import org.kuali.rice.krms.impl.util.KrmsImplConstants;
35  
36  import static org.kuali.rice.core.api.criteria.PredicateFactory.*;
37  
38  public final class KrmsAttributeDefinitionServiceImpl implements KrmsAttributeDefinitionService {
39  
40      private BusinessObjectService businessObjectService;
41      private final Map<String,KrmsAttributeDefinitionBo> krmsAttributeDefinitionIdCache = Collections.synchronizedMap( new HashMap<String,KrmsAttributeDefinitionBo>() );
42  
43      private CriteriaLookupService criteriaLookupService;
44  
45  	@Override
46  	/**
47  	* @see org.kuali.rice.krms.impl.repository.KrmsAttributeDefinitionService#convertAttributeKeys()
48  	*/
49  	public Map<String,String> convertAttributeKeys(Map<String,String> attributesByName, String namespace) {
50  		Map<String,String> attributesById = new HashMap<String,String>();
51  		if(attributesByName != null) {
52  			for(Map.Entry<String, String> attr : attributesByName.entrySet()) {
53  				String newKey = getKrmsAttributeId(attr.getKey(), namespace);
54  				if(StringUtils.isNotEmpty(newKey)) {
55  					attributesById.put(newKey, attr.getValue());
56  				}
57  			}
58  		}
59  		return attributesById;
60  	}
61     
62  	@Override
63  	/**
64  	* @see org.kuali.rice.krms.impl.repository.KrmsAttributeDefinitionService#getKrmsAttributeId()
65  	*/
66  	public String getKrmsAttributeId( String attributeName, String namespace) {
67  		String returnId = null;
68  		KrmsAttributeDefinitionBo bo = getKrmsAttributeBo(attributeName, namespace);
69  		if (bo != null){
70  			returnId = bo.getId();
71  		}
72  		return returnId;
73  	}
74      
75  	@Override
76  	/**
77  	* @see org.kuali.rice.krms.impl.repository.KrmsAttributeDefinitionService#getKrmsAttributeBo()
78  	*/
79  	public KrmsAttributeDefinitionBo getKrmsAttributeBo( String attributeName, String namespace) {
80  		String key = createKey(namespace, attributeName);
81  		if (krmsAttributeDefinitionIdCache.containsKey(key))
82  			return krmsAttributeDefinitionIdCache.get(key);		
83  
84  		KrmsAttributeDefinitionBo result = null;
85  		Map<String,Object> criteria = new HashMap<String,Object>( 3 );
86  		criteria.put( "name", attributeName );
87  		criteria.put( "namespace", namespace );
88          criteria.put( "active", Boolean.TRUE );
89  		Collection<KrmsAttributeDefinitionBo> defs = getBusinessObjectService().findMatching( KrmsAttributeDefinitionBo.class, criteria );
90  		if(CollectionUtils.isNotEmpty(defs)) {
91  			if (defs.size() > 1){
92  				throw new IllegalStateException("Multiple KrmsAttributeDefinitions found with same name and namespace");
93  			}
94  			result = defs.iterator().next();
95  			krmsAttributeDefinitionIdCache.put(key, result);
96  		}
97  		return result;
98  	}
99      
100 	@Override
101 	/**
102 	* @see org.kuali.rice.krms.impl.repository.KrmsAttributeDefinitionService#createAttributeDefinition()
103 	*/
104 	public KrmsAttributeDefinition createAttributeDefinition(KrmsAttributeDefinition attributeDefinition) {
105 		if (attributeDefinition == null){
106 	        throw new IllegalArgumentException("attributeDefinition is null");
107 		}
108 		final String nameKey = attributeDefinition.getName();
109 		final String namespaceKey = attributeDefinition.getNamespace();
110 		final KrmsAttributeDefinition existing = getAttributeDefinitionByNameAndNamespace(nameKey, namespaceKey);
111 		if (existing != null && existing.getName().equals(nameKey) && existing.getNamespace().equals(namespaceKey)){
112             throw new IllegalStateException("the krms attribute definition to create already exists: " + attributeDefinition);			
113 		}
114 		
115 		KrmsAttributeDefinitionBo bo = KrmsAttributeDefinitionBo.from(attributeDefinition);
116 		getBusinessObjectService().save(bo);
117 		updateCache(bo);
118 		return KrmsAttributeDefinitionBo.to(bo);
119 	}
120 
121 	@Override
122 	/**
123 	* @see org.kuali.rice.krms.impl.repository.KrmsAttributeDefinitionService#updateAttributeDefinition()
124 	*/
125 	public void updateAttributeDefinition(KrmsAttributeDefinition attributeDefinition) {
126 		if (attributeDefinition == null){
127 	        throw new IllegalArgumentException("attributeDefinition is null");
128 		}
129 		final String idKey = attributeDefinition.getId();
130 		final KrmsAttributeDefinitionBo existing = getBusinessObjectService().findBySinglePrimaryKey(KrmsAttributeDefinitionBo.class, idKey);
131 		if (existing == null){
132             throw new IllegalStateException("the krms attribute definition does not exist: " + attributeDefinition);			
133 		}
134 		final KrmsAttributeDefinition toUpdate;
135 		if (!existing.getId().equals(attributeDefinition.getId())){
136 			final KrmsAttributeDefinition.Builder builder = KrmsAttributeDefinition.Builder.create(attributeDefinition);
137 			builder.setId(existing.getId());
138 			toUpdate = builder.build();
139 		} else {
140 			toUpdate = attributeDefinition;
141 		}
142 		KrmsAttributeDefinitionBo bo = KrmsAttributeDefinitionBo.from(toUpdate);
143 		getBusinessObjectService().save(bo);
144 		updateCache(bo);
145 	}
146 
147 	@Override
148 	/**
149 	* @see org.kuali.rice.krms.impl.repository.KrmsAttributeDefinitionService#getAttributeDefinitionById()
150 	*/
151     public KrmsAttributeDefinition getAttributeDefinitionById(final String id) {
152         if (StringUtils.isBlank(id)) {
153             throw new IllegalArgumentException("id is blank");
154         }
155 		if (krmsAttributeDefinitionIdCache.containsKey(id)){
156 			return KrmsAttributeDefinitionBo.to(krmsAttributeDefinitionIdCache.get(id));	
157 		} 
158         KrmsAttributeDefinitionBo bo = getBusinessObjectService().findBySinglePrimaryKey(KrmsAttributeDefinitionBo.class, id);
159         return KrmsAttributeDefinitionBo.to(bo);
160     }
161 
162     @Override
163 	/**
164 	* @see org.kuali.rice.krms.impl.repository.KrmsAttributeDefinitionService#getAttributeDefinitionByNameAndNamespace()
165 	*/
166     public KrmsAttributeDefinition getAttributeDefinitionByNameAndNamespace(final String name, final String namespace) {
167         if (StringUtils.isBlank(name)) {
168             throw new IllegalArgumentException("name is blank");
169         }
170         if (StringUtils.isBlank(namespace)) {
171             throw new IllegalArgumentException("namespace is blank");
172         }
173         KrmsAttributeDefinitionBo bo = getKrmsAttributeBo(name, namespace);
174         if (bo == null) 
175         	return null;
176        	return KrmsAttributeDefinitionBo.to(bo);
177     }
178 
179     @Override
180 	/**
181 	* @see org.kuali.rice.krms.impl.repository.KrmsAttributeDefinitionService#findAttributeDefinitionsByNamespace()
182 	*/
183     public List<KrmsAttributeDefinition> findAttributeDefinitionsByNamespace(final String namespace) {
184         final Map<String, Object> map = new HashMap<String, Object>();
185         map.put("namespace", namespace);
186         map.put("active", Boolean.TRUE);
187         Collection<KrmsAttributeDefinitionBo> krmsAttributeDefinitionBos = getBusinessObjectService().findMatching(KrmsAttributeDefinitionBo.class, Collections.unmodifiableMap(map));
188         return convertListOfBosToImmutables(krmsAttributeDefinitionBos);
189     }
190 
191     @Override
192 	/**
193 	* @see org.kuali.rice.krms.impl.repository.KrmsAttributeDefinitionService#findAttributeDefinitionsByType()
194 	*/
195     public List<KrmsAttributeDefinition> findAttributeDefinitionsByType(final String typeId) {
196 
197         List<KrmsAttributeDefinition> results = Collections.emptyList();
198 
199         final Map<String, Object> map = new HashMap<String, Object>();
200         map.put("typeId", typeId);
201         map.put("active", Boolean.TRUE);
202         Collection<KrmsTypeAttributeBo> krmsTypeAttributeBos = getBusinessObjectService().findMatching(KrmsTypeAttributeBo.class, Collections.unmodifiableMap(map));
203 
204         if (!CollectionUtils.isEmpty(krmsTypeAttributeBos)) {
205             String [] inList = new String[krmsTypeAttributeBos.size()];
206             int inListIdex = 0;
207             for (KrmsTypeAttributeBo krmsTypeAttributeBo : krmsTypeAttributeBos) {
208                 inList[inListIdex] = krmsTypeAttributeBo.getAttributeDefinitionId();
209                 ++inListIdex; // don't forget to increment our index
210             }
211 
212             QueryByCriteria.Builder qBuilder = QueryByCriteria.Builder.create();
213             qBuilder.setPredicates(in("id", inList));
214             results = convertListOfBosToImmutables(getCriteriaLookupService().lookup(KrmsAttributeDefinitionBo.class, qBuilder.build()).getResults());
215         }
216 
217         return results;
218     }
219 
220 
221     @Override
222 	/**
223 	* @see org.kuali.rice.krms.impl.repository.KrmsAttributeDefinitionService#findAllAttributeDefinitions()
224 	*/
225     public List<KrmsAttributeDefinition> findAllAttributeDefinitions() {
226         final Map<String, Object> map = new HashMap<String, Object>();
227         map.put("active", Boolean.TRUE);
228         
229         Collection<KrmsAttributeDefinitionBo> krmsAttributeDefinitionBos = getBusinessObjectService().findMatching(KrmsAttributeDefinitionBo.class, Collections.unmodifiableMap(map));
230         return convertListOfBosToImmutables(krmsAttributeDefinitionBos);
231     }
232 
233     /**
234      * Sets the businessObjectService attribute value.
235      *
236      * @param businessObjectService The businessObjectService to set.
237      */
238     public void setBusinessObjectService(final BusinessObjectService businessObjectService) {
239         this.businessObjectService = businessObjectService;
240     }
241 
242     /**
243      * This method returns a reference to the businessObjectService.
244      * If the businessObjectService is not set, get it from the KRADServiceLocator.
245      * @return businessObjectService
246      */
247     protected BusinessObjectService getBusinessObjectService() {
248 		if ( businessObjectService == null ) {
249 			businessObjectService = KRADServiceLocator.getBusinessObjectService();
250 		}
251 		return businessObjectService;
252 	}
253 
254     /**
255      * Converts a List<KrmsAttributeDefinitionBo> to an Unmodifiable List<KrmsAttributeDefinition>
256      *
257      * @param krmsAttributeDefinitionBos a mutable List<KrmsAttributeDefinitionBo> to made completely immutable.
258      * @return An unmodifiable List<KrmsAttributeDefinition>
259      */
260     public List<KrmsAttributeDefinition> convertListOfBosToImmutables(final Collection<KrmsAttributeDefinitionBo> krmsAttributeDefinitionBos) {
261         ArrayList<KrmsAttributeDefinition> krmsAttributeDefinitions = new ArrayList<KrmsAttributeDefinition>();
262         for (KrmsAttributeDefinitionBo bo : krmsAttributeDefinitionBos) {
263             KrmsAttributeDefinition krmsAttributeDefinition = KrmsAttributeDefinitionBo.to(bo);
264             krmsAttributeDefinitions.add(krmsAttributeDefinition);
265         }
266         return Collections.unmodifiableList(krmsAttributeDefinitions);
267     }
268 
269     // Cache related methods
270     
271     public void clearCache(){
272     	krmsAttributeDefinitionIdCache.clear();
273     }
274     
275     private String createKey(String namespace, String name){
276     	String key = namespace + ":" + name;
277     	return key;
278     }
279     
280     private void updateCache(KrmsAttributeDefinitionBo bo){
281 		String key = createKey(bo.getNamespace(), bo.getName());
282 		if (bo.isActive()){
283 			krmsAttributeDefinitionIdCache.put(key, bo);
284 		} else {
285 			krmsAttributeDefinitionIdCache.remove(key);
286 		}
287     }
288 
289         /**
290      * Sets the criteriaLookupService attribute value.
291      *
292      * @param criteriaLookupService The criteriaLookupService to set.
293      */
294     public void setCriteriaLookupService(final CriteriaLookupService criteriaLookupService) {
295         this.criteriaLookupService = criteriaLookupService;
296     }
297 
298     protected CriteriaLookupService getCriteriaLookupService() {
299         return criteriaLookupService;
300     }
301 
302 }