Mercurial > dive4elements > river
comparison artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/FunctionResolver.java @ 9299:4a6cc7c6716a
uinfo.inundation_duration veg'zone select
author | gernotbelger |
---|---|
date | Wed, 25 Jul 2018 14:42:44 +0200 |
parents | 5030c46d8cb4 |
children | e511eb935ccd |
comparison
equal
deleted
inserted
replaced
9298:0b1a51b0c42e | 9299:4a6cc7c6716a |
---|---|
6 * documentation coming with Dive4Elements River for details. | 6 * documentation coming with Dive4Elements River for details. |
7 */ | 7 */ |
8 | 8 |
9 package org.dive4elements.river.artifacts.datacage.templating; | 9 package org.dive4elements.river.artifacts.datacage.templating; |
10 | 10 |
11 import java.lang.reflect.InvocationTargetException; | |
12 import java.lang.reflect.Method; | |
11 import java.text.SimpleDateFormat; | 13 import java.text.SimpleDateFormat; |
12 import java.util.ArrayList; | 14 import java.util.ArrayList; |
13 import java.util.Collection; | 15 import java.util.Collection; |
14 import java.util.Collections; | 16 import java.util.Collections; |
15 import java.util.Date; | 17 import java.util.Date; |
18 import java.util.HashMap; | |
16 import java.util.List; | 19 import java.util.List; |
17 import java.util.Map; | 20 import java.util.Map; |
18 import java.util.HashMap; | |
19 import java.util.Set; | 21 import java.util.Set; |
20 import java.util.regex.Matcher; | 22 import java.util.regex.Matcher; |
21 import java.util.regex.Pattern; | 23 import java.util.regex.Pattern; |
22 | 24 |
23 import java.lang.reflect.InvocationTargetException; | |
24 import java.lang.reflect.Method; | |
25 | |
26 import javax.xml.namespace.QName; | 25 import javax.xml.namespace.QName; |
27 | |
28 import javax.xml.xpath.XPathFunction; | 26 import javax.xml.xpath.XPathFunction; |
29 import javax.xml.xpath.XPathFunctionException; | 27 import javax.xml.xpath.XPathFunctionException; |
30 import javax.xml.xpath.XPathFunctionResolver; | 28 import javax.xml.xpath.XPathFunctionResolver; |
31 | 29 |
32 import org.apache.log4j.Logger; | 30 import org.apache.log4j.Logger; |
33 import org.dive4elements.artifactdatabase.transition.TransitionEngine; | 31 import org.dive4elements.artifactdatabase.transition.TransitionEngine; |
34 import org.dive4elements.artifacts.GlobalContext; | 32 import org.dive4elements.artifacts.GlobalContext; |
35 import org.dive4elements.river.artifacts.context.RiverContext; | 33 import org.dive4elements.river.artifacts.context.RiverContext; |
36 import org.dive4elements.river.artifacts.context.RiverContextFactory; | 34 import org.dive4elements.river.artifacts.context.RiverContextFactory; |
37 | 35 |
38 | |
39 /** Resolves functions (e.g. dc:contains) in Datacage/Meta-Data system. */ | 36 /** Resolves functions (e.g. dc:contains) in Datacage/Meta-Data system. */ |
40 public class FunctionResolver | 37 public class FunctionResolver implements XPathFunctionResolver { |
41 implements XPathFunctionResolver | |
42 { | |
43 /** Home log. */ | 38 /** Home log. */ |
44 private static Logger log = Logger.getLogger(FunctionResolver.class); | 39 private static Logger log = Logger.getLogger(FunctionResolver.class); |
45 | 40 |
46 public static final String FUNCTION_NAMESPACE_URI = "dc"; | 41 public static final String FUNCTION_NAMESPACE_URI = "dc"; |
47 | 42 |
48 public static final double FAR_AWAY = 99999d; | 43 public static final double FAR_AWAY = 99999d; |
49 | 44 |
50 protected static final class Entry { | 45 protected static final class Entry { |
51 | 46 |
52 Entry next; | 47 Entry next; |
53 XPathFunction function; | 48 XPathFunction function; |
54 int arity; | 49 int arity; |
55 | 50 |
56 public Entry(Entry next, XPathFunction function, int arity) { | 51 public Entry(final Entry next, final XPathFunction function, final int arity) { |
57 this.next = next; | 52 this.next = next; |
58 this.function = function; | 53 this.function = function; |
59 this.arity = arity; | 54 this.arity = arity; |
60 } | 55 } |
61 | 56 |
62 XPathFunction find(int arity) { | 57 XPathFunction find(final int arity) { |
63 Entry current = this; | 58 Entry current = this; |
64 while (current != null) { | 59 while (current != null) { |
65 if (current.arity == arity) { | 60 if (current.arity == arity) { |
66 return current.function; | 61 return current.function; |
67 } | 62 } |
74 /** List of functions. */ | 69 /** List of functions. */ |
75 protected Map<String, Entry> functions; | 70 protected Map<String, Entry> functions; |
76 | 71 |
77 protected Builder.BuildHelper buildHelper; | 72 protected Builder.BuildHelper buildHelper; |
78 | 73 |
79 | |
80 public FunctionResolver() { | 74 public FunctionResolver() { |
81 this(null); | 75 this(null); |
82 } | 76 } |
83 | 77 |
84 public FunctionResolver(Builder.BuildHelper buildHelper) { | 78 public FunctionResolver(final Builder.BuildHelper buildHelper) { |
85 this.buildHelper = buildHelper; | 79 this.buildHelper = buildHelper; |
86 | 80 |
87 functions = new HashMap<String, Entry>(); | 81 this.functions = new HashMap<>(); |
88 | 82 |
89 addFunction("coalesce", 2, new XPathFunction() { | 83 addFunction("coalesce", 2, new XPathFunction() { |
90 @Override | 84 @Override |
91 public Object evaluate(List args) throws XPathFunctionException { | 85 public Object evaluate(final List args) throws XPathFunctionException { |
92 return coalesce(args); | 86 return coalesce(args); |
93 } | 87 } |
94 }); | 88 }); |
95 | 89 |
90 addFunction("toString", 1, new XPathFunction() { | |
91 @Override | |
92 public Object evaluate(final List args) throws XPathFunctionException { | |
93 final Object arg = args.get(0); | |
94 return arg == null ? null : arg.toString(); | |
95 } | |
96 }); | |
97 | |
96 addFunction("lowercase", 1, new XPathFunction() { | 98 addFunction("lowercase", 1, new XPathFunction() { |
97 @Override | 99 @Override |
98 public Object evaluate(List args) throws XPathFunctionException { | 100 public Object evaluate(final List args) throws XPathFunctionException { |
99 return args.get(0).toString().toLowerCase(); | 101 return args.get(0).toString().toLowerCase(); |
100 } | 102 } |
101 }); | 103 }); |
102 | 104 |
103 addFunction("uppercase", 1, new XPathFunction() { | 105 addFunction("uppercase", 1, new XPathFunction() { |
104 @Override | 106 @Override |
105 public Object evaluate(List args) throws XPathFunctionException { | 107 public Object evaluate(final List args) throws XPathFunctionException { |
106 return args.get(0).toString().toUpperCase(); | 108 return args.get(0).toString().toUpperCase(); |
107 } | 109 } |
108 }); | 110 }); |
109 | 111 |
110 addFunction("contains", 2, new XPathFunction() { | 112 addFunction("contains", 2, new XPathFunction() { |
111 @Override | 113 @Override |
112 public Object evaluate(List args) throws XPathFunctionException { | 114 public Object evaluate(final List args) throws XPathFunctionException { |
113 return contains(args); | 115 return contains(args); |
114 } | 116 } |
115 }); | 117 }); |
116 | 118 |
117 addFunction("fromValue", 3, new XPathFunction() { | 119 addFunction("fromValue", 3, new XPathFunction() { |
118 @Override | 120 @Override |
119 public Object evaluate(List args) throws XPathFunctionException { | 121 public Object evaluate(final List args) throws XPathFunctionException { |
120 return fromValue(args); | 122 return fromValue(args); |
121 } | 123 } |
122 }); | 124 }); |
123 | 125 |
124 addFunction("toValue", 3, new XPathFunction() { | 126 addFunction("toValue", 3, new XPathFunction() { |
125 @Override | 127 @Override |
126 public Object evaluate(List args) throws XPathFunctionException { | 128 public Object evaluate(final List args) throws XPathFunctionException { |
127 return toValue(args); | 129 return toValue(args); |
128 } | 130 } |
129 }); | 131 }); |
130 | 132 |
131 addFunction("replace", 3, new XPathFunction() { | 133 addFunction("replace", 3, new XPathFunction() { |
132 @Override | 134 @Override |
133 public Object evaluate(List args) throws XPathFunctionException { | 135 public Object evaluate(final List args) throws XPathFunctionException { |
134 return replace(args); | 136 return replace(args); |
135 } | 137 } |
136 }); | 138 }); |
137 | 139 |
138 addFunction("replace-all", 3, new XPathFunction() { | 140 addFunction("replace-all", 3, new XPathFunction() { |
139 @Override | 141 @Override |
140 public Object evaluate(List args) throws XPathFunctionException { | 142 public Object evaluate(final List args) throws XPathFunctionException { |
141 return replaceAll(args); | 143 return replaceAll(args); |
142 } | 144 } |
143 }); | 145 }); |
144 | 146 |
145 addFunction("has-result", 0, new XPathFunction() { | 147 addFunction("has-result", 0, new XPathFunction() { |
146 @Override | 148 @Override |
147 public Object evaluate(List args) throws XPathFunctionException { | 149 public Object evaluate(final List args) throws XPathFunctionException { |
148 return FunctionResolver.this.buildHelper.hasResult(); | 150 return FunctionResolver.this.buildHelper.hasResult(); |
149 } | 151 } |
150 }); | 152 }); |
151 | 153 |
152 addFunction("group-key", 0, new XPathFunction() { | 154 addFunction("group-key", 0, new XPathFunction() { |
153 @Override | 155 @Override |
154 public Object evaluate(List args) throws XPathFunctionException { | 156 public Object evaluate(final List args) throws XPathFunctionException { |
155 return FunctionResolver.this.buildHelper.getGroupKey(); | 157 return FunctionResolver.this.buildHelper.getGroupKey(); |
156 } | 158 } |
157 }); | 159 }); |
158 | 160 |
159 addFunction("date-format", 2, new XPathFunction() { | 161 addFunction("date-format", 2, new XPathFunction() { |
160 @Override | 162 @Override |
161 public Object evaluate(List args) throws XPathFunctionException { | 163 public Object evaluate(final List args) throws XPathFunctionException { |
162 return dateFormat(args); | 164 return dateFormat(args); |
163 } | 165 } |
164 }); | 166 }); |
165 | 167 |
166 addFunction("dump-variables", 0, new XPathFunction() { | 168 addFunction("dump-variables", 0, new XPathFunction() { |
167 @Override | 169 @Override |
168 public Object evaluate(List args) throws XPathFunctionException { | 170 public Object evaluate(final List args) throws XPathFunctionException { |
169 return FunctionResolver.this.buildHelper.frames.dump(); | 171 return FunctionResolver.this.buildHelper.frames.dump(); |
170 } | 172 } |
171 }); | 173 }); |
172 | 174 |
173 addFunction("get", 1, new XPathFunction() { | 175 addFunction("get", 1, new XPathFunction() { |
174 @Override | 176 @Override |
175 public Object evaluate(List args) throws XPathFunctionException { | 177 public Object evaluate(final List args) throws XPathFunctionException { |
176 Object o = args.get(0); | 178 final Object o = args.get(0); |
177 if (o instanceof String) { | 179 if (o instanceof String) { |
178 return FunctionResolver.this.buildHelper.frames.getNull( | 180 return FunctionResolver.this.buildHelper.frames.getNull((String) o, StackFrames.NULL); |
179 (String)o, StackFrames.NULL); | |
180 } | 181 } |
181 return StackFrames.NULL; | 182 return StackFrames.NULL; |
182 } | 183 } |
183 }); | 184 }); |
184 | 185 |
185 addFunction("all-state-successors", 2, new XPathFunction() { | 186 addFunction("all-state-successors", 2, new XPathFunction() { |
186 @Override | 187 @Override |
187 public Object evaluate(List args) throws XPathFunctionException { | 188 public Object evaluate(final List args) throws XPathFunctionException { |
188 Object artifactName = args.get(0); | 189 final Object artifactName = args.get(0); |
189 Object stateId = args.get(1); | 190 final Object stateId = args.get(1); |
190 | 191 |
191 return artifactName instanceof String | 192 return artifactName instanceof String && stateId instanceof String ? allStateSuccessors((String) artifactName, (String) stateId) |
192 && stateId instanceof String | 193 : Collections.<String>emptySet(); |
193 ? allStateSuccessors((String)artifactName, (String)stateId) | |
194 : Collections.<String>emptySet(); | |
195 } | 194 } |
196 }); | 195 }); |
197 | 196 |
198 addFunction("find-all", 2, new XPathFunction() { | 197 addFunction("find-all", 2, new XPathFunction() { |
199 @Override | 198 @Override |
200 public Object evaluate(List args) throws XPathFunctionException { | 199 public Object evaluate(final List args) throws XPathFunctionException { |
201 Object needle = args.get(0); | 200 final Object needle = args.get(0); |
202 Object haystack = args.get(1); | 201 final Object haystack = args.get(1); |
203 return haystack instanceof String | 202 return haystack instanceof String && needle instanceof String ? findAll((String) needle, (String) haystack) : Collections.<String>emptyList(); |
204 && needle instanceof String | |
205 ? findAll((String)needle, (String)haystack) | |
206 : Collections.<String>emptyList(); | |
207 } | 203 } |
208 }); | 204 }); |
209 | 205 |
210 addFunction("max-number", 1, new XPathFunction() { | 206 addFunction("max-number", 1, new XPathFunction() { |
211 @Override | 207 @Override |
212 public Object evaluate(List args) throws XPathFunctionException { | 208 public Object evaluate(final List args) throws XPathFunctionException { |
213 return maxNumber(args.get(0)); | 209 return maxNumber(args.get(0)); |
214 } | 210 } |
215 }); | 211 }); |
216 | 212 |
217 addFunction("min-number", 1, new XPathFunction() { | 213 addFunction("min-number", 1, new XPathFunction() { |
218 @Override | 214 @Override |
219 public Object evaluate(List args) throws XPathFunctionException { | 215 public Object evaluate(final List args) throws XPathFunctionException { |
220 return minNumber(args.get(0)); | 216 return minNumber(args.get(0)); |
221 } | 217 } |
222 }); | 218 }); |
223 | 219 |
224 addFunction("column", 1, new XPathFunction() { | 220 addFunction("column", 1, new XPathFunction() { |
225 @Override | 221 @Override |
226 public Object evaluate(List args) throws XPathFunctionException { | 222 public Object evaluate(final List args) throws XPathFunctionException { |
227 return column(args.get(0)); | 223 return column(args.get(0)); |
228 } | 224 } |
229 }); | 225 }); |
230 | 226 |
231 addFunction(FixAnalysisYearXPathFunction.ID, FixAnalysisYearXPathFunction.ARITY, new FixAnalysisYearXPathFunction(buildHelper.getContext())); | 227 addFunction(FixAnalysisYearXPathFunction.ID, FixAnalysisYearXPathFunction.ARITY, new FixAnalysisYearXPathFunction(buildHelper.getContext())); |
228 | |
229 addFunction(DefaultVegetationZoneXPathFunction.ID, DefaultVegetationZoneXPathFunction.ARITY, new DefaultVegetationZoneXPathFunction()); | |
230 | |
231 addFunction(DataFromArtifactXPathFunction.ID, DataFromArtifactXPathFunction.ARITY, new DataFromArtifactXPathFunction(buildHelper.getContext())); | |
232 } | 232 } |
233 | 233 |
234 /** | 234 /** |
235 * Create a new function. | 235 * Create a new function. |
236 * @param name Name of the function. | 236 * |
237 * @param arity Number of arguments for function. | 237 * @param name |
238 * @param function the function itself. | 238 * Name of the function. |
239 * @param arity | |
240 * Number of arguments for function. | |
241 * @param function | |
242 * the function itself. | |
239 */ | 243 */ |
240 public void addFunction(String name, int arity, XPathFunction function) { | 244 public void addFunction(final String name, final int arity, final XPathFunction function) { |
241 Entry entry = functions.get(name); | 245 Entry entry = this.functions.get(name); |
242 if (entry == null) { | 246 if (entry == null) { |
243 entry = new Entry(null, function, arity); | 247 entry = new Entry(null, function, arity); |
244 functions.put(name, entry); | 248 this.functions.put(name, entry); |
245 } | 249 } else { |
246 else { | 250 final Entry newEntry = new Entry(entry.next, function, arity); |
247 Entry newEntry = new Entry(entry.next, function, arity); | |
248 entry.next = newEntry; | 251 entry.next = newEntry; |
249 } | 252 } |
250 } | 253 } |
251 | 254 |
252 @Override | 255 @Override |
253 public XPathFunction resolveFunction(QName functionName, int arity) { | 256 public XPathFunction resolveFunction(final QName functionName, final int arity) { |
254 | 257 |
255 if (!functionName.getNamespaceURI().equals(FUNCTION_NAMESPACE_URI)) { | 258 if (!functionName.getNamespaceURI().equals(FUNCTION_NAMESPACE_URI)) { |
256 return null; | 259 return null; |
257 } | 260 } |
258 | 261 |
259 Entry entry = functions.get(functionName.getLocalPart()); | 262 final Entry entry = this.functions.get(functionName.getLocalPart()); |
260 return entry != null | 263 return entry != null ? entry.find(arity) : null; |
261 ? entry.find(arity) | |
262 : null; | |
263 } | 264 } |
264 | 265 |
265 /** Implementation of case-ignoring dc:contains. */ | 266 /** Implementation of case-ignoring dc:contains. */ |
266 public static Object contains(List args) throws XPathFunctionException { | 267 public static Object contains(final List args) throws XPathFunctionException { |
267 Object haystack = args.get(0); | 268 final Object haystack = args.get(0); |
268 Object needle = args.get(1); | 269 Object needle = args.get(1); |
269 | 270 |
270 if (needle instanceof String && !(haystack instanceof String)) { | 271 if (needle instanceof String && !(haystack instanceof String)) { |
271 needle = ((String)needle).toUpperCase(); | 272 needle = ((String) needle).toUpperCase(); |
272 } | 273 } |
273 | 274 |
274 try { | 275 try { |
275 if (haystack instanceof Collection) { | 276 if (haystack instanceof Collection) { |
276 return Boolean.valueOf( | 277 return Boolean.valueOf(((Collection) haystack).contains(needle)); |
277 ((Collection)haystack).contains(needle)); | |
278 } | 278 } |
279 | 279 |
280 if (haystack instanceof Map) { | 280 if (haystack instanceof Map) { |
281 return Boolean.valueOf( | 281 return Boolean.valueOf(((Map) haystack).containsKey(needle)); |
282 ((Map)haystack).containsKey(needle)); | 282 } |
283 } | 283 |
284 | 284 if (haystack instanceof Object[]) { |
285 if (haystack instanceof Object []) { | 285 for (final Object straw : (Object[]) haystack) { |
286 for (Object straw: (Object [])haystack) { | |
287 if (straw.equals(needle)) { | 286 if (straw.equals(needle)) { |
288 return Boolean.TRUE; | 287 return Boolean.TRUE; |
289 } | 288 } |
290 } | 289 } |
291 } | 290 } |
292 | 291 |
293 if (haystack instanceof String && needle instanceof String) { | 292 if (haystack instanceof String && needle instanceof String) { |
294 String h = (String)haystack; | 293 final String h = (String) haystack; |
295 String n = (String)needle; | 294 final String n = (String) needle; |
296 return h.contains(n); | 295 return h.contains(n); |
297 } | 296 } |
298 | 297 |
299 return Boolean.FALSE; | 298 return Boolean.FALSE; |
300 } | 299 } |
301 catch (Exception e) { | 300 catch (final Exception e) { |
302 log.error(e); | 301 log.error(e); |
303 throw new XPathFunctionException(e); | 302 throw new XPathFunctionException(e); |
304 } | 303 } |
305 } | 304 } |
306 | 305 |
307 /** Implementation for getting the minimum value of location or distance | 306 /** |
308 * dc:fromValue. | 307 * Implementation for getting the minimum value of location or distance |
308 * dc:fromValue. | |
309 */ | 309 */ |
310 public static Object fromValue(List args) throws XPathFunctionException { | 310 public static Object fromValue(final List args) throws XPathFunctionException { |
311 Object mode = args.get(0); | 311 final Object mode = args.get(0); |
312 Object locations = args.get(1); | 312 final Object locations = args.get(1); |
313 Object from = args.get(2); | 313 final Object from = args.get(2); |
314 | 314 |
315 if ((mode instanceof String && mode.equals("location")) || | 315 if ((mode instanceof String && mode.equals("location")) || (locations instanceof String && !((String) locations).isEmpty())) { |
316 (locations instanceof String && !((String)locations).isEmpty())) { | |
317 if (!(locations instanceof String)) { | 316 if (!(locations instanceof String)) { |
318 return -FAR_AWAY; | 317 return -FAR_AWAY; |
319 } | 318 } |
320 String loc = ((String)locations).replace(" ", ""); | 319 final String loc = ((String) locations).replace(" ", ""); |
321 String[] split = loc.split(","); | 320 final String[] split = loc.split(","); |
322 if (split.length < 1) { | 321 if (split.length < 1) { |
323 return -FAR_AWAY; | 322 return -FAR_AWAY; |
324 } | 323 } |
325 try { | 324 try { |
326 double min = Double.parseDouble(split[0]); | 325 double min = Double.parseDouble(split[0]); |
327 for (int i = 1; i < split.length; ++i) { | 326 for (int i = 1; i < split.length; ++i) { |
328 double v = Double.parseDouble(split[i]); | 327 final double v = Double.parseDouble(split[i]); |
329 if (v < min) { | 328 if (v < min) { |
330 min = v; | 329 min = v; |
331 } | 330 } |
332 } | 331 } |
333 return min; | 332 return min; |
334 } | 333 } |
335 catch (NumberFormatException nfe) { | 334 catch (final NumberFormatException nfe) { |
336 return -FAR_AWAY; | 335 return -FAR_AWAY; |
337 } | 336 } |
338 } | 337 } else { |
339 else { | |
340 if (!(from instanceof String)) { | 338 if (!(from instanceof String)) { |
341 return -FAR_AWAY; | 339 return -FAR_AWAY; |
342 } | 340 } |
343 String f = (String)from; | 341 final String f = (String) from; |
344 try { | 342 try { |
345 return Double.parseDouble(f); | 343 return Double.parseDouble(f); |
346 } | 344 } |
347 catch(NumberFormatException nfe) { | 345 catch (final NumberFormatException nfe) { |
348 return -FAR_AWAY; | 346 return -FAR_AWAY; |
349 } | 347 } |
350 } | 348 } |
351 } | 349 } |
352 | 350 |
353 /** Implementation for getting the maximum value of location or distance | 351 /** |
354 * dc:toValue. | 352 * Implementation for getting the maximum value of location or distance |
353 * dc:toValue. | |
355 */ | 354 */ |
356 public static Object toValue(List args) throws XPathFunctionException { | 355 public static Object toValue(final List args) throws XPathFunctionException { |
357 Object mode = args.get(0); | 356 final Object mode = args.get(0); |
358 Object locations = args.get(1); | 357 final Object locations = args.get(1); |
359 Object to = args.get(2); | 358 final Object to = args.get(2); |
360 | 359 |
361 if ((mode instanceof String && mode.equals("location")) || | 360 if ((mode instanceof String && mode.equals("location")) || (locations instanceof String && !((String) locations).isEmpty())) { |
362 (locations instanceof String && !((String)locations).isEmpty())) { | |
363 if (!(locations instanceof String)) { | 361 if (!(locations instanceof String)) { |
364 return FAR_AWAY; | 362 return FAR_AWAY; |
365 } | 363 } |
366 try { | 364 try { |
367 String loc = ((String)locations).replace(" ", ""); | 365 final String loc = ((String) locations).replace(" ", ""); |
368 String[] split = loc.split(","); | 366 final String[] split = loc.split(","); |
369 if (split.length < 1) { | 367 if (split.length < 1) { |
370 return FAR_AWAY; | 368 return FAR_AWAY; |
371 } | 369 } |
372 double max = Double.parseDouble(split[0]); | 370 double max = Double.parseDouble(split[0]); |
373 for (int i = 1; i < split.length; ++i) { | 371 for (int i = 1; i < split.length; ++i) { |
374 double v = Double.parseDouble(split[i]); | 372 final double v = Double.parseDouble(split[i]); |
375 if (v > max) { | 373 if (v > max) { |
376 max = v; | 374 max = v; |
377 } | 375 } |
378 } | 376 } |
379 return max; | 377 return max; |
380 } | 378 } |
381 catch (NumberFormatException nfe) { | 379 catch (final NumberFormatException nfe) { |
382 return FAR_AWAY; | 380 return FAR_AWAY; |
383 } | 381 } |
384 } | 382 } else { |
385 else { | |
386 if (!(to instanceof String)) { | 383 if (!(to instanceof String)) { |
387 return FAR_AWAY; | 384 return FAR_AWAY; |
388 } | 385 } else { |
389 else { | 386 final String t = (String) to; |
390 String t = (String)to; | |
391 try { | 387 try { |
392 return Double.parseDouble(t); | 388 return Double.parseDouble(t); |
393 } | 389 } |
394 catch (NumberFormatException nfe) { | 390 catch (final NumberFormatException nfe) { |
395 return FAR_AWAY; | 391 return FAR_AWAY; |
396 } | 392 } |
397 } | 393 } |
398 } | 394 } |
399 } | 395 } |
400 | 396 |
401 /** Implementation for doing a string replace | 397 /** |
402 * dc:replace . | 398 * Implementation for doing a string replace |
399 * dc:replace . | |
403 */ | 400 */ |
404 public static Object replace(List args) throws XPathFunctionException { | 401 public static Object replace(final List args) throws XPathFunctionException { |
405 Object haystack = args.get(0); | 402 final Object haystack = args.get(0); |
406 Object needle = args.get(1); | 403 final Object needle = args.get(1); |
407 Object replacement = args.get(2); | 404 final Object replacement = args.get(2); |
408 | 405 |
409 if (needle instanceof String | 406 if (needle instanceof String && haystack instanceof String && replacement instanceof String) { |
410 && haystack instanceof String | 407 return ((String) haystack).replace((String) needle, (String) replacement); |
411 && replacement instanceof String) { | |
412 return ((String)haystack).replace( | |
413 (String)needle, (String)replacement); | |
414 } | 408 } |
415 return haystack; | 409 return haystack; |
416 } | 410 } |
417 | 411 |
418 /** Implementation for doing a string replace | 412 /** |
419 * dc:replace-all | 413 * Implementation for doing a string replace |
414 * dc:replace-all | |
420 */ | 415 */ |
421 public static Object replaceAll(List args) throws XPathFunctionException { | 416 public static Object replaceAll(final List args) throws XPathFunctionException { |
422 Object haystack = args.get(0); | 417 final Object haystack = args.get(0); |
423 Object needle = args.get(1); | 418 final Object needle = args.get(1); |
424 Object replacement = args.get(2); | 419 final Object replacement = args.get(2); |
425 | 420 |
426 if (needle instanceof String | 421 if (needle instanceof String && haystack instanceof String && replacement instanceof String) { |
427 && haystack instanceof String | 422 return ((String) haystack).replaceAll((String) needle, (String) replacement); |
428 && replacement instanceof String) { | |
429 return ((String)haystack).replaceAll( | |
430 (String)needle, (String)replacement); | |
431 } | 423 } |
432 return haystack; | 424 return haystack; |
433 } | 425 } |
434 | 426 |
435 public static Object dateFormat(List args) throws XPathFunctionException { | 427 public static Object dateFormat(final List args) throws XPathFunctionException { |
436 Object pattern = args.get(0); | 428 final Object pattern = args.get(0); |
437 Object date = args.get(1); | 429 Object date = args.get(1); |
438 | 430 |
439 try { | 431 try { |
440 // TODO: Take locale into account. | 432 // TODO: Take locale into account. |
441 SimpleDateFormat format = new SimpleDateFormat((String)pattern); | 433 final SimpleDateFormat format = new SimpleDateFormat((String) pattern); |
442 | 434 |
443 if (date instanceof Number) { | 435 if (date instanceof Number) { |
444 return format.format(new Date(((Number)date).longValue())); | 436 return format.format(new Date(((Number) date).longValue())); |
445 } | 437 } |
446 | 438 |
447 try { | 439 try { |
448 /* Oracle does not return a date object but | 440 /* |
449 an oracle.sql.TIMESTAMP */ | 441 * Oracle does not return a date object but |
450 Method meth = date.getClass() | 442 * an oracle.sql.TIMESTAMP |
451 .getMethod("dateValue", new Class[] {}); | 443 */ |
444 final Method meth = date.getClass().getMethod("dateValue", new Class[] {}); | |
452 date = meth.invoke(date, new Object[] {}); | 445 date = meth.invoke(date, new Object[] {}); |
453 } catch (IllegalArgumentException e) { | 446 } |
454 } catch (IllegalAccessException e) { | 447 catch (final IllegalArgumentException e) { |
455 } catch (InvocationTargetException e) { | 448 } |
456 } catch (NoSuchMethodException e) { | 449 catch (final IllegalAccessException e) { |
450 } | |
451 catch (final InvocationTargetException e) { | |
452 } | |
453 catch (final NoSuchMethodException e) { | |
457 } | 454 } |
458 | 455 |
459 if (date instanceof Date) { | 456 if (date instanceof Date) { |
460 return format.format((Date)date); | 457 return format.format((Date) date); |
461 } | 458 } |
462 } | 459 } |
463 catch (IllegalArgumentException iae) { | 460 catch (final IllegalArgumentException iae) { |
464 log.error(iae.getMessage()); | 461 log.error(iae.getMessage()); |
465 } | 462 } |
466 | 463 |
467 return ""; | 464 return ""; |
468 } | 465 } |
469 | 466 |
470 public static Set<String> allStateSuccessors( | 467 public static Set<String> allStateSuccessors(final String artifactName, final String stateId) { |
471 String artifactName, | 468 final GlobalContext gc = RiverContextFactory.getGlobalContext(); |
472 String stateId | |
473 ) { | |
474 GlobalContext gc = RiverContextFactory.getGlobalContext(); | |
475 if (gc == null) { | 469 if (gc == null) { |
476 return Collections.<String>emptySet(); | 470 return Collections.<String>emptySet(); |
477 } | 471 } |
478 Object o = gc.get(RiverContext.TRANSITION_ENGINE_KEY); | 472 final Object o = gc.get(RiverContext.TRANSITION_ENGINE_KEY); |
479 if (o instanceof TransitionEngine) { | 473 if (o instanceof TransitionEngine) { |
480 TransitionEngine te = (TransitionEngine)o; | 474 final TransitionEngine te = (TransitionEngine) o; |
481 return te.allRecursiveSuccessorStateIds(artifactName, stateId); | 475 return te.allRecursiveSuccessorStateIds(artifactName, stateId); |
482 } | 476 } |
483 return Collections.<String>emptySet(); | 477 return Collections.<String>emptySet(); |
484 } | 478 } |
485 | 479 |
486 public static Collection<String> findAll(String needle, String haystack) { | 480 public static Collection<String> findAll(final String needle, final String haystack) { |
487 | 481 |
488 ArrayList<String> result = new ArrayList<String>(); | 482 final ArrayList<String> result = new ArrayList<>(); |
489 | 483 |
490 Pattern pattern = Pattern.compile(needle); | 484 final Pattern pattern = Pattern.compile(needle); |
491 Matcher matcher = pattern.matcher(haystack); | 485 final Matcher matcher = pattern.matcher(haystack); |
492 while (matcher.find()) { | 486 while (matcher.find()) { |
493 result.add(matcher.group()); | 487 result.add(matcher.group()); |
494 } | 488 } |
495 return result; | 489 return result; |
496 } | 490 } |
497 | 491 |
498 public static Number maxNumber(Object list) { | 492 public static Number maxNumber(final Object list) { |
499 if (list instanceof Collection) { | 493 if (list instanceof Collection) { |
500 Collection collection = (Collection)list; | 494 final Collection collection = (Collection) list; |
501 double max = -Double.MAX_VALUE; | 495 double max = -Double.MAX_VALUE; |
502 for (Object x: collection) { | 496 for (final Object x : collection) { |
503 Number n; | 497 Number n; |
504 if (x instanceof Number) { | 498 if (x instanceof Number) { |
505 n = (Number)x; | 499 n = (Number) x; |
506 } | 500 } else if (x instanceof String) { |
507 else if (x instanceof String) { | |
508 try { | 501 try { |
509 n = Double.valueOf((String)x); | 502 n = Double.valueOf((String) x); |
510 } | 503 } |
511 catch (NumberFormatException nfe) { | 504 catch (final NumberFormatException nfe) { |
512 log.warn("'" + x + "' is not a number."); | 505 log.warn("'" + x + "' is not a number."); |
513 continue; | 506 continue; |
514 } | 507 } |
515 } | 508 } else { |
516 else { | |
517 log.warn("'" + x + "' is not a number."); | 509 log.warn("'" + x + "' is not a number."); |
518 continue; | 510 continue; |
519 } | 511 } |
520 | 512 |
521 double v = n.doubleValue(); | 513 final double v = n.doubleValue(); |
522 | 514 |
523 if (v > max) { | 515 if (v > max) { |
524 max = v; | 516 max = v; |
525 } | 517 } |
526 } | 518 } |
527 | 519 |
528 return Double.valueOf(max == -Double.MAX_VALUE | 520 return Double.valueOf(max == -Double.MAX_VALUE ? Double.MAX_VALUE : max); |
529 ? Double.MAX_VALUE | 521 } |
530 : max); | 522 |
531 } | 523 return list instanceof Number ? (Number) list : Double.valueOf(Double.MAX_VALUE); |
532 | 524 } |
533 return list instanceof Number | 525 |
534 ? (Number)list | 526 public static Number minNumber(final Object list) { |
535 : Double.valueOf(Double.MAX_VALUE); | |
536 } | |
537 | |
538 public static Number minNumber(Object list) { | |
539 if (list instanceof Collection) { | 527 if (list instanceof Collection) { |
540 Collection collection = (Collection)list; | 528 final Collection collection = (Collection) list; |
541 double min = Double.MAX_VALUE; | 529 double min = Double.MAX_VALUE; |
542 for (Object x: collection) { | 530 for (final Object x : collection) { |
543 Number n; | 531 Number n; |
544 if (x instanceof Number) { | 532 if (x instanceof Number) { |
545 n = (Number)x; | 533 n = (Number) x; |
546 } | 534 } else if (x instanceof String) { |
547 else if (x instanceof String) { | |
548 try { | 535 try { |
549 n = Double.valueOf((String)x); | 536 n = Double.valueOf((String) x); |
550 } | 537 } |
551 catch (NumberFormatException nfe) { | 538 catch (final NumberFormatException nfe) { |
552 log.warn("'" + x + "' is not a number."); | 539 log.warn("'" + x + "' is not a number."); |
553 continue; | 540 continue; |
554 } | 541 } |
555 } | 542 } else { |
556 else { | |
557 log.warn("'" + x + "' is not a number."); | 543 log.warn("'" + x + "' is not a number."); |
558 continue; | 544 continue; |
559 } | 545 } |
560 | 546 |
561 double v = n.doubleValue(); | 547 final double v = n.doubleValue(); |
562 | 548 |
563 if (v < min) { | 549 if (v < min) { |
564 min = v; | 550 min = v; |
565 } | 551 } |
566 } | 552 } |
567 | 553 |
568 return Double.valueOf(min == Double.MAX_VALUE | 554 return Double.valueOf(min == Double.MAX_VALUE ? -Double.MAX_VALUE : min); |
569 ? -Double.MAX_VALUE | 555 } |
570 : min); | 556 |
571 } | 557 return list instanceof Number ? (Number) list : Double.valueOf(-Double.MAX_VALUE); |
572 | 558 } |
573 return list instanceof Number | 559 |
574 ? (Number)list | 560 public static Object coalesce(final List list) { |
575 : Double.valueOf(-Double.MAX_VALUE); | 561 for (final Object x : list) { |
576 } | 562 if (x instanceof String && ((String) x).length() != 0) { |
577 | |
578 public static Object coalesce(List list) { | |
579 for (Object x: list) { | |
580 if (x instanceof String && ((String)x).length() != 0) { | |
581 return x; | 563 return x; |
582 } | 564 } |
583 if (x instanceof Number && ((Number)x).doubleValue() != 0.0) { | 565 if (x instanceof Number && ((Number) x).doubleValue() != 0.0) { |
584 return x; | 566 return x; |
585 } | 567 } |
586 } | 568 } |
587 return StackFrames.NULL; | 569 return StackFrames.NULL; |
588 } | 570 } |
589 | 571 |
590 private Object column(Object argument) { | 572 private Object column(final Object argument) { |
591 | 573 |
592 if( !(argument instanceof String) ) | 574 if (!(argument instanceof String)) |
593 throw new IllegalArgumentException("Argument of 'column' function must be a string"); | 575 throw new IllegalArgumentException("Argument of 'column' function must be a string"); |
594 | 576 |
595 String columnName = (String) argument; | 577 final String columnName = (String) argument; |
596 | 578 |
597 StackFrames frms = buildHelper.frames; | 579 final StackFrames frms = this.buildHelper.frames; |
598 | 580 |
599 return frms.getNull(columnName); | 581 return frms.getNull(columnName); |
600 } | 582 } |
601 } | 583 } |
602 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : | 584 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : |