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.action.ActionDefinition;
20  import org.kuali.rice.krms.framework.engine.Action;
21  import org.kuali.rice.krms.framework.type.ActionTypeService;
22  import org.kuali.rice.krms.impl.type.KrmsTypeResolver;
23  
24  /**
25   * An {@link Action} that doesn't load its members until execution.
26   *
27   * @author Kuali Rice Team (rice.collab@kuali.org)
28   *
29   */
30  final class LazyAction implements Action {
31  
32  	private final ActionDefinition actionDefinition;
33  	private final KrmsTypeResolver typeResolver;
34  
35  	private final Object mutex = new Object();
36  	
37  	// volatile for double-checked locking idiom
38  	private volatile Action action;
39  
40      /**
41       *
42       * @param actionDefinition ActionDefinition
43       * @param typeResolver KrmsTypeResolver
44       */
45  	LazyAction(ActionDefinition actionDefinition, KrmsTypeResolver typeResolver) {
46  		this.actionDefinition = actionDefinition;
47  		this.typeResolver = typeResolver;
48  		this.action = null;
49  	}
50  	
51  	@Override
52  	public void execute(ExecutionEnvironment environment) {
53  		getAction().execute(environment);
54  	}
55  
56  	@Override
57  	public void executeSimulation(ExecutionEnvironment environment) {
58  		getAction().executeSimulation(environment);
59  	}
60  	
61  	/**
62  	 * Gets the action using a lazy double-checked locking mechanism as documented in Effective Java Item 71.
63       * @return Action
64  	 */
65  	private Action getAction() {
66  		Action localAction = action;
67  		if (localAction == null) {
68  			synchronized (mutex) {
69  				localAction = action;
70  				if (localAction == null) {
71  					action = localAction = constructAction();
72  				}
73  			}
74  		}
75  		return localAction;
76  	}
77  
78      /**
79       * builder method
80       * @return Action
81       */
82  	private Action constructAction() {
83  		ActionTypeService actionTypeService = typeResolver.getActionTypeService(actionDefinition);
84  		Action action = actionTypeService.loadAction(actionDefinition);
85  		if (action == null) {
86  			action = new Action() {
87  				@Override
88  				public void execute(ExecutionEnvironment environment) {
89  				}
90  				public void executeSimulation(ExecutionEnvironment environment) {
91  				}
92  			};
93  		}
94  		return action;
95  	}
96  
97  	
98  }