001    /**
002     *      jline - Java console input library
003     *      Copyright (c) 2002-2006, Marc Prud'hommeaux <mwp1@cornell.edu>
004     *      All rights reserved.
005     *
006     *      Redistribution and use in source and binary forms, with or
007     *      without modification, are permitted provided that the following
008     *      conditions are met:
009     *
010     *      Redistributions of source code must retain the above copyright
011     *      notice, this list of conditions and the following disclaimer.
012     *
013     *      Redistributions in binary form must reproduce the above copyright
014     *      notice, this list of conditions and the following disclaimer
015     *      in the documentation and/or other materials provided with
016     *      the distribution.
017     *
018     *      Neither the name of JLine nor the names of its contributors
019     *      may be used to endorse or promote products derived from this
020     *      software without specific prior written permission.
021     *
022     *      THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
023     *      "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
024     *      BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
025     *      AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
026     *      EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
027     *      FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
028     *      OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
029     *      PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
030     *      DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
031     *      AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
032     *      LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
033     *      IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
034     *      OF THE POSSIBILITY OF SUCH DAMAGE.
035     */
036    package jline;
037    
038    import java.util.*;
039    
040    /**
041     *      <p>
042     *      A completor that contains multiple embedded completors. This differs
043     *      from the {@link ArgumentCompletor}, in that the nested completors
044     *      are dispatched individually, rather than delimited by arguments.
045     *      </p>
046     *
047     *  @author  <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
048     */
049    public class MultiCompletor
050            implements Completor
051    {
052            Completor [] completors = new Completor [0];
053    
054    
055            /**
056             *  Construct a MultiCompletor with no embedded completors.
057             */
058            public MultiCompletor ()
059            {
060                    this (new Completor [0]);
061            }
062    
063    
064            /**
065             *  Construct a MultiCompletor with the specified list of
066             *  {@link Completor} instances.
067             */
068            public MultiCompletor (final List completors)
069            {
070                    this ((Completor [])completors.toArray (
071                            new Completor [completors.size ()]));
072            }
073    
074    
075            /**
076             *  Construct a MultiCompletor with the specified
077             *  {@link Completor} instances.
078             */
079            public MultiCompletor (final Completor [] completors)
080            {
081                    this.completors = completors;
082            }
083    
084    
085            public int complete (final String buffer, final int pos, final List cand)
086            {
087                    int [] positions = new int [completors.length];
088                    List [] copies = new List [completors.length];
089                    for (int i = 0; i < completors.length; i++)
090                    {
091                            // clone and save the candidate list
092                            copies [i] = new LinkedList (cand);
093                            positions [i] = completors [i].complete (buffer, pos, copies [i]);
094                    }
095    
096                    int maxposition = -1;
097                    for (int i = 0; i < positions.length; i++)
098                            maxposition = Math.max (maxposition, positions [i]);
099    
100                    // now we have the max cursor value: build up all the
101                    // candidate lists that have the same cursor value
102                    for (int i = 0; i < copies.length; i++)
103                    {
104                            if (positions [i] == maxposition)
105                                    cand.addAll (copies [i]);
106                    }
107    
108                    return maxposition;
109            }
110    
111    
112            public void setCompletors (final Completor [] completors)
113            {
114                    this.completors = completors;
115            }
116    
117    
118            public Completor [] getCompletors ()
119            {
120                    return this.completors;
121            }
122    }