View Javadoc
1   package io.guixer.tools;
2   
3   import static com.google.common.base.Preconditions.checkNotNull;
4   import static com.google.common.collect.Maps.newHashMap;
5   
6   import java.util.Map;
7   
8   import javax.annotation.Nullable;
9   
10  import com.google.common.collect.Iterables;
11  
12  public abstract class AbstractExecutionContext implements ExecutionContext {
13  
14  	private final Map<String, Object> variables = newHashMap();
15  	private final Map<String, Object> maskedVariables = newHashMap();
16  	private final Functions functions;
17  
18  	public AbstractExecutionContext(
19  		final Functions functions
20  	) {
21  
22  		this.functions = checkNotNull(functions, "functions");
23  	}
24  
25  	@Override
26  	public final String[] getVariableNames() {
27  
28  		return Iterables.toArray(variables.keySet(), String.class);
29  	}
30  
31  	@Override
32  	public final <T> T setVariable(
33  		final String name,
34  		final T value
35  	) {
36  
37  		checkNotNull(name, "name");
38  		checkNotNull(value, "value");
39  
40  		maskedVariables.remove(name);
41  
42  		variables.put(name, value);
43  
44  		return value;
45  	}
46  
47  	@Override
48  	public final void setMaskedVariable(
49  		final String name,
50  		final Object value
51  	) {
52  
53  		checkNotNull(name, "name");
54  		checkNotNull(value, "value");
55  
56  		variables.remove(name);
57  
58  		maskedVariables.put(name, value);
59  	}
60  
61  	@Override
62  	public boolean usesMaskedVariables(
63  		final String value
64  	) {
65  
66  		// Filter: ${baseUrl}
67  		//
68  		for (int offset = 0;;) {
69  			final int index = value.indexOf("${", offset);
70  
71  			if (index == -1) {
72  				break;
73  			}
74  
75  			final int end = value.indexOf("}", index);
76  
77  			offset = index + 1;
78  
79  			final String propertyName = value.substring(index + 2, end).trim();
80  
81  			if (maskedVariables.containsKey(propertyName)) {
82  
83  				return true;
84  			}
85  		}
86  
87  		return false;
88  	}
89  
90  	@Override
91  	@Nullable
92  	public final Object getVariable(
93  		final String name
94  	) {
95  
96  		checkNotNull(name, "name");
97  
98  		return variables.get(name);
99  	}
100 
101 	@Override
102 	public final void removeVariable(
103 		final String name
104 	) {
105 
106 		checkNotNull(name, "name");
107 
108 		variables.remove(name);
109 	}
110 
111 	@Override
112 	public final String filterPlain(
113 		final String value
114 	) {
115 
116 		return filter(value, false);
117 	}
118 
119 	@Override
120 	public final String filterMasked(
121 		final String value
122 	) {
123 
124 		return filter(value, true);
125 	}
126 
127 	private String filter(
128 		final String value,
129 		final boolean isMasked
130 	) {
131 
132 		checkNotNull(value, "value");
133 
134 		String filtered = value;
135 
136 		// 1. Filter: $( username )
137 		//
138 		while (true) {
139 
140 			final int index = filtered.indexOf("$(");
141 
142 			if (index == -1) {
143 				break;
144 			}
145 
146 			final int end = filtered.indexOf(")", index);
147 
148 			final String functionName = filtered.substring(index + 2, end).trim();
149 
150 			final String result = functions.executeFunction(functionName);
151 
152 			filtered = filtered.substring(0, index) //
153 					+ result //
154 					+ filtered.substring(end + 1);
155 		}
156 
157 		// 2. Filter: ${baseUrl}
158 		//
159 		while (true) {
160 
161 			final int index = filtered.indexOf("${");
162 
163 			if (index == -1) {
164 				break;
165 			}
166 
167 			final int end = filtered.indexOf("}", index);
168 
169 			final String propertyName = filtered.substring(index + 2, end).trim();
170 
171 			@Nullable
172 			final Object maskedPropertyValue = maskedVariables.get(propertyName);
173 
174 			if (maskedPropertyValue != null) {
175 
176 				if (isMasked) {
177 
178 					filtered = filtered.substring(0, index) //
179 							+ maskedPropertyValue.toString() //
180 							+ filtered.substring(end + 1);
181 
182 					continue;
183 				}
184 
185 				throw new RuntimeException("Use of masked variable is forbidden: " + propertyName);
186 			}
187 
188 			@Nullable
189 			final Object propertyValue = variables.get(propertyName);
190 
191 			if (propertyValue == null) {
192 				throw new IllegalStateException("Unknown context attribute: " + propertyName);
193 			}
194 
195 			filtered = filtered.substring(0, index) //
196 					+ propertyValue.toString() //
197 					+ filtered.substring(end + 1);
198 		}
199 
200 		return filtered;
201 	}
202 }