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.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   * A rule which doesn't load it's members until evaluation.
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      /**
41       *
42       * @param ruleDefinition
43       * @param typeResolver
44       */
45  	LazyRule(RuleDefinition ruleDefinition, KrmsTypeResolver typeResolver) {
46  		this.ruleDefinition = ruleDefinition;
47  		this.typeResolver = typeResolver;
48  		this.rule = null;
49  	}
50  	
51  	@Override
52  	public boolean evaluate(ExecutionEnvironment environment) {
53  		return getRule().evaluate(environment);
54  	}
55  
56  	/**
57  	 * Gets the rule using a lazy double-checked locking mechanism as documented in Effective Java Item 71.
58  	 */
59  	private Rule getRule() {
60  		Rule localRule = rule;
61  		if (localRule == null) {
62  			synchronized (mutex) {
63  				localRule = rule;
64  				if (localRule == null) {
65  					rule = localRule = constructRule();
66  				}
67  			}
68  		}
69  		return localRule;
70  	}
71  
72      /**
73       * builder method
74       * @return Rule
75       */
76  	private Rule constructRule() {
77  		RuleTypeService ruleTypeService = typeResolver.getRuleTypeService(ruleDefinition);
78  		Rule rule = ruleTypeService.loadRule(ruleDefinition);
79  		if (rule == null) {
80  			rule = new Rule() {
81  				@Override
82  				public boolean evaluate(ExecutionEnvironment environment) {
83                      return false;
84  				}
85  			};
86  		}
87  		return rule;
88  	}
89  
90  	
91  }