/* * JBoss, Home of Professional Open Source. * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. Some portions may be licensed * to Red Hat, Inc. under one or more contributor license agreements. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. */ package org.teiid.translator.infinispan.hotrod; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Map; import org.infinispan.client.hotrod.RemoteCache; import org.infinispan.client.hotrod.Search; import org.infinispan.query.dsl.Query; import org.infinispan.query.dsl.QueryFactory; import org.teiid.infinispan.api.InfinispanDocument; import org.teiid.translator.document.DocumentNode; public class InfinispanResponse { private Query query; private int batchSize; private Integer offset; private Integer limit; private boolean lastBatch = false; private Iterator<Object> responseIter; private List<String> projected; private DocumentNode documentNode; private List<Map<String, Object>> currentDocumentRows; public InfinispanResponse(RemoteCache<Object, Object> cache, String queryStr, int batchSize, Integer limit, Integer offset, List<String> projected, DocumentNode documentNode) { this.batchSize = batchSize; this.offset = offset == null?0:offset; this.limit = limit; this.projected = projected; this.documentNode = documentNode; QueryFactory qf = Search.getQueryFactory(cache); this.query = qf.create(queryStr); } private void fetchNextBatch() { query.startOffset(offset); int nextBatch = this.batchSize; if (this.limit != null) { if (this.limit > nextBatch) { this.limit = this.limit - nextBatch; } else { nextBatch = this.limit; this.limit = 0; this.lastBatch = true; } } query.maxResults(nextBatch); List<Object> values = query.list(); if (query.getResultSize() < nextBatch) { this.lastBatch = true; } this.responseIter = values.iterator(); offset = offset + nextBatch; } public List<Object> getNextRow(){ if (this.currentDocumentRows != null && !this.currentDocumentRows.isEmpty()) { return buildRow(this.currentDocumentRows.remove(0)); } if (responseIter == null) { fetchNextBatch(); } if (responseIter != null && responseIter.hasNext()){ Object row = this.responseIter.next(); if (row instanceof Object[]) { return Arrays.asList((Object[])row); } this.currentDocumentRows = this.documentNode.tuples((InfinispanDocument)row); } else { if (lastBatch) { return null; } else { fetchNextBatch(); Object row = this.responseIter.next(); if (row instanceof Object[]) { return Arrays.asList((Object[])row); } this.currentDocumentRows = this.documentNode.tuples((InfinispanDocument)row); } } return getNextRow(); } private List<Object> buildRow(Map<String, Object> row) { ArrayList<Object> result = new ArrayList<>(); for (String attr : this.projected) { result.add(row.get(attr)); } return result; } }