/**
* 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();
}
}