View Javadoc
1   /*
2    * Copyright (C) 2007-2012 Argeo GmbH
3    *
4    * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0
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.argeo.slc.core.execution;
17  
18  import java.util.Collections;
19  import java.util.Date;
20  import java.util.HashMap;
21  import java.util.Map;
22  import java.util.UUID;
23  
24  import org.argeo.slc.SlcException;
25  import org.argeo.slc.execution.ExecutionContext;
26  import org.argeo.slc.execution.ExecutionFlow;
27  import org.argeo.slc.execution.ExecutionStack;
28  import org.springframework.beans.BeanWrapper;
29  import org.springframework.beans.BeanWrapperImpl;
30  import org.springframework.beans.BeansException;
31  import org.springframework.context.ApplicationContext;
32  import org.springframework.context.ApplicationContextAware;
33  
34  public class MapExecutionContext implements ExecutionContext,
35  		ApplicationContextAware {
36  	private final Map<String, Object> variables = Collections
37  			.synchronizedMap(new HashMap<String, Object>());
38  
39  	private final String uuid;
40  
41  	private ApplicationContext applicationContext;
42  	private ExecutionStack executionStack;
43  
44  	public MapExecutionContext() {
45  		uuid = UUID.randomUUID().toString();
46  		variables.put(VAR_EXECUTION_CONTEXT_ID, uuid);
47  		variables.put(VAR_EXECUTION_CONTEXT_CREATION_DATE, new Date());
48  	}
49  
50  	public void setVariable(String key, Object value) {
51  		// check if we do not refer to a bean
52  		int lastInd = key.lastIndexOf('.');
53  		if (applicationContext != null && lastInd > 0) {
54  			String beanName = key.substring(0, lastInd);
55  			String propertyName = key.substring(lastInd + 1);
56  			if (applicationContext.containsBean(beanName)) {
57  				BeanWrapper beanWrapper = new BeanWrapperImpl(
58  						applicationContext.getBean(beanName));
59  				if (!beanWrapper.isWritableProperty(propertyName))
60  					throw new SlcException("No writable property "
61  							+ propertyName + " in bean " + beanName);
62  				beanWrapper.setPropertyValue(propertyName, value);
63  			}
64  		}
65  
66  		variables.put(key, value);
67  	}
68  
69  	public Object getVariable(String key) {
70  		// check if we do not refer to a bean
71  		int lastInd = key.lastIndexOf('.');
72  		if (applicationContext != null && lastInd > 0) {
73  			String beanName = key.substring(0, lastInd);
74  			String propertyName = key.substring(lastInd + 1);
75  			if (applicationContext.containsBean(beanName)) {
76  				BeanWrapper beanWrapper = new BeanWrapperImpl(
77  						applicationContext.getBean(beanName));
78  				if (!beanWrapper.isReadableProperty(propertyName))
79  					throw new SlcException("No readable property "
80  							+ propertyName + " in bean " + beanName);
81  				Object obj = beanWrapper.getPropertyValue(propertyName);
82  				return obj;
83  			}
84  		}
85  
86  		Object value = variables.get(key);
87  		// try system property in last resort
88  		if (value == null)
89  			value = System.getProperty(key);
90  
91  		// if the variable was not found, look in the stack starting at the
92  		// upper flows
93  		if (value == null) {
94  			value = executionStack.findLocalVariable(key);
95  		}
96  		return value;
97  	}
98  
99  	public String getUuid() {
100 		return uuid;
101 	}
102 
103 	@Override
104 	public void beforeFlow(ExecutionFlow executionFlow) {
105 		// getUuid();
106 		executionStack.enterFlow(executionFlow);
107 		setVariable(ExecutionContext.VAR_FLOW_ID,
108 				executionStack.getCurrentStackLevelUuid());
109 		setVariable(ExecutionContext.VAR_FLOW_NAME, executionFlow.getName());
110 	}
111 
112 	@Override
113 	public void afterFlow(ExecutionFlow executionFlow) {
114 		executionStack.leaveFlow(executionFlow);
115 	}
116 
117 	@Override
118 	public boolean equals(Object obj) {
119 		if (obj instanceof ExecutionContext)
120 			return uuid.equals(((ExecutionContext) obj).getUuid());
121 		return false;
122 	}
123 
124 	@Override
125 	public String toString() {
126 		return getClass().getSimpleName() + "#" + uuid;
127 	}
128 
129 	public void setApplicationContext(ApplicationContext applicationContext)
130 			throws BeansException {
131 		this.applicationContext = applicationContext;
132 	}
133 
134 	public void setExecutionStack(ExecutionStack executionStack) {
135 		this.executionStack = executionStack;
136 	}
137 
138 }