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

prompto.value.CursorValue Maven / Gradle / Ivy

The newest version!
package prompto.value;

import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Predicate;

import prompto.error.PromptoError;
import prompto.error.ReadWriteError;
import prompto.error.SyntaxError;
import prompto.grammar.Identifier;
import prompto.intrinsic.Filterable;
import prompto.intrinsic.IterableWithCounts;
import prompto.intrinsic.PromptoList;
import prompto.runtime.Context;
import prompto.store.IStored;
import prompto.store.IStoredIterable;
import prompto.type.CategoryType;
import prompto.type.CursorType;
import prompto.type.IType;
import prompto.type.IntegerType;
import prompto.type.IterableType;
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 CursorValue extends BaseValue implements IIterable, IterableWithCounts, IFilterable {

	Context context;
	IStoredIterable iterable;
	boolean mutable;
	
	public CursorValue(Context context, IType itemType, IStoredIterable documents) {
		super(new CursorType(itemType));
		this.context = context;
		this.iterable = documents;
		this.mutable = itemType instanceof CategoryType ? ((CategoryType)itemType).isMutable() : false;
	}

	@Override
	public Object getStorableData() {
		throw new UnsupportedOperationException(); // can't be stored
	}
	
	
	public IType getItemType() {
		return ((CursorType)getType()).getItemType();
	}

	
	@Override
	public Long getCount() {
		return iterable.count();
	}
	
	@Override
	public Long getTotalCount() {
		return iterable.totalCount();
	}
	
	// GraphQL accessor
	public Iterable getItems() {
		return this;
	}

	@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 {
					IStored stored = iterator.next();
					CategoryType itemType = readItemType(stored);
					IValue value = itemType.newInstance(context, stored);
					if(value!=null)
						return value;
					if(type!=null) {
						itemType = (CategoryType)((IterableType)type).getItemType();
						value = itemType.newInstance(context, stored);
					}
					if(value!=null)
						return value;
					else if(hasNext())
						return next();
					else
						return NullValue.instance();
				} catch (PromptoError e) {
					throw new RuntimeException(e);
				}
			}
		};
	}
	
	@SuppressWarnings("unchecked")
	private CategoryType readItemType(IStored stored) throws PromptoError {
		Object value = stored.getData("category");
		if(value instanceof List) {
			List categories = (List)value;
			String category = categories.get(categories.size()-1);
			CategoryType type = new CategoryType(new Identifier(category));
			type.setMutable(this.mutable);
			return type;
		} else if(type!=null)
			return (CategoryType)((IterableType)type).getItemType();
		else
			return null;
	}

	@Override
	public IValue getMember(Context context, Identifier id, boolean autoCreate) {
		String name = id.toString();
		if ("count".equals(name))
			return new IntegerValue(getCount());
		else if ("totalCount".equals(name))
			return new IntegerValue(getTotalCount());
		else
			throw new SyntaxError("No such member:" + name);
	}
	
	@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", getItemType().getTypeName());
		result.set("itemTypeName", value);
		value = JsonNodeFactory.instance.objectNode();
		value.put("typeName", IntegerType.instance().getTypeName());
		value.put("value", iterable.count());
		result.set("count", value);
		value = JsonNodeFactory.instance.objectNode();
		value.put("typeName", IntegerType.instance().getTypeName());
		value.put("value", iterable.totalCount());
		result.set("totalCount", value);
		return result;
	}

	@Override
	public void toJsonStream(Context context, JsonGenerator generator, boolean withType, Map data) {
		try {
			if(withType) {
				generator.writeStartObject();
				generator.writeStringField("type", type.getTypeName());
				generator.writeFieldName("value");
			}
			generator.writeStartObject();
			generator.writeFieldName("mutable");
			generator.writeBoolean(mutable);
			generator.writeFieldName("count");
			generator.writeNumber(iterable.count());
			generator.writeFieldName("totalCount");
			generator.writeNumber(iterable.totalCount());
			generator.writeFieldName("items");
			generator.writeStartArray();
			Iterator iter = iterator();
			while(iter.hasNext())
				iter.next().toJsonStream(context, generator, withType, data);
			generator.writeEndArray();
			generator.writeEndObject();
			if(withType)
				generator.writeEndObject();
		} catch(IOException e) {
			throw new ReadWriteError(e.getMessage());
		}
	}

	@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(getItemType(), filtered);
			}
		};
	}
	
	public IValue toListValue() {
		ListValue values = new ListValue(this.getItemType());
		for(IValue item : this)
			values.addItem(item);
		return values;
	}



}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy