1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
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
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
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 }