<commit_before>/*
 * ################################################################
 *
 * ProActive Parallel Suite(TM): The Java(TM) library for
 *    Parallel, Distributed, Multi-Core Computing for
 *    Enterprise Grids & Clouds
 *
 * Copyright (C) 1997-2010 INRIA/University of
 * 				Nice-Sophia Antipolis/ActiveEon
 * Contact: <EMAIL> or <EMAIL>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; version 3 of
 * the License.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * If needed, contact us to obtain a release under GPL Version 2
 * or a different license than the GPL.
 *
 *  Initial developer(s):               The ProActive Team
 *                        http://proactive.inria.fr/team_members.htm
 *  Contributor(s): ActiveEon Team - http://www.activeeon.com
 *
 * ################################################################
 * $ACTIVEEON_INITIAL_DEV$
 */
package org.ow2.proactive.utils.console;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.Reader;
import java.util.List;
import java.util.Map;
import java.util.Stack;

import jline.ArgumentCompletor;
import jline.ClassNameCompletor;
import jline.Completor;
import jline.ConsoleReader;
import jline.FileNameCompletor;
import jline.History;
import jline.MultiCompletor;
import jline.SimpleCompletor;


/**
 * JlineConsole is an implementation of the {@link Console} interface.<br>
 * It uses the ConsoleReader from Jline package (located in jruby.jar) which provides completion and history.
 * 
 * If this console is not started, it ensure that it won't write anything on the display.
 *
 *
 * @author The ProActive Team
 * @since ProActive Scheduling 2.1
 */
public class JlineConsole implements Console {

    private static String newLineChar = System.getProperty("line.separator");
    private static char ABORT = 'q';
    private static char ALL = 'a';

    private boolean started = false;
    private String prompt = "";
    private ConsoleReader console;
    private SimpleCompletor completor;
    private boolean paginationActivated = true;
    private Stack<String> filters = new Stack<String>();

    private File historyFile = new File(System.getProperty("user.home") + File.separator + ".proactive" +
        File.separator + "console.hist");
    private int historySize = 20;

    /**
     * Create a new instance of SimpleConsole.
     */
    public JlineConsole() {
    }

    /**
     * Create a new instance of SimpleConsole using the given prompt.<br>
     * This constructor does not need a call to the {@link #start(String)} method. It
     * automatically starts the console with the given prompt.
     *
     * @param prompt the prompt to be displayed on the console.
     */
    public JlineConsole(String prompt) {
        start(prompt);
    }

