1 package cz.cuni.amis.pogamut.sposh.engine;
2
3 import cz.cuni.amis.pogamut.sposh.elements.Arguments;
4 import cz.cuni.amis.pogamut.sposh.elements.Arguments.Argument;
5 import cz.cuni.amis.pogamut.sposh.elements.FormalParameters;
6 import cz.cuni.amis.pogamut.sposh.elements.Result;
7 import java.util.Arrays;
8 import java.util.HashMap;
9 import java.util.HashSet;
10 import java.util.Map;
11 import java.util.Map.Entry;
12 import java.util.Set;
13
14
15
16
17
18
19
20 final public class VariableContext {
21 private VariableContext parent;
22 private Map<String, Object> args = new HashMap<String, Object>();
23
24 public VariableContext() {
25 this.parent = null;
26 }
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 public VariableContext(VariableContext ctx, Arguments callArgs) {
47 this.parent = ctx;
48 for (Arguments.Argument param : callArgs) {
49 String argumentVariable = param.getParameterVariable();
50 if (argumentVariable != null) {
51 args.put(param.getParameterName(), ctx.getValue(argumentVariable));
52 } else {
53 args.put(param.getParameterName(), param.getValue());
54 }
55 }
56 }
57
58
59
60
61
62
63
64
65
66
67
68 public VariableContext(VariableContext ctx, Arguments callParameters, FormalParameters formalParameters) {
69 this.parent = ctx;
70 HashSet<Argument> unusedArgs = new HashSet<Argument>(callParameters);
71 for (int index = 0; index < formalParameters.size(); ++index) {
72 String ctxVariableName = formalParameters.get(index).getName();
73 Object ctxVariableValue = formalParameters.get(index).getDefaultValue();
74
75
76 for (Argument param : callParameters) {
77 String argumentName = param.getParameterName();
78 try {
79 int paramterIndex = Integer.parseInt(argumentName);
80 if (index != paramterIndex) {
81 continue;
82 }
83 } catch (NumberFormatException ex) {
84
85
86 String parameterName = param.getParameterName();
87 if (!parameterName.equals(ctxVariableName))
88 continue;
89 }
90
91 unusedArgs.remove(param);
92
93 String variableName = param.getParameterVariable();
94 if (variableName != null) {
95 ctxVariableValue = ctx.getValue(variableName);
96 } else {
97 ctxVariableValue = param.getValue();
98 }
99 }
100
101 args.put(ctxVariableName, ctxVariableValue);
102 }
103 for (Argument unusedArg : unusedArgs) {
104 String variableName = unusedArg.getParameterVariable();
105 if (variableName != null) {
106 args.put(unusedArg.getParameterName(), ctx.getValue(variableName));
107 } else {
108 args.put(unusedArg.getParameterName(), unusedArg.getValue());
109 }
110 }
111 }
112
113
114
115
116
117
118
119 public synchronized Object put(String parameterName, Object value) {
120 return args.put(parameterName, value);
121 }
122
123
124
125
126
127 public synchronized String[] getKeys() {
128 Set<String> allKeys = new HashSet<String>();
129 VariableContext currentCtx = this;
130 while (currentCtx != null) {
131 allKeys.addAll(currentCtx.args.keySet());
132 currentCtx = currentCtx.parent;
133 }
134 return allKeys.toArray(new String[allKeys.size()]);
135 }
136
137
138
139
140
141
142
143 public synchronized Object getValue(String variableName) {
144 if (args.containsKey(variableName)) {
145 return args.get(variableName);
146 }
147 if (this.parent != null) {
148 return parent.getValue(variableName);
149 }
150 throw new IllegalArgumentException("There is no variable in the context with name \"" + variableName + "\".");
151 }
152
153 @Override
154 public String toString() {
155 StringBuilder sb = new StringBuilder();
156
157 sb.append('[');
158 String[] list = new String[args.size()];
159 int index = 0;
160 for (Entry entry : args.entrySet()) {
161 list[index++] = entry.getKey() + "=" + Result.toLap(entry.getValue());
162 }
163 Arrays.sort(list);
164 for (int i = 0; i < list.length; ++i) {
165 if (i != 0) {
166 sb.append(", ");
167 }
168 sb.append(list[i]);
169 }
170
171 sb.append(']');
172 return sb.toString();
173 }
174
175 public synchronized int size() {
176 return this.args.size();
177 }
178
179 public boolean hasVariable(String variableName) {
180 if (args.containsKey(variableName)) {
181 return true;
182 }
183 if (this.parent != null) {
184 return parent.hasVariable(variableName);
185 }
186 return false;
187 }
188 }