View Javadoc

1   /**
2    * Copyright 2005-2013 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  
19  import org.apache.commons.lang.StringUtils;
20  import org.kuali.rice.core.api.exception.RiceIllegalStateException;
21  import org.kuali.rice.krad.service.BusinessObjectService;
22  import org.kuali.rice.krms.api.repository.rule.RuleDefinition;
23  import org.kuali.rice.krms.api.repository.type.KrmsAttributeDefinition;
24  import org.kuali.rice.krms.impl.util.KrmsImplConstants.PropertyNames;
25  
26  import java.util.*;
27  
28  public final class RuleBoServiceImpl implements RuleBoService {
29  
30  	private BusinessObjectService businessObjectService;
31      private KrmsAttributeDefinitionService attributeDefinitionService;
32  
33  	/**
34  	 * This overridden creates a KRMS Rule in the repository
35  	 * 
36  	 * @see org.kuali.rice.krms.impl.repository.RuleBoService#createRule(org.kuali.rice.krms.api.repository.rule.RuleDefinition)
37  	 */
38  	@Override
39  	public RuleDefinition createRule(RuleDefinition rule) {
40  		if (rule == null){
41  			throw new IllegalArgumentException("rule is null");
42  		}
43  		final String nameKey = rule.getName();
44  		final String namespaceKey = rule.getNamespace();
45  		final RuleDefinition existing = getRuleByNameAndNamespace(nameKey, namespaceKey);
46  		if (existing != null){
47  			throw new IllegalStateException("the rule to create already exists: " + rule);			
48  		}	
49  		RuleBo ruleBo = RuleBo.from(rule);
50  		businessObjectService.save(ruleBo);
51  		return RuleBo.to(ruleBo);
52  	}
53  
54  	/**
55  	 * This overridden updates an existing Rule in the Repository
56  	 * 
57  	 * @see org.kuali.rice.krms.impl.repository.RuleBoService#updateRule(org.kuali.rice.krms.api.repository.rule.RuleDefinition)
58  	 */
59  	@Override
60  	public void updateRule(RuleDefinition rule) {
61  		if (rule == null){
62  			throw new IllegalArgumentException("rule is null");
63  		}
64  
65  		// must already exist to be able to update
66  		final String ruleIdKey = rule.getId();
67  		final RuleBo existing = businessObjectService.findBySinglePrimaryKey(RuleBo.class, ruleIdKey);
68  		if (existing == null) {
69  			throw new IllegalStateException("the rule does not exist: " + rule);
70  		}
71  		final RuleDefinition toUpdate;
72  		if (!existing.getId().equals(rule.getId())){
73  			// if passed in id does not match existing id, correct it
74  			final RuleDefinition.Builder builder = RuleDefinition.Builder.create(rule);
75  			builder.setId(existing.getId());
76  			toUpdate = builder.build();
77  		} else {
78  			toUpdate = rule;
79  		}
80  	     
81  		// copy all updateable fields to bo
82  		RuleBo boToUpdate = RuleBo.from(toUpdate);
83  
84  		// delete any old, existing attributes
85  		Map<String,String> fields = new HashMap<String,String>(1);
86  		fields.put(PropertyNames.Rule.RULE_ID, toUpdate.getId());
87  		businessObjectService.deleteMatching(RuleAttributeBo.class, fields);
88          
89  		// update the rule and create new attributes
90  		businessObjectService.save(boToUpdate);
91  	}
92  
93      @Override
94      public void deleteRule(String ruleId) {
95          if (ruleId == null){ throw new IllegalArgumentException("ruleId is null"); }
96          final RuleDefinition existing = getRuleByRuleId(ruleId);
97          if (existing == null){ throw new IllegalStateException("the Rule to delete does not exists: " + ruleId);}
98          businessObjectService.delete(from(existing));
99      }
100 
101 	/**
102 	 * This method retrieves a rule from the repository given the rule id.
103 	 * 
104 	 * @see org.kuali.rice.krms.impl.repository.RuleBoService#getRuleByRuleId(java.lang.String)
105 	 */
106 	@Override
107 	public RuleDefinition getRuleByRuleId(String ruleId) {
108 		if (StringUtils.isBlank(ruleId)){
109 			throw new IllegalArgumentException("rule id is null");
110 		}
111 		RuleBo bo = businessObjectService.findBySinglePrimaryKey(RuleBo.class, ruleId);
112 		return RuleBo.to(bo);
113 	}
114 
115 	/**
116 	 * This method retrieves a rule from the repository given the name of the rule
117 	 * and namespace.
118 	 * 
119 	 * @see org.kuali.rice.krms.impl.repository.RuleBoService#getRuleByRuleId(java.lang.String)
120 	 */
121 	@Override
122 	public RuleDefinition getRuleByNameAndNamespace(String name, String namespace) {
123         if (StringUtils.isBlank(name)) {
124             throw new IllegalArgumentException("name is blank");
125         }
126         if (StringUtils.isBlank(namespace)) {
127             throw new IllegalArgumentException("namespace is blank");
128         }
129 
130         final Map<String, Object> map = new HashMap<String, Object>();
131         map.put("name", name);
132         map.put("namespace", namespace);
133 
134         RuleBo myRule = businessObjectService.findByPrimaryKey(RuleBo.class, Collections.unmodifiableMap(map));
135 		return RuleBo.to(myRule);
136 	}
137 
138 //	/**
139 //	 * This overridden method ...
140 //	 * 
141 //	 * @see org.kuali.rice.krms.impl.repository.RuleBoService#createRuleAttribute(org.kuali.rice.krms.api.repository.rule.RuleAttribute)
142 //	 */
143 //	@Override
144 //	public void createRuleAttribute(RuleAttribute attribute) {
145 //		if (attribute == null){
146 //			throw new IllegalArgumentException("rule attribute is null");
147 //		}
148 //		final String attrIdKey = attribute.getId();
149 //		final RuleAttribute existing = getRuleAttributeById(attrIdKey);
150 //		if (existing != null){
151 //			throw new IllegalStateException("the rule attribute to create already exists: " + attribute);			
152 //		}
153 //
154 //		businessObjectService.save(RuleAttributeBo.from(attribute));		
155 //	}
156 //
157 //	/**
158 //	 * This overridden method ...
159 //	 * 
160 //	 * @see org.kuali.rice.krms.impl.repository.RuleBoService#updateRuleAttribute(org.kuali.rice.krms.api.repository.rule.RuleAttribute)
161 //	 */
162 //	@Override
163 //	public void updateRuleAttribute(RuleAttribute attribute) {
164 //		if (attribute == null){
165 //			throw new IllegalArgumentException("rule attribute is null");
166 //		}
167 //		final String attrIdKey = attribute.getId();
168 //		final RuleAttribute existing = getRuleAttributeById(attrIdKey);
169 //		if (existing == null) {
170 //			throw new IllegalStateException("the rule attribute does not exist: " + attribute);
171 //		}
172 //		final RuleAttribute toUpdate;
173 //		if (!existing.getId().equals(attribute.getRuleId())){
174 //			final RuleAttribute.Builder builder = RuleAttribute.Builder.create(attribute);
175 //			builder.setId(existing.getId());
176 //			toUpdate = builder.build();
177 //		} else {
178 //			toUpdate = attribute;
179 //		}
180 //
181 //		businessObjectService.save(RuleAttributeBo.from(toUpdate));
182 //	}
183 //
184 	/**
185 	 * This method ...
186 	 * 
187 	 * @see org.kuali.rice.krms.impl.repository.RuleBoService#getRuleAttributeById(java.lang.String)
188 	 */
189 	public RuleAttributeBo getRuleAttributeById(String attrId) {
190 		if (StringUtils.isBlank(attrId)){
191 			return null;			
192 		}
193 		RuleAttributeBo bo = businessObjectService.findBySinglePrimaryKey(RuleAttributeBo.class, attrId);
194 		return bo;
195 	}
196 
197     /**
198      * Converts a immutable {@link RuleDefinition} to its mutable {@link RuleBo} counterpart.
199      * @param rule the immutable object.
200      * @return a {@link RuleBo} the mutable RuleBo.
201      *
202      */
203     public RuleBo from(RuleDefinition rule) {
204         if (rule == null) { return null; }
205         RuleBo ruleBo = new RuleBo();
206         ruleBo.setName(rule.getName());
207         ruleBo.setDescription(rule.getDescription());
208         ruleBo.setNamespace(rule.getNamespace());
209         ruleBo.setTypeId(rule.getTypeId());
210         ruleBo.setPropId(rule.getPropId());
211         ruleBo.setProposition(PropositionBo.from(rule.getProposition()));
212         ruleBo.setId(rule.getId());
213         ruleBo.setActive(rule.isActive());
214         ruleBo.setVersionNumber(rule.getVersionNumber());
215         // TODO collections, etc.
216 //        Set<RuleAttributeBo> attributes = buildAttributeBo(rule);
217         ruleBo.setAttributeBos(buildAttributeBoList(rule));
218         return ruleBo;
219     }
220 
221     private Set<RuleAttributeBo> buildAttributeBo(RuleDefinition im) {
222         Set<RuleAttributeBo> attributes = new HashSet<RuleAttributeBo>();
223 
224         // build a map from attribute name to definition
225         Map<String, KrmsAttributeDefinition> attributeDefinitionMap = new HashMap<String, KrmsAttributeDefinition>();
226 
227         List<KrmsAttributeDefinition> attributeDefinitions = getAttributeDefinitionService().findAttributeDefinitionsByType(im.getTypeId());
228 
229         for (KrmsAttributeDefinition attributeDefinition : attributeDefinitions) {
230             attributeDefinitionMap.put(attributeDefinition.getName(), attributeDefinition);
231         }
232 
233         // for each entry, build a RuleAttributeBo and add it to the set
234         if (im.getAttributes() != null) {
235             for (Map.Entry<String,String> entry  : im.getAttributes().entrySet()) {
236                 KrmsAttributeDefinition attrDef = attributeDefinitionMap.get(entry.getKey());
237 
238                 if (attrDef != null) {
239                     RuleAttributeBo attributeBo = new RuleAttributeBo();
240                     attributeBo.setRuleId( im.getId() );
241                     attributeBo.setAttributeDefinitionId(attrDef.getId());
242                     attributeBo.setValue(entry.getValue());
243                     attributeBo.setAttributeDefinition(KrmsAttributeDefinitionBo.from(attrDef));
244                     attributes.add( attributeBo );
245                 } else {
246                     throw new RiceIllegalStateException("there is no attribute definition with the name '" +
247                             entry.getKey() + "' that is valid for the rule type with id = '" + im.getTypeId() +"'");
248                 }
249             }
250         }
251         return attributes;
252     }
253 
254     private List<RuleAttributeBo> buildAttributeBoList(RuleDefinition im) {
255         List<RuleAttributeBo> attributes = new LinkedList<RuleAttributeBo>();
256 
257         // build a map from attribute name to definition
258         Map<String, KrmsAttributeDefinition> attributeDefinitionMap = new HashMap<String, KrmsAttributeDefinition>();
259 
260         List<KrmsAttributeDefinition> attributeDefinitions = getAttributeDefinitionService().findAttributeDefinitionsByType(im.getTypeId());
261 
262         for (KrmsAttributeDefinition attributeDefinition : attributeDefinitions) {
263             attributeDefinitionMap.put(attributeDefinition.getName(), attributeDefinition);
264         }
265 
266         // for each entry, build a RuleAttributeBo and add it to the set
267         if (im.getAttributes() != null) {
268             for (Map.Entry<String,String> entry  : im.getAttributes().entrySet()) {
269                 KrmsAttributeDefinition attrDef = attributeDefinitionMap.get(entry.getKey());
270 
271                 if (attrDef != null) {
272                     RuleAttributeBo attributeBo = new RuleAttributeBo();
273                     attributeBo.setRuleId( im.getId() );
274                     attributeBo.setAttributeDefinitionId(attrDef.getId());
275                     attributeBo.setValue(entry.getValue());
276                     attributeBo.setAttributeDefinition(KrmsAttributeDefinitionBo.from(attrDef));
277                     attributes.add( attributeBo );
278                 } else {
279                     throw new RiceIllegalStateException("there is no attribute definition with the name '" +
280                             entry.getKey() + "' that is valid for the rule type with id = '" + im.getTypeId() +"'");
281                 }
282             }
283         }
284         return attributes;
285     }
286     /**
287 	 * Sets the businessObjectService attribute value.
288 	 *
289 	 * @param businessObjectService The businessObjectService to set.
290 	 */
291 	public void setBusinessObjectService(final BusinessObjectService businessObjectService) {
292 		this.businessObjectService = businessObjectService;
293 	}
294 
295 	/**
296 	 * Converts a List<RuleBo> to an Unmodifiable List<Rule>
297 	 *
298 	 * @param ruleBos a mutable List<RuleBo> to made completely immutable.
299 	 * @return An unmodifiable List<Rule>
300 	 */
301 	public List<RuleDefinition> convertListOfBosToImmutables(final Collection<RuleBo> ruleBos) {
302 		ArrayList<RuleDefinition> rules = new ArrayList<RuleDefinition>();
303 		for (RuleBo bo : ruleBos) {
304 			RuleDefinition rule = RuleBo.to(bo);
305 			rules.add(rule);
306 		}
307 		return Collections.unmodifiableList(rules);
308 	}
309 
310 
311     protected KrmsAttributeDefinitionService getAttributeDefinitionService() {
312         if (attributeDefinitionService == null) {
313             attributeDefinitionService = KrmsRepositoryServiceLocator.getKrmsAttributeDefinitionService();
314         }
315         return attributeDefinitionService;
316     }
317 
318 }