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