1 /* 2 * scriptable-dataset (https://github.com/hazendaz/scriptable-dataset) 3 * 4 * Copyright 2011-2024 Hazendaz. 5 * 6 * All rights reserved. This program and the accompanying materials 7 * are made available under the terms of The Apache Software License, 8 * Version 2.0 which accompanies this distribution, and is available at 9 * https://www.apache.org/licenses/LICENSE-2.0.txt 10 * 11 * Contributors: 12 * Gunnar Morling 13 * Hazendaz (Jeremy Landis). 14 */ 15 package de.gmorling.scriptabledataset; 16 17 import java.util.Arrays; 18 import java.util.List; 19 import java.util.Objects; 20 21 import org.apache.commons.lang3.Validate; 22 import org.dbunit.dataset.AbstractDataSet; 23 import org.dbunit.dataset.DataSetException; 24 import org.dbunit.dataset.IDataSet; 25 import org.dbunit.dataset.ITableIterator; 26 27 /** 28 * An implementation of a <a href="http://www.dbunit.org/">DBUnit</a> <code>IDataSet</code>, that allows the use of 29 * script expressions in its fields. In order to use a certain scripting language in a scriptable data set, a 30 * <a href="http://jcp.org/en/jsr/detail?id=223">JSR 223</a> ("Scripting for the Java<sup>TM</sup> Platform") 31 * compatible script engine has to exist for that language. 32 * <p> 33 * Using the <a href="http://jruby.org/">JRuby</a> engine e.g., a scriptable data set file could look like this: 34 * 35 * <pre> 36 * <dataset> 37 * <location num="jruby:12/2" addr="jruby:'Webster Street'.reverse" date="jruby:DateTime::now() - 14"/> 38 * </dataset> 39 * </pre> 40 * 41 * A ScriptableDataSet can be created as follows: 42 * 43 * <pre> 44 * IDataSet wrapped = ...; 45 * 46 * List<ScriptInvocationHandler> handlers = new ArrayList<Class<? extends ScriptInvocationHandler>>(); 47 * handlers.add(new JRubyImportAddingInvocationHandler()); 48 * 49 * IDataSet scriptableDS = new ScriptableDataSet( 50 * wrapped, new ScriptableDataSetConfig("jruby", "jruby:", handlers)); 51 * </pre> 52 * 53 * where 54 * <ul> 55 * <li><b>jruby</b> is the name of a scripting language as understood by {@link javax.script.ScriptEngineManager}</li> 56 * <li><b>jruby:</b> is a prefix, that shall precede fields in that scripting language</li> 57 * <li><b>handlers</b> is an optional list of {@link de.gmorling.scriptabledataset.handlers.ScriptInvocationHandler} s, 58 * that can be used to pre-process scripts (e.g. to add common imports) and post-process scripts (e.g. to convert 59 * results into data types understood by DBUnit).</li> 60 * </ul> 61 */ 62 public class ScriptableDataSet extends AbstractDataSet { 63 64 /** The wrapped. */ 65 private IDataSet wrapped; 66 67 /** The configurations. */ 68 private List<ScriptableDataSetConfig> configurations; 69 70 /** 71 * Creates a new ScriptableDataSet. 72 * 73 * @param wrapped 74 * Another data set to be wrapped by this scriptable data set. Must not be null. 75 * @param configurations 76 * At least one scriptable data set configuration. 77 */ 78 public ScriptableDataSet(IDataSet wrapped, ScriptableDataSetConfig... configurations) { 79 80 Objects.requireNonNull(wrapped); 81 82 Objects.requireNonNull(configurations); 83 Validate.noNullElements(configurations); 84 Validate.notEmpty(configurations); 85 86 this.wrapped = wrapped; 87 this.configurations = Arrays.asList(configurations); 88 } 89 90 @Override 91 protected ITableIterator createIterator(boolean reversed) throws DataSetException { 92 return new ScriptableIterator(reversed ? wrapped.reverseIterator() : wrapped.iterator(), configurations); 93 } 94 95 }