org.etlunit.feature.file.FileFeatureModule Maven / Gradle / Ivy
package org.etlunit.feature.file;
import com.google.inject.Binder;
import com.google.inject.Injector;
import com.google.inject.Module;
import org.etlunit.*;
import org.etlunit.context.VariableContext;
import org.etlunit.feature.AbstractFeature;
import org.etlunit.feature.FeatureModule;
import org.etlunit.feature.assertion.AssertionFeatureModule;
import org.etlunit.io.FileBuilder;
import org.etlunit.parser.*;
import org.etlunit.util.JSonBuilderProxy;
import javax.inject.Inject;
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Staged file objects look like this:
* fileContext_[contextName] [
* {
* file: '/path/to/file'
* (, classifier: 'variableName')?
* (, destination-name: 'destinationName')?
* }(,{ . . . })*
* ]
*
* If this is the default context, then the variable name will be fileContext_DEFAULT.
* Where file is the path to the file to be utilized, and classifier is a meaning that is specific to the file consumer.
*/
@FeatureModule
public class FileFeatureModule extends AbstractFeature
{
private static final List prerequisites = Arrays.asList("logging", "assertion");
private static final String CONTEXT_PREFIX = "fileContext[";
private static final String CONTEXT_POSTFIX = "]";
private static final String DEFAULT_CONTEXT_NAME = "DEFAULT";
private AssertionFeatureModule assertionFeatureModule;
private final FileRuntimeSupport fileRuntimeSupport = new FileRuntimeSupportImpl();
private final class StageHandler extends NullClassListener implements StageOperationProcessor
{
public action_code processStage(StageOperation operation, ETLTestOperation op, ETLTestValueObject obj, VariableContext context, ExecutionContext econtext) throws TestAssertionFailure, TestExecutionError, TestWarning
{
String file = operation.getFile();
String listFile = operation.getListFile();
if (file == null)
{
if (listFile == null)
{
throw new IllegalArgumentException("Either one of " + StageOperation.LISTFILE_JSON_NAME + " or " + StageOperation.FILE_JSON_NAME + " must be specified");
}
file = listFile;
}
List fileNames = new ArrayList();
fileNames.add(file);
String package_ = op.getTestMethod().getTestClass().getPackage();
if (listFile != null)
{
// blast all names contained in the list file into the context
File source = fileRuntimeSupport.getDataFile(package_, listFile);
try
{
BufferedReader bufferedReader = new BufferedReader(new FileReader(source));
try
{
String str = null;
while ((str = bufferedReader.readLine()) != null)
{
fileNames.add(str);
}
}
finally
{
bufferedReader.close();
}
}
catch (IOException e)
{
throw new TestExecutionError("List file does not exist", e);
}
}
String var = operation.getVariableName();
for (int i = 0; i < fileNames.size(); i++)
{
String fileName = fileNames.get(i);
File source = fileRuntimeSupport.getDataFile(package_, fileName);
// Set the file variable. For list files this will be @var for the first, and @var-2..n for the second on (1-based numbering)
if (var != null)
{
context.declareAndSetStringValue(var + (i == 0 ? "" : ("-" + (i + 1))), fileName);
}
String classifier = operation.getClassifier();
JSonBuilderProxy proxy = new JSonBuilderProxy().object().key("file").value(source.getAbsolutePath());
if (classifier != null)
{
proxy = proxy.key("classifier").value(classifier);
}
String destinationName = operation.getDestinationName();
if (destinationName != null)
{
proxy = proxy.key("destination-name").value(destinationName);
}
String str = proxy.endObject().toString();
ETLTestValueObject co = getFileContext(obj, context);
if (co != null)
{
// this will be an array of objects. We need to add another to the end
try
{
co.getValueAsList().add(ETLTestParser.loadObject(str));
}
catch (ParseException e)
{
throw new IllegalArgumentException(e);
}
}
else
{
setFileContext(obj, context, "[" + str + "]");
}
}
return action_code.handled;
}
}
private final StageHandler stageHandler = new StageHandler();
@Override
public void initialize(Injector inj)
{
assertionFeatureModule.extend(postCreate(new FileAssertExtender(this)));
}
@Override
protected Injector preCreateSub(Injector inj)
{
return inj.createChildInjector(new Module()
{
public void configure(Binder binder)
{
binder.bind(FileRuntimeSupport.class).toInstance(fileRuntimeSupport);
}
});
}
@Inject
public void setAssertionFeature(AssertionFeatureModule f)
{
assertionFeatureModule = f;
}
@Override
public List getPrerequisites()
{
return prerequisites;
}
@Override
protected List getSupportedFolderNamesSub()
{
return Arrays.asList("files");
}
public String getFeatureName()
{
return "file";
}
@Override
public ClassListener getListener()
{
return stageHandler;
}
private static String getFileContextId(ETLTestValueObject param)
{
ETLTestValueObject contextNameObj = param.query("context-name");
String contextName = null;
if (contextNameObj != null)
{
contextName = contextNameObj.getValueAsString();
}
return getContextKey(contextName);
}
private static void setFileContext(ETLTestValueObject param, VariableContext vcontext, String json)
{
String fileContextId = getFileContextId(param);
if (!vcontext.hasVariableBeenDeclared(fileContextId))
{
try
{
vcontext.declareAndSetValue(fileContextId, ETLTestParser.loadObject("{}"));
}
catch (ParseException e)
{
throw new RuntimeException(e);
}
}
ETLTestValueObject fcontext = getFileContextContainer(param, vcontext);
new ETLTestValueObjectBuilder(fcontext).key("file-list").jsonValue(json);
}
public static ETLTestValueObject getFileContext(ETLTestValueObject param, VariableContext vcontext)
{
ETLTestValueObject context = getFileContextContainer(param, vcontext);
if (context != null)
{
return context.query("file-list");
}
return null;
}
public static ETLTestValueObject getFileContextContainer(ETLTestValueObject param, VariableContext vcontext)
{
String contextKey = getFileContextId(param);
if (vcontext.hasVariableBeenDeclared(contextKey))
{
return vcontext.getValue(contextKey);
}
return null;
}
/**
* @param id - null for default context
* @return
*/
private static String getContextKey(String id)
{
return CONTEXT_PREFIX + (id == null ? DEFAULT_CONTEXT_NAME : id) + CONTEXT_POSTFIX;
}
}