View Javadoc

1   /*
2    * Copyright 2006 Outsource Cafe, Inc.
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.javagen.agile.core.context;
17  
18  import java.util.ArrayList;
19  import java.util.Collection;
20  import java.util.List;
21  import java.util.Map;
22  import java.util.Set;
23  
24  /***
25   * Holds a stack of ContextHolders (i.e. Contexts) allowing access as if it was a single
26   * context.  Keys pushed on the stack will mask prior keys with identical names.
27   * 
28   * @author Richard Easterling
29   */
30  public class ContextHolderStack implements Context {
31  
32  	protected List<ContextHolder> contextHolderStack = new ArrayList<ContextHolder>();
33  	
34  	protected Context combinedContext;
35  	
36  	////////////////////////////////////////////////////////////////////////////
37  	// Stack methods:
38  	////////////////////////////////////////////////////////////////////////////
39  	
40  	public ContextHolder pop() {
41  		combinedContext = null;
42  		return contextHolderStack.isEmpty() ? null : contextHolderStack.remove(contextHolderStack.size()-1);
43  	}
44  	
45  	public ContextHolder peek() {
46  		return contextHolderStack.isEmpty() ? null : contextHolderStack.get(contextHolderStack.size()-1);
47  	}
48  	
49  	public ContextHolderStack push(ContextHolder context) {
50  		if (context!=null)
51  			contextHolderStack.add(context);
52  		combinedContext = null;
53  		return this;
54  	}
55  	
56  	////////////////////////////////////////////////////////////////////////////
57  	// Map methods:
58  	////////////////////////////////////////////////////////////////////////////
59  
60  	public Object get(Object key) {
61  		if (contextHolderStack==null)
62  			return null;
63  		for(int i=contextHolderStack.size()-1; i>=0; i--) {
64  			ContextHolder contextHolder = contextHolderStack.get(i);
65  			Object value = contextHolder.getContext()==null ? null : contextHolder.getContext().get(key);
66  			if (value!=null)
67  				return value;
68  		}
69  		return null;
70  	}
71  	
72  	public boolean containsKey(Object key) {
73  		if (contextHolderStack==null)
74  			return false;
75  		for(int i=contextHolderStack.size()-1; i>=0; i--) {
76  			ContextHolder contextHolder = contextHolderStack.get(i);
77  			boolean value = contextHolder.getContext()==null ? false : contextHolder.getContext().containsKey(key);
78  			if (value)
79  				return value;
80  		}
81  		return false;
82  	}
83  
84  	public Set<String> keySet() {
85  		return combinedContext().keySet();
86  	}
87  	
88  	public void clear() {
89  		combinedContext = null;
90  	}
91  
92  	public boolean containsValue(Object value) {
93  		return combinedContext().containsValue(value);
94  	}
95  
96  	public Set<Entry<String, Object>> entrySet() {
97  		return combinedContext().entrySet();
98  	}
99  
100 	public boolean equals(Object o) {
101 		return combinedContext().equals(o);
102 	}
103 
104 	public int hashCode() {
105 		return combinedContext().hashCode();
106 	}
107 
108 	public boolean isEmpty() {
109 		return combinedContext().isEmpty();
110 	}
111 
112 	public Object put(String key, Object value) {
113 		throw new UnsupportedOperationException("ContextHolderStack supports read-only methods of java.util.Map");
114 	}
115 
116 	public void putAll(Map<? extends String, ? extends Object> t) {
117 		throw new UnsupportedOperationException("ContextHolderStack supports read-only methods of java.util.Map");
118 	}
119 
120 	public Object remove(Object key) {
121 		throw new UnsupportedOperationException("ContextHolderStack supports read-only methods of java.util.Map");
122 	}
123 
124 	public int size() {
125 		return combinedContext().size();
126 	}
127 
128 	public Collection<Object> values() {
129 		return combinedContext().values();
130 	}
131 	
132 	////////////////////////////////////////////////////////////////////////////
133 	// support methods:
134 	////////////////////////////////////////////////////////////////////////////
135 
136 	public Context combinedContext() {
137 		if (combinedContext==null) {
138 			combinedContext = new DefaultContext();
139 			for(ContextHolder contextHolder : contextHolderStack) {
140 				Map<String, Object> context = contextHolder.getContext();
141 				if (context!=null)
142 					for(String key : context.keySet()) {
143 						combinedContext.put(key, context.get(key));
144 					}
145 			}
146 		}
147 		return combinedContext;
148 	}
149 
150 	
151 }