View Javadoc
1   /**
2    * Copyright 2005-2015 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.proposition.PropositionDefinition;
20  import org.kuali.rice.krms.framework.engine.Proposition;
21  import org.kuali.rice.krms.framework.engine.PropositionResult;
22  import org.kuali.rice.krms.framework.type.PropositionTypeService;
23  import org.kuali.rice.krms.impl.type.KrmsTypeResolver;
24  
25  import java.util.Collections;
26  import java.util.List;
27  
28  /**
29   * TODO... 
30   * 
31   * @author Kuali Rice Team (rice.collab@kuali.org)
32   *
33   */
34  final class LazyProposition implements Proposition {
35  
36  	private final PropositionDefinition propositionDefinition;
37  	private final KrmsTypeResolver resolver;
38  	
39  	private final Object mutex = new Object();
40  	
41  	// volatile for double-checked locking idiom
42  	private volatile Proposition proposition;
43  	
44  	LazyProposition(PropositionDefinition propositionDefinition, KrmsTypeResolver resolver) {
45  		this.propositionDefinition = propositionDefinition;
46  		this.resolver = resolver;
47  		this.proposition = null;
48  	}
49  	
50  	@Override
51  	public PropositionResult evaluate(ExecutionEnvironment environment) {
52  		return getProposition().evaluate(environment);
53  	}
54  	
55  	/**
56  	 * Gets the proposition using a lazy double-checked locking mechanism as documented in Effective Java Item 71.
57  	 */
58  	private Proposition getProposition() {
59  		Proposition localProposition = proposition;
60  		if (localProposition == null) {
61  			synchronized (mutex) {
62  				localProposition = proposition;
63  				if (localProposition == null) {
64  					proposition = localProposition = constructProposition();
65  				}
66  			}
67  		}
68  		return localProposition;
69  	}
70  	
71  	private Proposition constructProposition() {
72          Proposition proposition = null;
73          if (propositionDefinition != null) {
74  		    PropositionTypeService propositionTypeService = resolver.getPropositionTypeService(propositionDefinition);
75  		    proposition = propositionTypeService.loadProposition(propositionDefinition);
76          }
77  		if (proposition == null) {
78  			proposition = new Proposition() {
79  				@Override
80  				public PropositionResult evaluate(ExecutionEnvironment environment) {
81  					return new PropositionResult(true);
82  				}
83  
84  			    @Override
85  			    public List<Proposition> getChildren() {
86  			        return Collections.emptyList();
87  			    }
88  			    
89  			    @Override
90  			    public boolean isCompound() {
91  			        return false;
92  			    }
93  			};
94  		}
95  		return proposition;
96  	}
97  
98  	@Override
99  	public List<Proposition> getChildren() {
100 	    return getProposition().getChildren();
101 	}
102 	
103 	@Override
104 	public boolean isCompound() {
105 	    return getProposition().isCompound();
106 	}
107 }