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.test.context;
17  
18  import java.util.Map;
19  import java.util.TreeMap;
20  
21  import org.apache.commons.logging.Log;
22  import org.apache.commons.logging.LogFactory;
23  import org.argeo.slc.core.test.SimpleResultPart;
24  import org.argeo.slc.test.TestResult;
25  import org.argeo.slc.test.TestStatus;
26  import org.argeo.slc.test.context.ContextAware;
27  import org.argeo.slc.test.context.ParentContextAware;
28  
29  /** Utilities for comparing and synchronising contexts. */
30  public class ContextUtils {
31  	private final static Log log = LogFactory.getLog(ContextUtils.class);
32  
33  	public static void compareReachedExpected(ContextAware contextAware,
34  			TestResult testResult) {
35  		for (String key : contextAware.getExpectedValues().keySet()) {
36  
37  			// Compare expected values with reached ones
38  			Object expectedValue = contextAware.getExpectedValues().get(key);
39  
40  			if (expectedValue.toString().equals(
41  					contextAware.getContextSkipFlag())) {
42  				if (log.isDebugEnabled())
43  					log.debug("Skipped check for key '" + key + "'");
44  				continue;
45  			}
46  
47  			if (contextAware.getValues().containsKey(key)) {
48  				Object reachedValue = contextAware.getValues().get(key);
49  
50  				if (expectedValue.equals(contextAware.getContextAnyFlag())) {
51  					testResult.addResultPart(new SimpleResultPart(
52  							TestStatus.PASSED, "Expected any value for key '"
53  									+ key + "'"));
54  				} else if (expectedValue.equals(reachedValue)) {
55  					testResult.addResultPart(new SimpleResultPart(
56  							TestStatus.PASSED, "Values matched for key '" + key
57  									+ "'"));
58  				} else {
59  					testResult.addResultPart(new SimpleResultPart(
60  							TestStatus.FAILED, "Mismatch for key '" + key
61  									+ "': expected '" + expectedValue
62  									+ "' but reached '" + reachedValue + "'"));
63  				}
64  			} else {
65  				testResult.addResultPart(new SimpleResultPart(
66  						TestStatus.FAILED, "No value reached for key '" + key
67  								+ "'"));
68  			}
69  		}
70  	}
71  
72  	/**
73  	 * Makes sure that all children and sub-children of parent share the same
74  	 * maps for values and expected values.
75  	 */
76  	public static void synchronize(ParentContextAware parent) {
77  		Map<String, Object> expectedValuesCommon = new TreeMap<String, Object>(
78  				parent.getExpectedValues());
79  		synchronize(parent, expectedValuesCommon);
80  		if (log.isDebugEnabled())
81  			log.debug("Synchronized context " + parent);
82  
83  	}
84  
85  	private static void synchronize(ParentContextAware parent,
86  			Map<String, Object> expectedValuesCommon) {
87  		for (ContextAware child : parent.getChildContexts()) {
88  			// Values
89  			putNotContained(parent.getValues(), child.getValues());
90  			child.setValues(parent.getValues());
91  
92  			// Expected Values
93  			// Expected values reference is not overridden: each child has its
94  			// own expected values map.
95  			overrideContained(expectedValuesCommon, child.getExpectedValues());
96  
97  			// Creates a new Map in order not to disturb other context using the
98  			// same keys
99  			Map<String, Object> expectedValuesCommonChild = new TreeMap<String, Object>(
100 					expectedValuesCommon);
101 			putNotContained(expectedValuesCommonChild,
102 					child.getExpectedValues());
103 
104 			if (child instanceof ParentContextAware) {
105 				// Recursive sync
106 				synchronize((ParentContextAware) child,
107 						expectedValuesCommonChild);
108 			}
109 		}
110 
111 	}
112 
113 	/**
114 	 * Put into common map the values from child map which are not already
115 	 * defined in common map.
116 	 */
117 	public static void putNotContained(Map<String, Object> commonMap,
118 			Map<String, Object> childMap) {
119 		for (String key : childMap.keySet()) {
120 			if (!commonMap.containsKey(key)) {
121 				commonMap.put(key, childMap.get(key));
122 			}
123 		}
124 	}
125 
126 	/** Overrides child map values with the values already set in common map */
127 	public static void overrideContained(Map<String, Object> commonMap,
128 			Map<String, Object> childMap) {
129 		for (String key : childMap.keySet()) {
130 			if (commonMap.containsKey(key)) {
131 				childMap.put(key, commonMap.get(key));
132 			}
133 		}
134 	}
135 
136 	/** Makes sure this cannot be instantiated. */
137 	private ContextUtils() {
138 
139 	}
140 }