Source Code Cross Referenced for ArgumentCompletor.java in  » Development » jLine » jline » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Development » jLine » jline 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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:         *  A {@link Completor} implementation that invokes a child completor
013:         *  using the appropriate <i>separator</i> argument. This
014:         *  can be used instead of the individual completors having to
015:         *  know about argument parsing semantics.
016:         *  <p>
017:         *  <strong>Example 1</strong>: Any argument of the command line can
018:         *  use file completion.
019:         *  <p>
020:         *  <pre>
021:         *        consoleReader.addCompletor (new ArgumentCompletor (
022:         *                new {@link FileNameCompletor} ()))
023:         *  </pre>
024:         *  <p>
025:         *  <strong>Example 2</strong>: The first argument of the command line
026:         *  can be completed with any of "foo", "bar", or "baz", and remaining
027:         *  arguments can be completed with a file name.
028:         *  <p>
029:         *  <pre>
030:         *        consoleReader.addCompletor (new ArgumentCompletor (
031:         *                new {@link SimpleCompletor} (new String [] { "foo", "bar", "baz"})));
032:         *        consoleReader.addCompletor (new ArgumentCompletor (
033:         *                new {@link FileNameCompletor} ()));
034:         *  </pre>
035:         *
036:         *  <p>
037:         *        When the argument index is past the last embedded completors, the last
038:         *        completors is always used. To disable this behavior, have the last
039:         *        completor be a {@link NullCompletor}. For example:
040:         *        </p>
041:         *
042:         *        <pre>
043:         *        consoleReader.addCompletor (new ArgumentCompletor (
044:         *                new {@link SimpleCompletor} (new String [] { "foo", "bar", "baz"}),
045:         *                new {@link SimpleCompletor} (new String [] { "xxx", "yyy", "xxx"}),
046:         *                new {@link NullCompletor}
047:         *                ));
048:         *        </pre>
049:         *  <p>
050:         *  TODO: handle argument quoting and escape characters
051:         *  </p>
052:         *
053:         *  @author  <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
054:         */
055:        public class ArgumentCompletor implements  Completor {
056:            final Completor[] completors;
057:            final ArgumentDelimiter delim;
058:            boolean strict = true;
059:
060:            /**
061:             *  Constuctor: create a new completor with the default
062:             *  argument separator of " ".
063:             *
064:             *  @param  completor  the embedded completor
065:             */
066:            public ArgumentCompletor(final Completor completor) {
067:                this (new Completor[] { completor });
068:            }
069:
070:            /**
071:             *  Constuctor: create a new completor with the default
072:             *  argument separator of " ".
073:             *
074:             *  @param  completors  the List of completors to use
075:             */
076:            public ArgumentCompletor(final List completors) {
077:                this ((Completor[]) completors.toArray(new Completor[completors
078:                        .size()]));
079:            }
080:
081:            /**
082:             *  Constuctor: create a new completor with the default
083:             *  argument separator of " ".
084:             *
085:             *  @param  completors  the embedded argument completors
086:             */
087:            public ArgumentCompletor(final Completor[] completors) {
088:                this (completors, new WhitespaceArgumentDelimiter());
089:            }
090:
091:            /**
092:             *  Constuctor: create a new completor with the specified
093:             *  argument delimiter.
094:             *
095:             *  @param  completor the embedded completor
096:             *  @param  delim     the delimiter for parsing arguments
097:             */
098:            public ArgumentCompletor(final Completor completor,
099:                    final ArgumentDelimiter delim) {
100:                this (new Completor[] { completor }, delim);
101:            }
102:
103:            /**
104:             *  Constuctor: create a new completor with the specified
105:             *  argument delimiter.
106:             *
107:             *  @param  completors the embedded completors
108:             *  @param  delim      the delimiter for parsing arguments
109:             */
110:            public ArgumentCompletor(final Completor[] completors,
111:                    final ArgumentDelimiter delim) {
112:                this .completors = completors;
113:                this .delim = delim;
114:            }
115:
116:            /**
117:             *  If true, a completion at argument index N will only succeed
118:             *  if all the completions from 0-(N-1) also succeed.
119:             */
120:            public void setStrict(final boolean strict) {
121:                this .strict = strict;
122:            }
123:
124:            /**
125:             *  Returns whether a completion at argument index N will succees
126:             *  if all the completions from arguments 0-(N-1) also succeed.
127:             */
128:            public boolean getStrict() {
129:                return this .strict;
130:            }
131:
132:            public int complete(final String buffer, final int cursor,
133:                    final List candidates) {
134:                ArgumentList list = delim.delimit(buffer, cursor);
135:                int argpos = list.getArgumentPosition();
136:                int argIndex = list.getCursorArgumentIndex();
137:
138:                if (argIndex < 0) {
139:                    return -1;
140:                }
141:
142:                final Completor comp;
143:
144:                // if we are beyond the end of the completors, just use the last one
145:                if (argIndex >= completors.length) {
146:                    comp = completors[completors.length - 1];
147:                } else {
148:                    comp = completors[argIndex];
149:                }
150:
151:                // ensure that all the previous completors are successful before
152:                // allowing this completor to pass (only if strict is true).
153:                for (int i = 0; getStrict() && (i < argIndex); i++) {
154:                    Completor sub = completors[(i >= completors.length) ? (completors.length - 1)
155:                            : i];
156:                    String[] args = list.getArguments();
157:                    String arg = ((args == null) || (i >= args.length)) ? ""
158:                            : args[i];
159:
160:                    List subCandidates = new LinkedList();
161:
162:                    if (sub.complete(arg, arg.length(), subCandidates) == -1) {
163:                        return -1;
164:                    }
165:
166:                    if (subCandidates.size() == 0) {
167:                        return -1;
168:                    }
169:                }
170:
171:                int ret = comp.complete(list.getCursorArgument(), argpos,
172:                        candidates);
173:
174:                if (ret == -1) {
175:                    return -1;
176:                }
177:
178:                int pos = ret + (list.getBufferPosition() - argpos);
179:
180:                /**
181:                 *  Special case: when completing in the middle of a line, and the
182:                 *  area under the cursor is a delimiter, then trim any delimiters
183:                 *  from the candidates, since we do not need to have an extra
184:                 *  delimiter.
185:                 *
186:                 *  E.g., if we have a completion for "foo", and we
187:                 *  enter "f bar" into the buffer, and move to after the "f"
188:                 *  and hit TAB, we want "foo bar" instead of "foo  bar".
189:                 */
190:                if ((cursor != buffer.length())
191:                        && delim.isDelimiter(buffer, cursor)) {
192:                    for (int i = 0; i < candidates.size(); i++) {
193:                        String val = candidates.get(i).toString();
194:
195:                        while ((val.length() > 0)
196:                                && delim.isDelimiter(val, val.length() - 1)) {
197:                            val = val.substring(0, val.length() - 1);
198:                        }
199:
200:                        candidates.set(i, val);
201:                    }
202:                }
203:
204:                ConsoleReader.debug("Completing " + buffer + "(pos=" + cursor
205:                        + ") " + "with: " + candidates + ": offset=" + pos);
206:
207:                return pos;
208:            }
209:
210:            /**
211:             *  The {@link ArgumentCompletor.ArgumentDelimiter} allows custom
212:             *  breaking up of a {@link String} into individual arguments in
213:             *  order to dispatch the arguments to the nested {@link Completor}.
214:             *
215:             *  @author  <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
216:             */
217:            public static interface ArgumentDelimiter {
218:                /**
219:                 *  Break the specified buffer into individual tokens
220:                 *  that can be completed on their own.
221:                 *
222:                 *  @param  buffer           the buffer to split
223:                 *  @param  argumentPosition the current position of the
224:                 *                           cursor in the buffer
225:                 *  @return                  the tokens
226:                 */
227:                ArgumentList delimit(String buffer, int argumentPosition);
228:
229:                /**
230:                 *  Returns true if the specified character is a whitespace
231:                 *  parameter.
232:                 *
233:                 *  @param  buffer the complete command buffer
234:                 *  @param  pos    the index of the character in the buffer
235:                 *  @return        true if the character should be a delimiter
236:                 */
237:                boolean isDelimiter(String buffer, int pos);
238:            }
239:
240:            /**
241:             *  Abstract implementation of a delimiter that uses the
242:             *  {@link #isDelimiter} method to determine if a particular
243:             *  character should be used as a delimiter.
244:             *
245:             *  @author  <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
246:             */
247:            public abstract static class AbstractArgumentDelimiter implements 
248:                    ArgumentDelimiter {
249:                private char[] quoteChars = new char[] { '\'', '"' };
250:                private char[] escapeChars = new char[] { '\\' };
251:
252:                public void setQuoteChars(final char[] quoteChars) {
253:                    this .quoteChars = quoteChars;
254:                }
255:
256:                public char[] getQuoteChars() {
257:                    return this .quoteChars;
258:                }
259:
260:                public void setEscapeChars(final char[] escapeChars) {
261:                    this .escapeChars = escapeChars;
262:                }
263:
264:                public char[] getEscapeChars() {
265:                    return this .escapeChars;
266:                }
267:
268:                public ArgumentList delimit(final String buffer,
269:                        final int cursor) {
270:                    List args = new LinkedList();
271:                    StringBuffer arg = new StringBuffer();
272:                    int argpos = -1;
273:                    int bindex = -1;
274:
275:                    for (int i = 0; (buffer != null) && (i <= buffer.length()); i++) {
276:                        // once we reach the cursor, set the
277:                        // position of the selected index
278:                        if (i == cursor) {
279:                            bindex = args.size();
280:                            // the position in the current argument is just the
281:                            // length of the current argument
282:                            argpos = arg.length();
283:                        }
284:
285:                        if ((i == buffer.length()) || isDelimiter(buffer, i)) {
286:                            if (arg.length() > 0) {
287:                                args.add(arg.toString());
288:                                arg.setLength(0); // reset the arg
289:                            }
290:                        } else {
291:                            arg.append(buffer.charAt(i));
292:                        }
293:                    }
294:
295:                    return new ArgumentList((String[]) args
296:                            .toArray(new String[args.size()]), bindex, argpos,
297:                            cursor);
298:                }
299:
300:                /**
301:                 *  Returns true if the specified character is a whitespace
302:                 *  parameter. Check to ensure that the character is not
303:                 *  escaped by any of
304:                 *  {@link #getQuoteChars}, and is not escaped by ant of the
305:                 *  {@link #getEscapeChars}, and returns true from
306:                 *  {@link #isDelimiterChar}.
307:                 *
308:                 *  @param  buffer the complete command buffer
309:                 *  @param  pos    the index of the character in the buffer
310:                 *  @return        true if the character should be a delimiter
311:                 */
312:                public boolean isDelimiter(final String buffer, final int pos) {
313:                    if (isQuoted(buffer, pos)) {
314:                        return false;
315:                    }
316:
317:                    if (isEscaped(buffer, pos)) {
318:                        return false;
319:                    }
320:
321:                    return isDelimiterChar(buffer, pos);
322:                }
323:
324:                public boolean isQuoted(final String buffer, final int pos) {
325:                    return false;
326:                }
327:
328:                public boolean isEscaped(final String buffer, final int pos) {
329:                    if (pos <= 0) {
330:                        return false;
331:                    }
332:
333:                    for (int i = 0; (escapeChars != null)
334:                            && (i < escapeChars.length); i++) {
335:                        if (buffer.charAt(pos) == escapeChars[i]) {
336:                            return !isEscaped(buffer, pos - 1); // escape escape
337:                        }
338:                    }
339:
340:                    return false;
341:                }
342:
343:                /**
344:                 *  Returns true if the character at the specified position
345:                 *  if a delimiter. This method will only be called if the
346:                 *  character is not enclosed in any of the
347:                 *  {@link #getQuoteChars}, and is not escaped by ant of the
348:                 *  {@link #getEscapeChars}. To perform escaping manually,
349:                 *  override {@link #isDelimiter} instead.
350:                 */
351:                public abstract boolean isDelimiterChar(String buffer, int pos);
352:            }
353:
354:            /**
355:             *  {@link ArgumentCompletor.ArgumentDelimiter}
356:             *  implementation that counts all
357:             *  whitespace (as reported by {@link Character#isWhitespace})
358:             *  as being a delimiter.
359:             *
360:             *  @author  <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
361:             */
362:            public static class WhitespaceArgumentDelimiter extends
363:                    AbstractArgumentDelimiter {
364:                /**
365:                 *  The character is a delimiter if it is whitespace, and the
366:                 *  preceeding character is not an escape character.
367:                 */
368:                public boolean isDelimiterChar(String buffer, int pos) {
369:                    return Character.isWhitespace(buffer.charAt(pos));
370:                }
371:            }
372:
373:            /**
374:             *  The result of a delimited buffer.
375:             *
376:             *  @author  <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
377:             */
378:            public static class ArgumentList {
379:                private String[] arguments;
380:                private int cursorArgumentIndex;
381:                private int argumentPosition;
382:                private int bufferPosition;
383:
384:                /**
385:                 *  @param  arguments           the array of tokens
386:                 *  @param  cursorArgumentIndex the token index of the cursor
387:                 *  @param  argumentPosition    the position of the cursor in the
388:                 *                              current token
389:                 *  @param  bufferPosition      the position of the cursor in
390:                 *                              the whole buffer
391:                 */
392:                public ArgumentList(String[] arguments,
393:                        int cursorArgumentIndex, int argumentPosition,
394:                        int bufferPosition) {
395:                    this .arguments = arguments;
396:                    this .cursorArgumentIndex = cursorArgumentIndex;
397:                    this .argumentPosition = argumentPosition;
398:                    this .bufferPosition = bufferPosition;
399:                }
400:
401:                public void setCursorArgumentIndex(int cursorArgumentIndex) {
402:                    this .cursorArgumentIndex = cursorArgumentIndex;
403:                }
404:
405:                public int getCursorArgumentIndex() {
406:                    return this .cursorArgumentIndex;
407:                }
408:
409:                public String getCursorArgument() {
410:                    if ((cursorArgumentIndex < 0)
411:                            || (cursorArgumentIndex >= arguments.length)) {
412:                        return null;
413:                    }
414:
415:                    return arguments[cursorArgumentIndex];
416:                }
417:
418:                public void setArgumentPosition(int argumentPosition) {
419:                    this .argumentPosition = argumentPosition;
420:                }
421:
422:                public int getArgumentPosition() {
423:                    return this .argumentPosition;
424:                }
425:
426:                public void setArguments(String[] arguments) {
427:                    this .arguments = arguments;
428:                }
429:
430:                public String[] getArguments() {
431:                    return this .arguments;
432:                }
433:
434:                public void setBufferPosition(int bufferPosition) {
435:                    this .bufferPosition = bufferPosition;
436:                }
437:
438:                public int getBufferPosition() {
439:                    return this.bufferPosition;
440:                }
441:            }
442:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.