View Javadoc

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 java.util.Arrays;
7   import java.util.HashMap;
8   import java.util.Map;
9   import java.util.Map.Entry;
10  
11  /**
12   * This class is responsible for storing and passing arguments throught the posh plan.
13   * Unnamed varibales are named as number (e.g. "0", "1"...), named variables
14   * have same name as in plan.
15   * @author Honza
16   */
17  final public class VariableContext {
18  
19      private Map<String, Object> args = new HashMap<String, Object>();
20  
21      public VariableContext() {
22      }
23  
24      /**
25       * Create argument context from formal parameters.
26       */
27      VariableContext(FormalParameters params) {
28          for (FormalParameters.Parameter param : params) {
29              if (args.put(param.getName(), param.getDefaultValue()) != null) {
30                  throw new IllegalArgumentException(
31                          "Two parameters with same name \"" + param.getName()
32                          + "\", default value \"" + param.getDefaultValue() + "\".");
33              }
34          }
35      }
36  
37      /**
38       * Create new VariableContext that will contain only variables from call arguments.
39       * @param callArgs
40       */
41      VariableContext(VariableContext ctx, Arguments callArgs) {
42          for (Arguments.Argument param : callArgs) {
43              String argumentVariable = param.getParameterVariable();
44              if (argumentVariable != null) {
45                  args.put(param.getParameterName(), ctx.getValue(argumentVariable));
46              } else {
47                  args.put(param.getParameterName(), param.getValue());
48              }
49          }
50      }
51  
52      VariableContext(VariableContext ctx) {
53          for (Map.Entry<String, Object> arg : ctx.args.entrySet()) {
54              args.put(arg.getKey(), arg.getValue());
55          }
56      }
57  
58      /**
59       * Create new variable context for diving into another function.
60       * New context will contain only variables from formal parameters, and its
61       * values will be values passed from call arguments or (if missing) default value
62       * from formal parametrs.
63       * 
64       * @param ctx
65       * @param callParameters
66       * @param formalParameters
67       */
68      VariableContext(VariableContext ctx, Arguments callParameters, FormalParameters formalParameters) {
69          for (int index = 0; index < formalParameters.size(); ++index) {
70              String ctxVariableName = formalParameters.get(index).getName();
71              Object ctxVariableValue = formalParameters.get(index).getDefaultValue();
72  
73              // if user supplied value, get it and put it into ctxVariableValue instead of default value
74              for (Argument param : callParameters) {
75                  String argumentName = param.getParameterName();
76                  try {
77                      int paramterIndex = Integer.parseInt(argumentName);
78                      if (index != paramterIndex) {
79                          continue;
80                      }
81                  } catch (NumberFormatException ex) {
82                      // nope, this is not a unnamed parametr, this one has a name
83                      // Is name among formal parametrs?
84                      String parameterName = param.getParameterName();
85                      if (!parameterName.equals(ctxVariableName))
86                          continue;
87                  }
88                  
89                  String variableName = param.getParameterVariable();
90                  if (variableName != null) {
91                      ctxVariableValue = ctx.getValue(variableName);
92                  } else {
93                      ctxVariableValue = param.getValue();
94                  }
95              }
96  
97              args.put(ctxVariableName, ctxVariableValue);
98          }
99      }
100 
101     /**
102      * Put another variable into this context
103      * @param parameterName name of new parameter
104      * @param value value of parameter
105      * @return old value for parameterName or null if it is a new parameter.
106      */
107     public synchronized Object put(String parameterName, Object value) {
108         return args.put(parameterName, value);
109     }
110 
111     /**
112      * Get keys of all variables in this context.
113      * @return
114      */
115     public synchronized String[] getKeys() {
116         return args.keySet().toArray(new String[args.size()]);
117     }
118 
119     /**
120      * Get value stored in the 
121      * @param variableName
122      * @return
123      */
124     public synchronized Object getValue(String variableName) {
125         if (args.containsKey(variableName)) {
126             return args.get(variableName);
127         }
128         throw new IllegalArgumentException("There is no variable in the context with name \"" + variableName + "\".");
129     }
130 
131     @Override
132     public String toString() {
133         StringBuilder sb = new StringBuilder();
134 
135         sb.append('[');
136         String[] list = new String[args.size()];
137         int index = 0;
138         for (Entry entry : args.entrySet()) {
139             list[index++] = entry.getKey() + "=" + entry.getValue();
140         }
141         Arrays.sort(list);
142         for (int i = 0; i < list.length; ++i) {
143             if (i != 0) {
144                 sb.append(", ");
145             }
146             sb.append(list[i]);
147         }
148 
149         sb.append(']');
150         return sb.toString();
151     }
152 
153     public synchronized int size() {
154         return this.args.size();
155     }
156 }