/* * Copyright 2012 The Java HandlerSocket Connection Project * * https://github.com/komelgman/Java-HandlerSocket-Connection/ * * The Project licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package kom.handlersocket; import kom.handlersocket.core.SafeByteStream; import kom.handlersocket.query.HSQuery; import kom.handlersocket.result.HSResult; import kom.handlersocket.result.HSResultFuture; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelFuture; import java.nio.charset.Charset; import java.util.*; public class HSConnection { private Charset charset; private Channel channel; private final LinkedList<HSResultFuture> pendingResults = new LinkedList<HSResultFuture>(); private final LinkedList<PendingQueries> pendingQueries = new LinkedList<PendingQueries>(); private HSResultFuture currentResultFuture = null; public HSConnection() { this(Charset.defaultCharset()); } public HSConnection(Charset charset) { this.charset = charset; } public HSConnection addQuery(HSIndexDescriptor indexDescriptor, HSQuery query) { return addQueries(indexDescriptor, Arrays.asList(query)); } public HSConnection addQueries(HSIndexDescriptor indexDescriptor, final HSQuery... queries) { return addQueries(indexDescriptor, Arrays.asList(queries)); } public HSConnection addQueries(HSIndexDescriptor indexDescriptor, final List<? extends HSQuery> queries) { synchronized (pendingQueries) { pendingQueries.add(new PendingQueries(indexDescriptor, queries)); } return this; } public HSResultFuture execute() { final LinkedList<PendingQueries> pendingQueries = getPendingQueries(); final SafeByteStream packet = new SafeByteStream(pendingQueries.size() * 64, 65536, charset); final LinkedList<HSResult> resultSet = new LinkedList<HSResult>(); for (PendingQueries entry : pendingQueries) { for (HSQuery query : entry.queries) { resultSet.add(new HSResult(entry.indexDescriptor, query.resultType(), charset)); query.encode(entry.indexDescriptor, packet); } } final HSResultFuture resultFuture = new HSResultFuture(resultSet); synchronized (pendingResults) { pendingResults.addFirst(resultFuture); channel.write(packet); } return resultFuture; } private LinkedList<PendingQueries> getPendingQueries() { final LinkedList<PendingQueries> result; synchronized (pendingQueries) { result = (LinkedList<PendingQueries>)pendingQueries.clone(); pendingQueries.clear(); } return result; } public void response(List<List<ChannelBuffer>> data) { synchronized (pendingResults) { for (List<ChannelBuffer> entity : data) { if (currentResultFuture == null || currentResultFuture.isReady()) { currentResultFuture = pendingResults.removeLast(); } currentResultFuture.addResult(entity); } } } public void setChannel(Channel channel) { this.channel = channel; } public Channel getChannel() { return channel; } public ChannelFuture close() { return channel.close(); } public Charset getCharset() { return charset; } public void setCharset(Charset charset) { this.charset = charset; } private class PendingQueries { public final HSIndexDescriptor indexDescriptor; public final List<? extends HSQuery> queries; public PendingQueries(HSIndexDescriptor indexDescriptor, List<? extends HSQuery> queries) { this.indexDescriptor = indexDescriptor; this.queries = queries; } } }