View Javadoc

1   /**
2    * Copyright 2005-2011 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.provider.repository;
17  
18  import org.kuali.rice.krms.api.engine.ExecutionEnvironment;
19  import org.kuali.rice.krms.api.repository.rule.RuleDefinition;
20  import org.kuali.rice.krms.framework.engine.Rule;
21  import org.kuali.rice.krms.framework.type.RuleTypeService;
22  import org.kuali.rice.krms.impl.type.KrmsTypeResolver;
23  
24  /**
25   * TODO... 
26   * 
27   * @author Kuali Rice Team (rice.collab@kuali.org)
28   *
29   */
30  final class LazyRule implements Rule {
31  
32  	private final RuleDefinition ruleDefinition;
33  	private final KrmsTypeResolver typeResolver;
34  	
35  	private final Object mutex = new Object();
36  	
37  	// volatile for double-checked locking idiom
38  	private volatile Rule rule;
39  	
40  	LazyRule(RuleDefinition ruleDefinition, KrmsTypeResolver typeResolver) {
41  		this.ruleDefinition = ruleDefinition;
42  		this.typeResolver = typeResolver;
43  		this.rule = null;
44  	}
45  	
46  	@Override
47  	public boolean evaluate(ExecutionEnvironment environment) {
48  		return getRule().evaluate(environment);
49  	}
50  
51  	/**
52  	 * Gets the rule using a lazy double-checked locking mechanism as documented in Effective Java Item 71.
53  	 */
54  	private Rule getRule() {
55  		Rule localRule = rule;
56  		if (localRule == null) {
57  			synchronized (mutex) {
58  				localRule = rule;
59  				if (localRule == null) {
60  					rule = localRule = constructRule();
61  				}
62  			}
63  		}
64  		return localRule;
65  	}
66  	
67  	private Rule constructRule() {
68  		RuleTypeService ruleTypeService = typeResolver.getRuleTypeService(ruleDefinition);
69  		Rule rule = ruleTypeService.loadRule(ruleDefinition);
70  		if (rule == null) {
71  			rule = new Rule() {
72  				@Override
73  				public boolean evaluate(ExecutionEnvironment environment) {
74                      return false;
75  				}
76  			};
77  		}
78  		return rule;
79  	}
80  
81  	
82  }