<commit_before>package com.tinkerpop.rexster;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;

import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

/**
 * Manages the socket listening for incoming shutdown requests.
 *
 * Adapted from http://code.google.com/p/shutdown-listener/
 */
public class ShutdownManager {
    protected final Logger logger = Logger.getLogger(this.getClass());
    
    private final CountDownLatch shutdownLatch = new CountDownLatch(1);
    private final AtomicBoolean shutdownRequested = new AtomicBoolean(false);
    private final AtomicBoolean shutdownComplete = new AtomicBoolean(false);

    protected final Collection<ShutdownListener> internalShutdownListeners = new ArrayList<ShutdownListener>();
    protected Collection<ShutdownListener> shutdownListeners = null;

    public static final String COMMAND_SHUTDOWN_WAIT = "sw";
    public static final String COMMAND_SHUTDOWN_NO_WAIT = "s";
    public static final String COMMAND_STATUS = "status";

    private int port = 8184;
    private String host = "127.0.0.1";

    static {
        PropertyConfigurator.configure(RexsterApplication.class.getResource("log4j.properties"));
    }

    public ShutdownManager(String host, int port) {
        this.port = port;
        this.host = host;
    }

    public void registerShutdownListener(ShutdownListener shutdownListener) {
        if (this.shutdownListeners == null) {
            this.shutdownListeners = new ArrayList<ShutdownListener>();
        }
        this.shutdownListeners.add(shutdownListener);
    }
    
    public final void start() throws Exception {

        final ShutdownSocketListener shutdownSocketListener = new ShutdownSocketListener(this.host, this.port);
        
        final Thread shutdownSocketThread = new Thread(shutdownSocketListener, "ShutdownListener-" + this.host + ":" + this.port);
        shutdownSocketThread.setDaemon(true);
        shutdownSocketThread.start();
        
        //Add the listener to the shutdown list 
        this.internalShutdownListeners.add(shutdownSocketListener);
        
        //Register a shutdown handler
        final Thread shutdownHook = new Thread(new ShutdownHookHandler(), "JVM Shutdown Hook");
        Runtime.getRuntime().addShutdownHook(shutdownHook);
        this.logger.debug("Registered JVM shutdown hook");
        
        this.internalShutdownListeners.add(new ShutdownListener() {
            public void shutdown() {
                Runtime.getRuntime().removeShutdownHook(shutdownHook);
                logger.debug("Removed JVM shutdown hook");
            }

            @Override
            public String toString() {
                return "JVM Shutdown Hook Remover";
            }
        });
    }
    
    /**
     * If shutdown isn't complete will wait on the shutdown lock for shutdown to complete.
     * DOES NOT TRIGGER SHUTDOWN
     */
    public final void waitForShutdown() {
        if (this.shutdownComplete.get()) {
            return;
        }
        
        try {
            this.shutdownLatch.await();
        }
        catch (InterruptedException e) {
            this.logger.warn("Interrupted waiting for shutdown condition", e);
        }
    }

    /**
     * Calls shutdown hooks and cleans up shutdown listener code, notifies all waiting threads on completion
     */
    public final void shutdown() {
        final boolean shuttingDown = this.shutdownRequested.getAndSet(true);
        if (shuttingDown) {
            if (this.shutdownComplete.get()) {
                logger.info("Already shut down, ignoring duplicate request");
            }
            else {
                logger.info("Already shutting down, ignoring duplicate request");
            }
            return;
        }
    
        this.preShutdownListeners();
        
        //Run external shutdown tasks
        this.runShutdownHandlers(this.shutdownListeners);
        
        //Run internal shutdown tasks
        this.runShutdownHandlers(this.internalShutdownListeners);
        
        this.postShutdownListeners();
        
        this.shutdownComplete.set(true);
        this.shutdownLatch.countDown();
    }
    
    /**
     * Called before the shutdown listeners
     */
    protected void preShutdownListeners() {
    }
    
    /**
     * Called after the shutdown listeners, before threads waiting on {@link #waitForShutdown()} are released
     */
    protected void postShutdownListeners() {
    }

    /**
     * Sort a {@link List} of {@link com.tinkerpop.rexster.ShutdownManager.ShutdownSocketListener} before {@link #runShutdownHandlers(Collection)} iterates over them.
     * Default implementation does nothing
     */
    protected void sortShutdownListeners(List<ShutdownListener> shutdownListeners) {
    }
    
    protected final void runShutdownHandlers(Collection<ShutdownListener> shutdownListeners) {
        final List<ShutdownListener> shutdownListenersClone = new ArrayList<ShutdownListener>(shutdownListeners);
        this.sortShutdownListeners(shutdownListenersClone);
        for (final ShutdownListener shutdownListener : shutdownListenersClone) {
            try {
                this.logger.info("Calling ShutdownListener: " + shutdownListener);
                shutdownListener.shutdown();
                this.logger.info("ShutdownListener " + shutdownListener + " complete");
            }
            catch (Exception e) {
                this.logger.warn("ShutdownListener " + shutdownListener + " threw an exception, continuing with shutdown", e);
            }
        }
    }
    
    /**
     * Runnable for waiting on connections to the shutdown socket and handling them
     */
    private class ShutdownSocketListener implements Runnable, ShutdownListener {
        private final ServerSocket shutdownSocket;
        private final InetAddress bindHost;
        private final int port;
        
