All Downloads are FREE. Search and download functionalities are using the official Maven repository.

prompto.value.IterableValue Maven / Gradle / Ivy

The newest version!
package prompto.value;

import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

import prompto.error.PromptoError;
import prompto.error.ReadWriteError;
import prompto.expression.IExpression;
import prompto.grammar.Identifier;
import prompto.intrinsic.Filterable;
import prompto.intrinsic.IterableWithCounts;
import prompto.intrinsic.PromptoList;
import prompto.runtime.Context;
import prompto.runtime.Variable;
import prompto.type.IType;
import prompto.type.IntegerType;
import prompto.type.IteratorType;
import prompto.type.ListType;
import prompto.type.TextType;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;

public class IterableValue extends BaseValue implements IIterable, IterableWithCounts, IFilterable {

	IType sourceType;
	Context context;
	Identifier name;
	IterableWithCounts iterable;
	IExpression expression;
	
	public IterableValue(Context context, Identifier name, IType sourceType, 
			IterableWithCounts iterable, IExpression expression, IType resultType) {
		super(new IteratorType(resultType));
		this.sourceType = sourceType;
		this.context = context;
		this.name = name;
		this.iterable = iterable;
		this.expression = expression;
	}
	
	@Override
	public String toString() {
		return StreamSupport.stream(this.spliterator(), false)
				.map(IValue::toString)
				.collect(Collectors.joining(", "));
	}

	@Override
	public Long getCount() {
		return iterable.getCount();
	}
	
	@Override
	public Long getTotalCount() {
		return iterable.getTotalCount();
	}

	@Override
	public IterableWithCounts getIterable(Context context) {
		return this;
	}

	@Override 
	public Iterator iterator() {
		return new Iterator() {
			
			Iterator iterator = iterable.iterator();
			
			@Override
			public boolean hasNext() {
				return iterator.hasNext();
			}
			
			@Override
			public IValue next() {
				try {
					Context child = context.newChildContext();
					child.registerInstance(new Variable(name, sourceType));
					child.setValue(name, iterator.next());
					return expression.interpret(child);
				} catch (PromptoError e) {
					throw new RuntimeException(e);
				}
			}
		};
	}
	
	@Override
	public Filterable getFilterable(Context context) {
		return new Filterable() {
			@Override
			public IValue filter(Predicate predicate) {
				PromptoList filtered = new PromptoList(false);
				for(IValue value : getIterable(context)) {
					if(predicate.test(value))
						filtered.add(value);
				}
				return new ListValue(sourceType, filtered);
			}

		};
	}
	
	@Override
	public IValue getMember(Context context, Identifier id, boolean autoCreate) throws PromptoError {
		String name = id.toString();
		if ("count".equals(name))
			return new IntegerValue(iterable.getCount());
		else
			return super.getMember(context, id, autoCreate);
	}
	
	
	@Override
	public JsonNode valueToJsonNode(Context context, Function producer) throws PromptoError {
		ObjectNode result = JsonNodeFactory.instance.objectNode();
		ObjectNode value = JsonNodeFactory.instance.objectNode();
		value.put("typeName", TextType.instance().getTypeName());
		value.put("value", sourceType.getTypeName());
		result.set("itemTypeName", value);
		value = JsonNodeFactory.instance.objectNode();
		value.put("typeName", IntegerType.instance().getTypeName());
		value.put("value", iterable.getCount());
		result.set("count", value);
		value = JsonNodeFactory.instance.objectNode();
		value.put("typeName", IntegerType.instance().getTypeName());
		value.put("value", iterable.getTotalCount());
		result.set("totalCount", value);
		return result;
	}

	@Override
	public void toJsonStream(Context context, JsonGenerator generator, boolean withType, Map data) throws PromptoError {
		try {
			if(withType) {
				generator.writeStartObject();
				generator.writeFieldName("type");
				// serialize Cursor as list
				IType type = new ListType(((IteratorType)getType()).getItemType());
				generator.writeString(type.getTypeName());
				generator.writeFieldName("value");
			}
			generator.writeStartArray();
			Iterator iter = iterator();
			while(iter.hasNext())
				iter.next().toJsonStream(context, generator, withType, data);
			generator.writeEndArray();
			if(withType)
				generator.writeEndObject();
		} catch(IOException e) {
			throw new ReadWriteError(e.getMessage());
		}
	}

	
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy