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 */
007package jline;
008
009import 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 */
020public 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}