001: /*****************************************************************************
002: * *
003: * This file is part of the BeanShell Java Scripting distribution. *
004: * Documentation and updates may be found at http://www.beanshell.org/ *
005: * *
006: * Sun Public License Notice: *
007: * *
008: * The contents of this file are subject to the Sun Public License Version *
009: * 1.0 (the "License"); you may not use this file except in compliance with *
010: * the License. A copy of the License is available at http://www.sun.com *
011: * *
012: * The Original Code is BeanShell. The Initial Developer of the Original *
013: * Code is Pat Niemeyer. Portions created by Pat Niemeyer are Copyright *
014: * (C) 2000. All Rights Reserved. *
015: * *
016: * GNU Public License Notice: *
017: * *
018: * Alternatively, the contents of this file may be used under the terms of *
019: * the GNU Lesser General Public License (the "LGPL"), in which case the *
020: * provisions of LGPL are applicable instead of those above. If you wish to *
021: * allow use of your version of this file only under the terms of the LGPL *
022: * and not to allow others to use your version of this file under the SPL, *
023: * indicate your decision by deleting the provisions above and replace *
024: * them with the notice and other provisions required by the LGPL. If you *
025: * do not delete the provisions above, a recipient may use your version of *
026: * this file under either the SPL or the LGPL. *
027: * *
028: * Patrick Niemeyer (pat@pat.net) *
029: * Author of Learning Java, O'Reilly & Associates *
030: * http://www.pat.net/~pat/ *
031: * *
032: *****************************************************************************/package bsh.util;
033:
034: import java.util.*;
035: import bsh.StringUtil;
036: import bsh.NameSource;
037:
038: /**
039: NameCompletionTable is a utility that implements simple name completion for
040: a collection of names, NameSources, and other NameCompletionTables.
041: This implementation uses a trivial linear search and comparison...
042: */
043: public class NameCompletionTable extends ArrayList implements
044: NameCompletion {
045: /** Unimplemented - need a collection here */
046: NameCompletionTable table;
047: List sources;
048:
049: /** Unimplemented - need a collection of sources here*/
050:
051: /**
052: */
053: public NameCompletionTable() {
054: }
055:
056: /**
057: Add a NameCompletionTable, which is more optimized than the more
058: general NameSource
059: */
060: public void add(NameCompletionTable table) {
061: /** Unimplemented - need a collection here */
062: if (this .table != null)
063: throw new RuntimeException("Unimplemented usage error");
064:
065: this .table = table;
066: }
067:
068: /**
069: Add a NameSource which is monitored for names.
070: Unimplemented - behavior is broken... no updates
071: */
072: public void add(NameSource source) {
073: /*
074: Unimplemented -
075: Need to add an inner class util here that holds the source and
076: monitors it by registering a listener
077: */
078: if (sources == null)
079: sources = new ArrayList();
080:
081: sources.add(source);
082: }
083:
084: /**
085: Add any matching names to list (including any from other tables)
086: */
087: protected void getMatchingNames(String part, List found) {
088: // check our table
089: for (int i = 0; i < size(); i++) {
090: String name = (String) get(i);
091: if (name.startsWith(part))
092: found.add(name);
093: }
094:
095: // Check other tables.
096: /** Unimplemented - need a collection here */
097: if (table != null)
098: table.getMatchingNames(part, found);
099:
100: // Check other sources
101: // note should add caching in source adapters
102: if (sources != null)
103: for (int i = 0; i < sources.size(); i++) {
104: NameSource src = (NameSource) sources.get(i);
105: String[] names = src.getAllNames();
106: for (int j = 0; j < names.length; j++)
107: if (names[j].startsWith(part))
108: found.add(names[j]);
109:
110: }
111: }
112:
113: public String[] completeName(String part) {
114: List found = new ArrayList();
115: getMatchingNames(part, found);
116:
117: if (found.size() == 0)
118: return new String[0];
119:
120: // Find the max common prefix
121: String maxCommon = (String) found.get(0);
122: for (int i = 1; i < found.size() && maxCommon.length() > 0; i++) {
123: maxCommon = StringUtil.maxCommonPrefix(maxCommon,
124: (String) found.get(i));
125:
126: // if maxCommon gets as small as part, stop trying
127: if (maxCommon.equals(part))
128: break;
129: }
130:
131: // Return max common or all ambiguous
132: if (maxCommon.length() > part.length())
133: return new String[] { maxCommon };
134: else
135: return (String[]) (found.toArray(new String[0]));
136: }
137:
138: /**
139: class SourceCache implements NameSource.Listener
140: {
141: NameSource src;
142: SourceMonitor( NameSource src ) {
143: this.src = src;
144: }
145: public void nameSourceChanged( NameSource src ) {
146: }
147: }
148: */
149: }
|