1 /* 2 * Copyright (c) 2002-2012, the original author or authors. 3 * 4 * This software is distributable under the BSD license. See the terms of the 5 * BSD license in the documentation provided with this software. 6 * 7 * http://www.opensource.org/licenses/bsd-license.php 8 */ 9 package jdk.internal.jline.console.completer; 10 11 import java.util.ArrayList; 12 import java.util.Arrays; 13 import java.util.Collection; 14 import java.util.LinkedList; 15 import java.util.List; 16 17 import static jdk.internal.jline.internal.Preconditions.checkNotNull; 18 19 /** 20 * Completer which contains multiple completers and aggregates them together. 21 * 22 * @author <a href="mailto:jason@planet57.com">Jason Dillon</a> 23 * @since 2.3 24 */ 25 public class AggregateCompleter 26 implements Completer 27 { 28 private final List<Completer> completers = new ArrayList<Completer>(); 29 30 public AggregateCompleter() { 31 // empty 32 } 33 34 /** 35 * Construct an AggregateCompleter with the given collection of completers. 36 * The completers will be used in the iteration order of the collection. 37 * 38 * @param completers the collection of completers 39 */ 40 public AggregateCompleter(final Collection<Completer> completers) { 41 checkNotNull(completers); 42 this.completers.addAll(completers); 43 } 44 45 /** 46 * Construct an AggregateCompleter with the given completers. 47 * The completers will be used in the order given. 48 * 49 * @param completers the completers 50 */ 51 public AggregateCompleter(final Completer... completers) { 52 this(Arrays.asList(completers)); 53 } 54 55 /** 56 * Retrieve the collection of completers currently being aggregated. 57 * 58 * @return the aggregated completers 59 */ 60 public Collection<Completer> getCompleters() { 61 return completers; 62 } 63 64 /** 65 * Perform a completion operation across all aggregated completers. 66 * 67 * @see Completer#complete(String, int, java.util.List) 68 * @return the highest completion return value from all completers 69 */ 70 public int complete(final String buffer, final int cursor, final List<CharSequence> candidates) { 71 // buffer could be null 72 checkNotNull(candidates); 73 74 List<Completion> completions = new ArrayList<Completion>(completers.size()); 75 76 // Run each completer, saving its completion results 77 int max = -1; 78 for (Completer completer : completers) { 79 Completion completion = new Completion(candidates); 80 completion.complete(completer, buffer, cursor); 81 82 // Compute the max cursor position 83 max = Math.max(max, completion.cursor); 84 85 completions.add(completion); 86 } 87 88 // Append candidates from completions which have the same cursor position as max 89 for (Completion completion : completions) { 90 if (completion.cursor == max) { 91 candidates.addAll(completion.candidates); 92 } 93 } 94 95 return max; 96 } 97 98 /** 99 * @return a string representing the aggregated completers 100 */ 101 @Override 102 public String toString() { 103 return getClass().getSimpleName() + "{" + 104 "completers=" + completers + 105 '}'; 106 } 107 108 private class Completion 109 { 110 public final List<CharSequence> candidates; 111 112 public int cursor; 113 114 public Completion(final List<CharSequence> candidates) { 115 checkNotNull(candidates); 116 this.candidates = new LinkedList<CharSequence>(candidates); 117 } 118 119 public void complete(final Completer completer, final String buffer, final int cursor) { 120 checkNotNull(completer); 121 this.cursor = completer.complete(buffer, cursor, candidates); 122 } 123 } 124 }