        private ShutdownSocketListener(String host, int port) {
            this.port = port;
            try {
                this.bindHost = InetAddress.getByName(host);
            }<commit_msg>Removed ugly exception print from logs on ctrl-c.<commit_after>package com.tinkerpop.rexster;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;

import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

/**
 * Manages the socket listening for incoming shutdown requests.
 *
 * Adapted from http://code.google.com/p/shutdown-listener/
 */
public class ShutdownManager {
    protected final Logger logger = Logger.getLogger(this.getClass());
    
    private final CountDownLatch shutdownLatch = new CountDownLatch(1);
    private final AtomicBoolean shutdownRequested = new AtomicBoolean(false);
    private final AtomicBoolean shutdownComplete = new AtomicBoolean(false);

    protected final Collection<ShutdownListener> internalShutdownListeners = new ArrayList<ShutdownListener>();
    protected Collection<ShutdownListener> shutdownListeners = null;

    public static final String COMMAND_SHUTDOWN_WAIT = "sw";
    public static final String COMMAND_SHUTDOWN_NO_WAIT = "s";
    public static final String COMMAND_STATUS = "status";

    private int port = 8184;
    private String host = "127.0.0.1";

    static {
        PropertyConfigurator.configure(RexsterApplication.class.getResource("log4j.properties"));
    }

    public ShutdownManager(String host, int port) {
        this.port = port;
        this.host = host;
    }

    public void registerShutdownListener(ShutdownListener shutdownListener) {
        if (this.shutdownListeners == null) {
            this.shutdownListeners = new ArrayList<ShutdownListener>();
        }
        this.shutdownListeners.add(shutdownListener);
    }
    
    public final void start() throws Exception {

        final ShutdownSocketListener shutdownSocketListener = new ShutdownSocketListener(this.host, this.port);
        
        final Thread shutdownSocketThread = new Thread(shutdownSocketListener, "ShutdownListener-" + this.host + ":" + this.port);
        shutdownSocketThread.setDaemon(true);
        shutdownSocketThread.start();
        
        //Add the listener to the shutdown list 
        this.internalShutdownListeners.add(shutdownSocketListener);
        
        //Register a shutdown handler
        final Thread shutdownHook = new Thread(new ShutdownHookHandler(), "JVM Shutdown Hook");
        Runtime.getRuntime().addShutdownHook(shutdownHook);
        this.logger.debug("Registered JVM shutdown hook");
        
        this.internalShutdownListeners.add(new ShutdownListener() {
            public void shutdown() {
                Runtime.getRuntime().removeShutdownHook(shutdownHook);
                logger.debug("Removed JVM shutdown hook");
            }

            @Override
            public String toString() {
                return "JVM Shutdown Hook Remover";
            }
        });
    }
    
    /**
     * If shutdown isn't complete will wait on the shutdown lock for shutdown to complete.
     * DOES NOT TRIGGER SHUTDOWN
     */
    public final void waitForShutdown() {
        if (this.shutdownComplete.get()) {
            return;
        }
        
        try {
            this.shutdownLatch.await();
        }
        catch (InterruptedException e) {
            this.logger.warn("Interrupted waiting for shutdown condition", e);
        }
    }

    /**
     * Calls shutdown hooks and cleans up shutdown listener code, notifies all waiting threads on completion
     */
    public final void shutdown() {
        final boolean shuttingDown = this.shutdownRequested.getAndSet(true);
        if (shuttingDown) {
            if (this.shutdownComplete.get()) {
                logger.info("Already shut down, ignoring duplicate request");
            }
            else {
                logger.info("Already shutting down, ignoring duplicate request");
            }
            return;
        }
    
        this.preShutdownListeners();
        
        //Run external shutdown tasks
        this.runShutdownHandlers(this.shutdownListeners);
        
        //Run internal shutdown tasks
        this.runShutdownHandlers(this.internalShutdownListeners);
        
        this.postShutdownListeners();
        
        this.shutdownComplete.set(true);
        this.shutdownLatch.countDown();
    }
    
    /**
     * Called before the shutdown listeners
     */
    protected void preShutdownListeners() {
    }
    
    /**
     * Called after the shutdown listeners, before threads waiting on {@link #waitForShutdown()} are released
     */
    protected void postShutdownListeners() {
    }

    /**
     * Sort a {@link List} of {@link com.tinkerpop.rexster.ShutdownManager.ShutdownSocketListener} before {@link #runShutdownHandlers(Collection)} iterates over them.
     * Default implementation does nothing
     */
    protected void sortShutdownListeners(List<ShutdownListener> shutdownListeners) {
    }
    
    protected final void runShutdownHandlers(Collection<ShutdownListener> shutdownListeners) {
        final List<ShutdownListener> shutdownListenersClone = new ArrayList<ShutdownListener>(shutdownListeners);
        this.sortShutdownListeners(shutdownListenersClone);
        for (final ShutdownListener shutdownListener : shutdownListenersClone) {
            try {
                this.logger.info("Calling ShutdownListener: " + shutdownListener);
                shutdownListener.shutdown();
                this.logger.info("ShutdownListener " + shutdownListener + " complete");
            }
            catch (Exception e) {
                this.logger.warn("ShutdownListener " + shutdownListener + " threw an exception, continuing with shutdown");
            }
        }
    }
    
    /**
     * Runnable for waiting on connections to the shutdown socket and handling them
     */
    private class ShutdownSocketListener implements Runnable, ShutdownListener {
        private final ServerSocket shutdownSocket;
        private final InetAddress bindHost;
        private final int port;
        
        private ShutdownSocketListener(String host, int port) {
            this.port = port;
            try {
                this.bindHost = InetAddress.getByName(host);
            }
{'fraction_non_alphanumeric': 0.08433917862294087, 'fraction_numerical': 0.002125559857283838, 'mean_word_length': 2.654368932038835, 'pattern_counts': {'":': 2, '<': 19, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6537794', 'n_tokens_mistral': 3427, 'n_tokens_neox': 3313, 'n_words': 830}