@@ -0,0 +1,1860 @@
+package de.felixbruns.jotify.protocol.channel;%0A%0Aimport java.nio.charset.Charset;%0Aimport java.util.ArrayList;%0Aimport java.util.Arrays;%0Aimport java.util.List;%0Aimport java.util.concurrent.Semaphore;%0Aimport java.util.concurrent.TimeUnit;%0Aimport java.util.concurrent.TimeoutException;%0A%0Apublic class ChannelHeaderCallback implements ChannelListener %7B%0A%09private Semaphore    done;%0A%09private List%3CString%3E urls;%0A%09%0A%09public ChannelHeaderCallback()%7B%0A%09%09this.done = new Semaphore(1);%0A%09%09this.urls = new ArrayList%3CString%3E();%0A%09%09%0A%09%09this.done.acquireUninterruptibly();%0A%09%7D%0A%09%0A%09public void channelHeader(Channel channel, byte%5B%5D header)%7B%0A%09%09/* HTTP stream. */%0A%09%09if(header%5B0%5D == 0x07)%7B%0A%09%09%09/* header%5B1%5D contains number of stream part. */%0A%09%09%09this.urls.add(new String(%0A%09%09%09%09Arrays.copyOfRange(header, 2, header.length),%0A%09%09%09%09Charset.forName(%22UTF-8%22)%0A%09%09%09));%0A%09%09%7D%0A%09%7D%0A%09%0A%09public void channelData(Channel channel, byte%5B%5D data)%7B%0A%09%09/* Ignore */%0A%09%7D%0A%09%0A%09public void channelEnd(Channel channel)%7B%0A%09%09Channel.unregister(channel.getId());%0A%09%09%0A%09%09this.done.release();%0A%09%7D%0A%09%0A%09public void channelError(Channel channel)%7B%0A%09%09this.done.release();%0A%09%7D%0A%09%0A%09private List%3CString%3E getData()%7B%0A%09%09/* Return HTTP stream URLs. */%0A%09%09return this.urls;%0A%09%7D%0A%09%0A%09public List%3CString%3E get()%7B%0A%09%09/* Wait for data to become available. */%0A%09%09this.done.acquireUninterruptibly();%0A%0A%09%09/* Return HTTP stream URLs. */%0A%09%09return this.getData();%0A%09%7D%0A%09%0A%09public List%3CString%3E get(long timeout, TimeUnit unit)%7B%0A%09%09/* Wait for data to become available. */%0A%09%09try%7B%0A%09%09%09if(!this.done.tryAcquire(timeout, unit))%7B%0A%09%09%09%09throw new TimeoutException(%22Timeout while waiting for data.%22);%0A%09%09%09%7D%0A%09%09%7D%0A%09%09catch(InterruptedException e)%7B%0A%09%09%09throw new RuntimeException(e);%0A%09%09%7D%0A%09%09catch(TimeoutException e)%7B%0A%09%09%09throw new RuntimeException(e);%0A%09%09%7D%0A%0A%09%09/* Return HTTP stream URLs. */%0A%09%09return this.getData();%0A%09%7D%0A%09%0A%09public boolean isDone()%7B%0A%09%09return this.done.availablePermits() %3E 0;%0A%09%7D%0A%7D%0A

Add ChannelHeaderCallback. Needed for HTTP streaming.