Package com.buschmais.xo.impl.query

Source Code of com.buschmais.xo.impl.query.QueryResultIterableImpl

package com.buschmais.xo.impl.query;

import com.buschmais.xo.api.Query;
import com.buschmais.xo.api.ResultIterator;
import com.buschmais.xo.api.XOException;
import com.buschmais.xo.impl.AbstractResultIterable;
import com.buschmais.xo.impl.SessionContext;
import com.buschmais.xo.impl.proxy.query.RowInvocationHandler;
import com.buschmais.xo.impl.proxy.query.RowProxyMethodService;
import com.buschmais.xo.spi.annotation.QueryDefinition;
import com.buschmais.xo.spi.reflection.AnnotatedType;

import java.io.IOException;
import java.util.*;

class QueryResultIterableImpl<Entity, Relation, T> extends AbstractResultIterable<T> implements Query.Result<T> {

    private final SessionContext<?, Entity, ?, ?, ?, Relation, ?, ?> sessionContext;
    private final ResultIterator<Map<String, Object>> iterator;
    private final SortedSet<Class<?>> returnTypes;
    private final RowProxyMethodService rowProxyMethodService;

    QueryResultIterableImpl(SessionContext<?, Entity, ?, ?, ?, Relation, ?, ?> sessionContext,
                            ResultIterator<Map<String, Object>> iterator, Class<?> returnType, SortedSet<Class<?>> returnTypes) {
        this.sessionContext = sessionContext;
        this.iterator = iterator;
        this.returnTypes = returnTypes;
        if (CompositeRowObject.class.equals(returnType) || new AnnotatedType(returnType).getByMetaAnnotation(QueryDefinition.class) != null) {
            this.rowProxyMethodService = new RowProxyMethodService(returnTypes);
        } else {
            this.rowProxyMethodService = null;
        }
    }

    @Override
    public ResultIterator<T> iterator() {
        return new ResultIterator<T>() {

            @Override
            public boolean hasNext() {
                return iterator.hasNext();
            }

            @Override
            public T next() {
                Map<String, Object> next = iterator.next();
                Map<String, Object> row = new LinkedHashMap<>();
                for (Map.Entry<String, Object> entry : next.entrySet()) {
                    String column = entry.getKey();
                    Object value = entry.getValue();
                    Object decodedValue = decodeValue(value);
                    row.put(column, decodedValue);
                }
                if (rowProxyMethodService != null) {
                    RowInvocationHandler invocationHandler = new RowInvocationHandler(row, rowProxyMethodService);
                    return (T) sessionContext.getProxyFactory().createInstance(invocationHandler, returnTypes.toArray(new Class<?>[0]), CompositeRowObject.class);
                }
                if (row.size() != 1) {
                    throw new XOException("Only single columns per row can be returned.");
                }
                return (T) row.values().iterator().next();
            }

            @Override
            public void remove() {
                iterator.remove();
            }

            private Object decodeValue(Object value) {
                if (value == null) {
                    return null;
                }
                Object decodedValue;
                if (sessionContext.getDatastoreSession().isEntity(value)) {
                    return sessionContext.getEntityInstanceManager().readInstance((Entity) value);
                } else if (sessionContext.getDatastoreSession().isRelation(value)) {
                    return sessionContext.getRelationInstanceManager().readInstance((Relation) value);
                } else if (value instanceof List<?>) {
                    decodedValue = decodeIterable((Iterable<?>) value, new ArrayList<>());
                } else if (value instanceof Set<?>) {
                    decodedValue = decodeIterable((Iterable<?>) value, new HashSet<>());
                } else if (value instanceof Iterable<?>) {
                    decodedValue = decodeIterable((Iterable<?>) value, new ArrayList<>());
                } else {
                    decodedValue = value;
                }
                return decodedValue;
            }

            private Collection<Object> decodeIterable(Iterable<?> iterable, Collection<Object> decodedCollection) {
                for (Object o : iterable) {
                    decodedCollection.add(decodeValue(o));
                }
                return decodedCollection;
            }

            @Override
            public void close() {
                iterator.close();
            }
        };
    }

    @Override
    public void close() throws IOException {
        iterator.close();
    }
}
TOP

Related Classes of com.buschmais.xo.impl.query.QueryResultIterableImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.