/** * Copyright (C) 2010-2012, FuseSource Corp. All rights reserved. * * http://fusesource.com * * Licensed 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 org.fusesource.mqtt.client; import org.fusesource.hawtbuf.Buffer; import org.fusesource.hawtbuf.UTF8Buffer; import org.fusesource.hawtdispatch.Task; import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicLong; import static org.fusesource.hawtbuf.Buffer.utf8; /** * <p> * A blocking Connection interface to MQTT. * </p> * * @author <a href="http://hiramchirino.com">Hiram Chirino</a> */ public class BlockingConnection { private final FutureConnection next; public BlockingConnection(FutureConnection next) { this.next = next; } public boolean isConnected() { return next.isConnected(); } public void connect() throws Exception { this.next.connect().await(); } public void disconnect() throws Exception { this.next.disconnect().await(); } public void kill() throws Exception { this.next.kill().await(); } public byte[] subscribe(final Topic[] topics) throws Exception { return this.next.subscribe(topics).await(); } public void unsubscribe(final String[] topics) throws Exception { this.next.unsubscribe(topics).await(); } public void unsubscribe(final UTF8Buffer[] topics) throws Exception { this.next.unsubscribe(topics).await(); } public void publish(final UTF8Buffer topic, final Buffer payload, final QoS qos, final boolean retain) throws Exception { this.next.publish(topic, payload, qos, retain).await(); } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); //To change body of overridden methods use File | Settings | File Templates. } public void publish(final String topic, final byte[] payload, final QoS qos, final boolean retain) throws Exception { publish(utf8(topic), new Buffer(payload), qos, retain); } public Message receive() throws Exception { return this.next.receive().await(); } /** * @return null if the receive times out. */ public Message receive(long amount, TimeUnit unit) throws Exception { Future<Message> receive = this.next.receive(); try { Message message = receive.await(amount, unit); if( message!=null ) { message.blocking = true; } return message; } catch (TimeoutException e) { // Put it back on the queue.. receive.then(new Callback<Message>() { public void onSuccess(final Message value) { next.putBackMessage(value); } public void onFailure(Throwable value) { } }); return null; } } public void setReceiveBuffer(final long receiveBuffer) throws InterruptedException { final CountDownLatch done = new CountDownLatch(1); next.getDispatchQueue().execute(new Runnable() { public void run() { try { next.setReceiveBuffer(receiveBuffer); } finally { done.countDown(); } } }); done.await(); } public long getReceiveBuffer() throws InterruptedException { final CountDownLatch done = new CountDownLatch(1); final AtomicLong result = new AtomicLong(); next.getDispatchQueue().execute(new Runnable() { public void run() { try { result.set(next.getReceiveBuffer()); } finally { done.countDown(); } } }); done.await(); return result.get(); } public void resume() { next.resume(); } public void suspend() { next.suspend(); } }