001    /*
002     * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
003     *
004     * This software is distributable under the BSD license. See the terms of the
005     * BSD license in the documentation provided with this software.
006     */
007    package jline;
008    
009    import java.util.*;
010    
011    /**
012     *  <p>
013     *  A completor that contains multiple embedded completors. This differs
014     *  from the {@link ArgumentCompletor}, in that the nested completors
015     *  are dispatched individually, rather than delimited by arguments.
016     *  </p>
017     *
018     *  @author  <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
019     */
020    public class MultiCompletor implements Completor {
021        Completor[] completors = new Completor[0];
022    
023        /**
024         *  Construct a MultiCompletor with no embedded completors.
025         */
026        public MultiCompletor() {
027            this(new Completor[0]);
028        }
029    
030        /**
031         *  Construct a MultiCompletor with the specified list of
032         *  {@link Completor} instances.
033         */
034        public MultiCompletor(final List completors) {
035            this((Completor[]) completors.toArray(new Completor[completors.size()]));
036        }
037    
038        /**
039         *  Construct a MultiCompletor with the specified
040         *  {@link Completor} instances.
041         */
042        public MultiCompletor(final Completor[] completors) {
043            this.completors = completors;
044        }
045    
046        public int complete(final String buffer, final int pos, final List cand) {
047            int[] positions = new int[completors.length];
048            List[] copies = new List[completors.length];
049    
050            for (int i = 0; i < completors.length; i++) {
051                // clone and save the candidate list
052                copies[i] = new LinkedList(cand);
053                positions[i] = completors[i].complete(buffer, pos, copies[i]);
054            }
055    
056            int maxposition = -1;
057    
058            for (int i = 0; i < positions.length; i++) {
059                maxposition = Math.max(maxposition, positions[i]);
060            }
061    
062            // now we have the max cursor value: build up all the
063            // candidate lists that have the same cursor value
064            for (int i = 0; i < copies.length; i++) {
065                if (positions[i] == maxposition) {
066                    cand.addAll(copies[i]);
067                }
068            }
069    
070            return maxposition;
071        }
072    
073        public void setCompletors(final Completor[] completors) {
074            this.completors = completors;
075        }
076    
077        public Completor[] getCompletors() {
078            return this.completors;
079        }
080    }