/* * ProActive Parallel Suite(TM): * The Open Source library for parallel and distributed * Workflows & Scheduling, Orchestration, Cloud Automation * and Big Data Analysis on Enterprise Grids & Clouds. * * Copyright (c) 2007 - 2017 ActiveEon * Contact: contact@activeeon.com * * This library is free software: you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License * as published by the Free Software Foundation: version 3 of * the License. * * This program 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * If needed, contact us to obtain a release under GPL Version 2 or 3 * or a different license than the AGPL. */ package org.ow2.proactive_grid_cloud_portal.cli.console; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.SortedSet; import java.util.StringTokenizer; import java.util.TreeSet; import jline.console.completer.Completer; /** * <p> * A simple {@link Completer} implementation that handles a pre-defined * list of completion words. * </p> * * <p> * Example usage: * </p> * <pre> * myConsoleReader.addCompletor (new SimpleCompletor (new String [] { "now", "yesterday", "tomorrow" })); * </pre> * * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a> */ public class SimpleCompletor implements Completer, Cloneable { /** * The list of candidates that will be completed. */ SortedSet candidates; /** * A delimiter to use to qualify completions. */ String delimiter; final SimpleCompletorFilter filter; /** * Create a new SimpleCompletor with a single possible completion * values. */ public SimpleCompletor(final String candidateString) { this(new String[] { candidateString }); } /** * Create a new SimpleCompletor with a list of possible completion * values. */ public SimpleCompletor(final String[] candidateStrings) { this(candidateStrings, null); } public SimpleCompletor(final String[] strings, final SimpleCompletorFilter filter) { this.filter = filter; setCandidateStrings(strings); } /** * Complete candidates using the contents of the specified Reader. */ public SimpleCompletor(final Reader reader) throws IOException { this(getStrings(reader)); } /** * Complete candidates using the whitespearated values in * read from the specified Reader. */ public SimpleCompletor(final InputStream in) throws IOException { this(getStrings(new InputStreamReader(in))); } private static String[] getStrings(final Reader in) throws IOException { final Reader reader = (in instanceof BufferedReader) ? in : new BufferedReader(in); List words = new LinkedList(); String line; while ((line = ((BufferedReader) reader).readLine()) != null) { for (StringTokenizer tok = new StringTokenizer(line); tok.hasMoreTokens(); words.add(tok.nextToken())) { ; } } return (String[]) words.toArray(new String[words.size()]); } public int complete(final String buffer, final int cursor, final List clist) { String start = (buffer == null) ? "" : buffer; SortedSet matches = candidates.tailSet(start); for (Iterator i = matches.iterator(); i.hasNext();) { String can = (String) i.next(); if (!(can.startsWith(start))) { break; } if (delimiter != null) { int index = can.indexOf(delimiter, cursor); if (index != -1) { can = can.substring(0, index + 1); } } clist.add(can); } if (clist.size() == 1) { clist.set(0, ((String) clist.get(0)) + " "); } // the index of the completion is always from the beginning of // the buffer. return (clist.size() == 0) ? (-1) : 0; } public void setDelimiter(final String delimiter) { this.delimiter = delimiter; } public String getDelimiter() { return this.delimiter; } public void setCandidates(final SortedSet candidates) { if (filter != null) { TreeSet filtered = new TreeSet(); for (Iterator i = candidates.iterator(); i.hasNext();) { String element = (String) i.next(); element = filter.filter(element); if (element != null) { filtered.add(element); } } this.candidates = filtered; } else { this.candidates = candidates; } } public SortedSet getCandidates() { return Collections.unmodifiableSortedSet(this.candidates); } public void setCandidateStrings(final String[] strings) { setCandidates(new TreeSet(Arrays.asList(strings))); } public void addCandidateString(final String candidateString) { final String string = (filter == null) ? candidateString : filter.filter(candidateString); if (string != null) { candidates.add(string); } } public Object clone() throws CloneNotSupportedException { return super.clone(); } /** * Filter for elements in the completor. * * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a> */ public interface SimpleCompletorFilter { /** * Filter the specified String. To not filter it, return the * same String as the parameter. To exclude it, return null. */ String filter(String element); } public static class NoOpFilter implements SimpleCompletorFilter { public String filter(final String element) { return element; } } }