org.etlunit.parser.ETLTestValueObjectBuilder Maven / Gradle / Ivy
package org.etlunit.parser;
import java.util.*;
public class ETLTestValueObjectBuilder
{
enum stack_type
{
list,
map
}
enum value_type
{
valueObject,
string,
pojo,
json
}
class StackItem
{
final Map mapContext;
final List listContext;
final String myAttributeName;
final stack_type type;
StackItem(List list)
{
mapContext = null;
listContext = list;
myAttributeName = null;
type = stack_type.list;
}
StackItem(Map map)
{
mapContext = map;
listContext = null;
myAttributeName = null;
type = stack_type.map;
}
StackItem(stack_type type, String attributeName)
{
this.type = type;
this.myAttributeName = attributeName;
switch (type)
{
case list:
listContext = new ArrayList();
mapContext = null;
break;
case map:
listContext = null;
mapContext = new HashMap();
break;
default:
throw new IllegalArgumentException();
}
}
}
private final LinkedList stack = new LinkedList();
private String currentAttributeName = null;
private final ETLTestValueObject base;
public ETLTestValueObjectBuilder()
{
base = null;
}
public ETLTestValueObjectBuilder(ETLTestValueObject base)
{
this.base = base;
switch (base.getValueType())
{
case quoted_string:
throw new IllegalArgumentException("Cannot extend a string value");
case object:
stack.add(new StackItem(base.getValueAsMap()));
break;
case list:
stack.add(new StackItem(base.getValueAsList()));
break;
case literal:
throw new IllegalArgumentException("Cannot extend a string value");
case pojo:
throw new IllegalArgumentException("Cannot extend a pojo value");
}
}
public ETLTestValueObjectBuilder object()
{
stack.push(new StackItem(stack_type.map, currentAttributeName));
currentAttributeName = null;
return this;
}
public ETLTestValueObjectBuilder list()
{
stack.push(new StackItem(stack_type.list, currentAttributeName));
currentAttributeName = null;
return this;
}
public ETLTestValueObjectBuilder key(String name)
{
if (stack.size() == 0)
{
throw new IllegalStateException("Builder does not have a current state");
}
else if (currentAttributeName != null)
{
throw new IllegalStateException("Builder already has a key context");
}
else if (stack.peek().type == stack_type.list)
{
throw new IllegalStateException("Lists do not have keys");
}
else
{
StackItem si = stack.peek();
if (si.type == stack_type.map && si.mapContext.containsKey(name))
{
throw new IllegalStateException("Key name '" + name + "' has already been used in this context");
}
}
currentAttributeName = name;
return this;
}
public ETLTestValueObjectBuilder removeKey(String name)
{
if (stack.size() == 0)
{
throw new IllegalStateException("Builder does not have a current state");
}
else if (currentAttributeName != null)
{
throw new IllegalStateException("Builder already has a key context");
}
else if (stack.peek().type == stack_type.list)
{
throw new IllegalStateException("Lists do not have keys");
}
else
{
StackItem si = stack.peek();
if (si.type == stack_type.map && !si.mapContext.containsKey(name))
{
throw new IllegalStateException("Key name '" + name + "' does not exist in this context");
}
si.mapContext.remove(name);
}
return this;
}
public boolean hasKey(String name)
{
if (stack.size() == 0)
{
throw new IllegalStateException("Builder does not have a current state");
}
else if (stack.peek().type == stack_type.list)
{
throw new IllegalStateException("Lists do not have keys");
}
else
{
StackItem si = stack.peek();
if (si.type == stack_type.map && si.mapContext.containsKey(name))
{
return true;
}
}
return false;
}
public ETLTestValueObjectBuilder value(String val)
{
return value(val, value_type.string);
}
public ETLTestValueObjectBuilder value(ETLTestValueObject val)
{
return value(val, value_type.valueObject);
}
public ETLTestValueObjectBuilder pojoValue(Object val)
{
return value(val, value_type.pojo);
}
public ETLTestValueObjectBuilder jsonValue(Object val)
{
return value(val, value_type.json);
}
private ETLTestValueObjectBuilder value(Object val, value_type type)
{
if (stack.size() == 0)
{
throw new IllegalStateException("Builder does not have a current state");
}
//if the current context is a list, append to the list
StackItem st = stack.peek();
ETLTestValueObject valObj = null;
switch (type)
{
case valueObject:
valObj = (ETLTestValueObject) val;
break;
case string:
valObj = new ETLTestValueObjectImpl((String) val);
break;
case pojo:
valObj = new ETLTestValueObjectImpl(val);
break;
case json:
try
{
valObj = ETLTestParser.loadObject((String) val);
}
catch (ParseException e)
{
throw new IllegalArgumentException("Json object is not valid");
}
break;
}
if (st.type == stack_type.list)
{
st.listContext.add(valObj);
}
else if (currentAttributeName == null)
{
throw new IllegalStateException("Values on objects need a key value first");
}
else
{
st.mapContext.put(currentAttributeName, valObj);
// key value can only be used once
currentAttributeName = null;
}
return this;
}
public ETLTestValueObjectBuilder endList()
{
StackItem st = stack.peek();
// if the list is our only context, do nothing
if (st.type == stack_type.map)
{
throw new IllegalStateException("Object not in context");
}
else if (stack.size() == 1)
{
return this;
}
// pop the list and decide what to do with it
st = stack.pop();
ETLTestValueObjectImpl valueObject = new ETLTestValueObjectImpl(st.listContext);
// if the next item down is a list, then add this item onto that list
StackItem enclosing = stack.peek();
if (enclosing.type == stack_type.list)
{
enclosing.listContext.add(valueObject);
}
else if (st.myAttributeName == null)
{
throw new IllegalStateException("List needs a key name");
}
else
{
// we must have a key to map this element to
enclosing.mapContext.put(st.myAttributeName, valueObject);
}
return this;
}
public ETLTestValueObjectBuilder endObject()
{
StackItem child = stack.peek();
//if this is the root object, do nothing
if (currentAttributeName != null)
{
throw new IllegalStateException("Key " + currentAttributeName + " has not ben given a value");
}
else if (child.type == stack_type.list)
{
throw new IllegalStateException("Object not in context");
}
else if (stack.size() == 1)
{
return this;
}
// pop this element off, and attach this object to it's parent
child = stack.pop();
StackItem parent = stack.peek();
ETLTestValueObjectImpl valueObject = new ETLTestValueObjectImpl(child.mapContext);
// ensure that the child is in fact an object
if (parent.type == stack_type.list)
{
// just add to the end of the list
parent.listContext.add(valueObject);
}
else if (child.myAttributeName == null)
{
throw new IllegalStateException("Object needs a key name");
}
else
{
parent.mapContext.put(child.myAttributeName, valueObject);
}
return this;
}
public ETLTestValueObject toObject()
{
if (stack.size() == 0)
{
throw new IllegalStateException("Builder does not have a current state");
}
StackItem st = stack.peek();
switch (st.type)
{
case list:
return new ETLTestValueObjectImpl(st.listContext);
case map:
return new ETLTestValueObjectImpl(st.mapContext);
default:
throw new IllegalStateException("");
}
}
public ETLTestValueObjectBuilder removeAllKeys(String... keys)
{
for (String key : keys)
{
if (hasKey(key))
{
removeKey(key);
}
}
return this;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy