ContinuousChangesDriver.java :  » CouchDB » jcouchdb » org » jcouchdb » db » Java Open Source

Java Open Source » CouchDB » jcouchdb 
jcouchdb » org » jcouchdb » db » ContinuousChangesDriver.java
/**
 * 
 */
package org.jcouchdb.db;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.SocketException;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.commons.io.IOUtils;
import org.jcouchdb.document.ChangeListener;
import org.jcouchdb.document.ChangeNotification;
import org.jcouchdb.document.HeartBeatListener;
import org.jcouchdb.util.ExceptionWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.svenson.JSONParser;

class ContinuousChangesDriver
    extends Thread
{
    private final static AtomicInteger driverCount = new AtomicInteger();

    private static Logger log = LoggerFactory.getLogger(ContinuousChangesDriver.class);

    private String filter;

    private Long since;

    private Options options;

    private ChangeListener listener;

    private Database db;


    public ContinuousChangesDriver(Database db, String filter, Long since, Options options,
        ChangeListener listener)
    {
        super("ContinuousChangesDriver-" + driverCount.incrementAndGet());

        this.db = db;
        this.filter = filter;
        this.since = since;
        this.options = options;
        this.listener = listener;
    }


    @Override
    public void run()
    {
        synchronized(this)
        {
            this.notifyAll();
        }

        log.info("ContinuousChangesDriver started.");
        
        Response response = null;

        options = db.getCommonChangesOptions(filter, since, options);
        options.putUnencoded("feed", "continuous");

        InputStream ir = null;

        while (!db.getServer().isShutdown())
        {
            log.debug("driver loop");
            try
            {
                log.info(
                    "Sending continuous change request. filter = {}, since = {}, options = {}",
                    new Object[] { filter, since, options });
                response = db.getServer().get("/" + db.getName() + "/_changes" + options.toQuery());

                ir = response.getInputStream();
                log.debug("input stream = {}", ir);

                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                
                while (!db.getServer().isShutdown())
                {
                    int c = ir.read();
                    if (c == -1)
                    {
                        throw new IllegalStateException("Unexpected EOF");
                    }

                    if (c == '\n')
                    {
                        convertRawData(bos.toByteArray());
                        bos.reset();
                    }
                    else
                    {
                        bos.write(c);
                    }
                }
            }
            catch(SocketException e)
            {
                log.debug("SocketException listening to continuous changes");
            }
            catch (Exception e)
            {
                log.info("Error listening to continuous changes", e);
            }
            finally
            {
                if (ir != null)
                {
                    IOUtils.closeQuietly(ir);
                    ir = null;
                }

                if (response != null)
                {
                    response.destroy();
                }
            }
        }
    }


    private void convertRawData(byte[] byteArray)
    {
        if (byteArray.length > 0)
        {
            try
            {
                String json = new String(byteArray, "UTF-8");
                log.debug("received notification JSON = {}", json);
                ChangeNotification changeNotification = JSONParser.defaultJSONParser().parse(ChangeNotification.class, json);
                listener.onChange(changeNotification);
            }
            catch (UnsupportedEncodingException e)
            {
                throw ExceptionWrapper.wrap(e);
            }
        }
        else
        {
            log.debug("received heartbeat");
            if (listener instanceof HeartBeatListener)
            {
                ((HeartBeatListener)listener).heartbeat();
            }
        }
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.