    /**
     * {@inheritDoc}
     */
    public Console start(String prompt) {
        try {
            console = new ConsoleReader(System.in, new PrintWriter(System.out, true));
            completor = new SimpleCompletor(new String[] {});
            ArgumentCompletor comp = new ArgumentCompletor(new MultiCompletor(new Completor[] {
                    new ClassNameCompletor(), completor, new FileNameCompletor() }),
                new ArgumentCompletor.WhitespaceArgumentDelimiter() {
                    @Override
                    public boolean isDelimiterChar(String buffer, int pos) {
                        return super.isDelimiterChar(buffer, pos) || buffer.charAt(pos) == '\'' ||
                            buffer.charAt(pos) == '"' || buffer.charAt(pos) == '{' ||
                            buffer.charAt(pos) == '}' || buffer.charAt(pos) == ',' ||
                            buffer.charAt(pos) == ';';
                    }
                });
            comp.setStrict(false);
            console.addCompletor(comp);
            //Load history
            if (!historyFile.exists()) {
                historyFile.createNewFile();
            } else {
                History history = new History();
                FileReader fr = new FileReader(historyFile);
                BufferedReader br = new BufferedReader(fr);
                String line;
                while ((line = br.readLine()) != null) {
                    history.addToHistory(line);
                }
                fr.close();
                br.close();
                console.setHistory(history);
            }
            Runtime.getRuntime().addShutdownHook(new Thread() {
                @Override
                public void run() {
                    try {
                        if (historyFile.exists()) {
                            historyFile.delete();
                        }
                        historyFile.createNewFile();
                        PrintStream ps = new PrintStream(historyFile);
                        List h = console.getHistory().getHistoryList();
                        for (int i = h.size() - historySize > 0 ? h.size() - historySize : 0; i < h.size(); i++) {
                            ps.println(h.get(i));
                        }
                        ps.close();
                    } catch (IOException e) {
                    }
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        this.prompt = prompt;
        this.started = true;
        return this;
    }

    /**
     * {@inheritDoc}
     */
    public void stop() {
        if (this.started) {
            this.console = null;
            this.started = false;
        }
    }

    /**
     * {@inheritDoc}
     */
    public void flush() {
        if (this.started && console != null) {
            try {<commit_msg>Improve jlineconsole termination<commit_after>/*
 * ################################################################
 *
 * ProActive Parallel Suite(TM): The Java(TM) library for
 *    Parallel, Distributed, Multi-Core Computing for
 *    Enterprise Grids & Clouds
 *
 * Copyright (C) 1997-2010 INRIA/University of
 * 				Nice-Sophia Antipolis/ActiveEon
 * Contact: <EMAIL> or <EMAIL>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; version 3 of
 * the License.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * If needed, contact us to obtain a release under GPL Version 2
 * or a different license than the GPL.
 *
 *  Initial developer(s):               The ProActive Team
 *                        http://proactive.inria.fr/team_members.htm
 *  Contributor(s): ActiveEon Team - http://www.activeeon.com
 *
 * ################################################################
 * $ACTIVEEON_INITIAL_DEV$
 */
package org.ow2.proactive.utils.console;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.Reader;
import java.util.List;
import java.util.Map;
import java.util.Stack;

import jline.ArgumentCompletor;
import jline.ClassNameCompletor;
import jline.Completor;
import jline.ConsoleReader;
import jline.FileNameCompletor;
import jline.History;
import jline.MultiCompletor;
import jline.SimpleCompletor;


/**
 * JlineConsole is an implementation of the {@link Console} interface.<br>
 * It uses the ConsoleReader from Jline package (located in jruby.jar) which provides completion and history.
 * 
 * If this console is not started, it ensure that it won't write anything on the display.
 *
 *
 * @author The ProActive Team
 * @since ProActive Scheduling 2.1
 */
public class JlineConsole implements Console {

    private static String newLineChar = System.getProperty("line.separator");
    private static char ABORT = 'q';
    private static char ALL = 'a';

    private boolean started = false;
    private String prompt = "";
    private ConsoleReader console;
    private SimpleCompletor completor;
    private boolean paginationActivated = true;
    private Stack<String> filters = new Stack<String>();

    private File historyFile = new File(System.getProperty("user.home") + File.separator + ".proactive" +
        File.separator + "console.hist");
    private int historySize = 20;

    /**
     * Create a new instance of SimpleConsole.
     */
    public JlineConsole() {
    }

    /**
     * Create a new instance of SimpleConsole using the given prompt.<br>
     * This constructor does not need a call to the {@link #start(String)} method. It
     * automatically starts the console with the given prompt.
     *
     * @param prompt the prompt to be displayed on the console.
     */
    public JlineConsole(String prompt) {
        start(prompt);
    }

    /**
     * {@inheritDoc}
     */
    public Console start(String prompt) {
        try {
            console = new ConsoleReader(System.in, new PrintWriter(System.out, true));
            completor = new SimpleCompletor(new String[] {});
            ArgumentCompletor comp = new ArgumentCompletor(new MultiCompletor(new Completor[] {
                    new ClassNameCompletor(), completor, new FileNameCompletor() }),
                new ArgumentCompletor.WhitespaceArgumentDelimiter() {
                    @Override
                    public boolean isDelimiterChar(String buffer, int pos) {
                        return super.isDelimiterChar(buffer, pos) || buffer.charAt(pos) == '\'' ||
                            buffer.charAt(pos) == '"' || buffer.charAt(pos) == '{' ||
                            buffer.charAt(pos) == '}' || buffer.charAt(pos) == ',' ||
                            buffer.charAt(pos) == ';';
                    }
                });
            comp.setStrict(false);
            console.addCompletor(comp);
            //Load history
            if (!historyFile.exists()) {
                historyFile.createNewFile();
            } else {
                History history = new History();
                FileReader fr = new FileReader(historyFile);
                BufferedReader br = new BufferedReader(fr);
                String line;
                while ((line = br.readLine()) != null) {
                    history.addToHistory(line);
                }
                fr.close();
                br.close();
                console.setHistory(history);
            }
            Runtime.getRuntime().addShutdownHook(new Thread() {
                @Override
                public void run() {
                    dumpHistory();
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        this.prompt = prompt;
        this.started = true;
        return this;
    }

    boolean dumped = false;

    private synchronized void dumpHistory() {
        if (!dumped) {
            dumped = true;
            try {
                if (historyFile.exists()) {
                    historyFile.delete();
                }
                historyFile.createNewFile();
                PrintStream ps = new PrintStream(historyFile);
                List h = console.getHistory().getHistoryList();
                for (int i = h.size() - historySize > 0 ? h.size() - historySize : 0; i < h.size(); i++) {
                    ps.println(h.get(i));
                }
                ps.close();
            } catch (IOException e) {
            }
        }
    }

    /**
     * {@inheritDoc}
     */
    public void stop() {
        if (this.started) {
            this.started = false;
            dumpHistory();
        }
    }

    /**
     * {@inheritDoc}
     */
    public void flush() {
        if (this.started && console != null) {
            try {
{'fraction_non_alphanumeric': 0.11814345991561181, 'fraction_numerical': 0.004844506954211595, 'mean_word_length': 2.069304556354916, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, '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': '4042373', 'n_tokens_mistral': 3432, 'n_tokens_neox': 3246, 'n_words': 1007}