|
Lines 11-24
Link Here
|
| 11 |
|
11 |
|
| 12 |
package org.eclipse.osgi.framework.internal.core; |
12 |
package org.eclipse.osgi.framework.internal.core; |
| 13 |
|
13 |
|
| 14 |
import java.io.*; |
|
|
| 15 |
import java.lang.reflect.*; |
| 16 |
import java.net.URL; |
| 17 |
import java.util.*; |
| 18 |
import org.eclipse.osgi.framework.console.CommandInterpreter; |
14 |
import org.eclipse.osgi.framework.console.CommandInterpreter; |
| 19 |
import org.eclipse.osgi.framework.console.CommandProvider; |
15 |
|
| 20 |
import org.eclipse.osgi.util.NLS; |
|
|
| 21 |
import org.osgi.framework.Bundle; |
| 22 |
|
16 |
|
| 23 |
/** |
17 |
/** |
| 24 |
* This class knows how to parse and execute the command line arguments to the FrameworkConsole. |
18 |
* This class knows how to parse and execute the command line arguments to the FrameworkConsole. |
|
Lines 30-50
Link Here
|
| 30 |
* |
24 |
* |
| 31 |
* FrameworkCommandInterpreter provides several print methods which handle the "More" command. |
25 |
* FrameworkCommandInterpreter provides several print methods which handle the "More" command. |
| 32 |
*/ |
26 |
*/ |
| 33 |
public class FrameworkCommandInterpreter implements CommandInterpreter { |
27 |
public class FrameworkCommandInterpreter extends BaseCommandInterpreter { |
|
|
28 |
/** Strings used to format other strings */ |
| 29 |
private static final String tab = "\t"; //$NON-NLS-1$ |
| 34 |
|
30 |
|
| 35 |
/** The command line in StringTokenizer form */ |
|
|
| 36 |
private StringTokenizer tok; |
| 37 |
/** The active CommandProviders */ |
| 38 |
private Object[] commandProviders; |
| 39 |
/** The FrameworkConsole */ |
| 40 |
private FrameworkConsole con; |
31 |
private FrameworkConsole con; |
| 41 |
/** The stream to send output to */ |
|
|
| 42 |
private PrintWriter out; |
| 43 |
|
| 44 |
/** Strings used to format other strings */ |
| 45 |
private String tab = "\t"; //$NON-NLS-1$ |
| 46 |
private String newline = "\r\n"; //$NON-NLS-1$ |
| 47 |
private boolean firstCommand = true; |
| 48 |
|
32 |
|
| 49 |
/** |
33 |
/** |
| 50 |
* The maximum number of lines to print without user prompt. |
34 |
* The maximum number of lines to print without user prompt. |
|
Lines 60-103
Link Here
|
| 60 |
* the input parms. |
44 |
* the input parms. |
| 61 |
*/ |
45 |
*/ |
| 62 |
public FrameworkCommandInterpreter(String cmdline, Object[] commandProviders, FrameworkConsole con) { |
46 |
public FrameworkCommandInterpreter(String cmdline, Object[] commandProviders, FrameworkConsole con) { |
| 63 |
tok = new StringTokenizer(cmdline); |
47 |
super(cmdline, commandProviders, con.out); |
| 64 |
this.commandProviders = commandProviders; |
|
|
| 65 |
this.con = con; |
48 |
this.con = con; |
| 66 |
this.out = con.getWriter(); |
|
|
| 67 |
} |
49 |
} |
| 68 |
|
50 |
|
| 69 |
/** |
|
|
| 70 |
Get the next argument in the input. |
| 71 |
|
| 72 |
E.g. if the commandline is hello world, the _hello method |
| 73 |
will get "world" as the first argument. |
| 74 |
|
| 75 |
@return A string containing the next argument on the command line |
| 76 |
*/ |
| 77 |
public String nextArgument() { |
| 78 |
if (tok == null || !tok.hasMoreElements()) { |
| 79 |
return null; |
| 80 |
} |
| 81 |
String token = tok.nextToken(); |
| 82 |
//check for quotes |
| 83 |
int index = token.indexOf('"'); |
| 84 |
if (index != -1) { |
| 85 |
//if we only have one quote, find the second quote |
| 86 |
if (index == token.lastIndexOf('"')) { |
| 87 |
token += tok.nextToken("\""); //$NON-NLS-1$ |
| 88 |
} |
| 89 |
StringBuffer buf = new StringBuffer(token); |
| 90 |
|
| 91 |
//strip quotes |
| 92 |
while (index != -1) { |
| 93 |
buf.deleteCharAt(index); |
| 94 |
token = buf.toString(); |
| 95 |
index = token.indexOf('"'); |
| 96 |
} |
| 97 |
return buf.toString(); |
| 98 |
} |
| 99 |
return (token); |
| 100 |
} |
| 101 |
|
51 |
|
| 102 |
/** |
52 |
/** |
| 103 |
Execute a command line as if it came from the end user. |
53 |
Execute a command line as if it came from the end user. |
|
Lines 111-119
Link Here
|
| 111 |
@return The object returned by the method executed. |
61 |
@return The object returned by the method executed. |
| 112 |
*/ |
62 |
*/ |
| 113 |
public Object execute(String cmd) { |
63 |
public Object execute(String cmd) { |
| 114 |
if (!firstCommand) |
|
|
| 115 |
return innerExecute(cmd); |
| 116 |
firstCommand = false; |
| 117 |
resetLineCount(); |
64 |
resetLineCount(); |
| 118 |
Object retval = null; |
65 |
Object retval = null; |
| 119 |
// handle "more" command here |
66 |
// handle "more" command here |
|
Lines 134-185
Link Here
|
| 134 |
} |
81 |
} |
| 135 |
return retval; |
82 |
return retval; |
| 136 |
} |
83 |
} |
| 137 |
Class[] parameterTypes = new Class[] {CommandInterpreter.class}; |
84 |
return super.execute(cmd); |
| 138 |
Object[] parameters = new Object[] {this}; |
|
|
| 139 |
boolean executed = false; |
| 140 |
int size = commandProviders.length; |
| 141 |
for (int i = 0; !executed && (i < size); i++) { |
| 142 |
try { |
| 143 |
Object target = commandProviders[i]; |
| 144 |
Method method = target.getClass().getMethod("_" + cmd, parameterTypes); //$NON-NLS-1$ |
| 145 |
retval = method.invoke(target, parameters); |
| 146 |
executed = true; // stop after the command has been found |
| 147 |
} catch (NoSuchMethodException ite) { |
| 148 |
// keep going - maybe another command provider will be able to execute this command |
| 149 |
} catch (InvocationTargetException ite) { |
| 150 |
executed = true; // don't want to keep trying - we found the method but got an error |
| 151 |
printStackTrace(ite.getTargetException()); |
| 152 |
} catch (Exception ee) { |
| 153 |
executed = true; // don't want to keep trying - we got an error we don't understand |
| 154 |
printStackTrace(ee); |
| 155 |
} |
| 156 |
} |
| 157 |
// if no command was found to execute, display help for all registered command providers |
| 158 |
if (!executed) { |
| 159 |
for (int i = 0; i < size; i++) { |
| 160 |
try { |
| 161 |
CommandProvider commandProvider = (CommandProvider) commandProviders[i]; |
| 162 |
out.print(commandProvider.getHelp()); |
| 163 |
out.flush(); |
| 164 |
} catch (Exception ee) { |
| 165 |
printStackTrace(ee); |
| 166 |
} |
| 167 |
} |
| 168 |
// call help for the more command provided by this class |
| 169 |
out.print(getHelp()); |
| 170 |
out.flush(); |
| 171 |
} |
| 172 |
return retval; |
| 173 |
} |
| 174 |
|
| 175 |
private Object innerExecute(String cmd) { |
| 176 |
if (cmd != null && cmd.length() > 0) { |
| 177 |
CommandInterpreter intcp = new FrameworkCommandInterpreter(cmd, commandProviders, con); |
| 178 |
String command = intcp.nextArgument(); |
| 179 |
if (command != null) |
| 180 |
return intcp.execute(command); |
| 181 |
} |
| 182 |
return null; |
| 183 |
} |
85 |
} |
| 184 |
|
86 |
|
| 185 |
/** |
87 |
/** |
|
Lines 208-214
Link Here
|
| 208 |
if (lines < 0) { |
110 |
if (lines < 0) { |
| 209 |
throw new IllegalArgumentException(ConsoleMsg.CONSOLE_LINES_TO_SCROLL_NEGATIVE_ERROR); |
111 |
throw new IllegalArgumentException(ConsoleMsg.CONSOLE_LINES_TO_SCROLL_NEGATIVE_ERROR); |
| 210 |
} |
112 |
} |
| 211 |
|
|
|
| 212 |
maxLineCount = lines; |
113 |
maxLineCount = lines; |
| 213 |
} |
114 |
} |
| 214 |
|
115 |
|
|
Lines 220-376
Link Here
|
| 220 |
} |
121 |
} |
| 221 |
|
122 |
|
| 222 |
/** |
123 |
/** |
| 223 |
* Prints a string to the output medium (appended with newline character). |
|
|
| 224 |
* <p> |
| 225 |
* This method does not increment the line counter for the 'more' prompt. |
| 226 |
* |
| 227 |
* @param o the string to be printed |
| 228 |
*/ |
| 229 |
private void printline(Object o) { |
| 230 |
print(o + newline); |
| 231 |
} |
| 232 |
|
| 233 |
/** |
| 234 |
* Prints an object to the outputstream |
| 235 |
* |
| 236 |
* @param o the object to be printed |
| 237 |
*/ |
| 238 |
public void print(Object o) { |
| 239 |
synchronized (out) { |
| 240 |
check4More(); |
| 241 |
out.print(o); |
| 242 |
out.flush(); |
| 243 |
} |
| 244 |
} |
| 245 |
|
| 246 |
/** |
| 247 |
* Prints a empty line to the outputstream |
| 248 |
*/ |
| 249 |
public void println() { |
| 250 |
println(""); //$NON-NLS-1$ |
| 251 |
} |
| 252 |
|
| 253 |
/** |
| 254 |
* Print a stack trace including nested exceptions. |
| 255 |
* @param t The offending exception |
| 256 |
*/ |
| 257 |
public void printStackTrace(Throwable t) { |
| 258 |
t.printStackTrace(out); |
| 259 |
|
| 260 |
Method[] methods = t.getClass().getMethods(); |
| 261 |
|
| 262 |
int size = methods.length; |
| 263 |
Class throwable = Throwable.class; |
| 264 |
|
| 265 |
for (int i = 0; i < size; i++) { |
| 266 |
Method method = methods[i]; |
| 267 |
|
| 268 |
if (Modifier.isPublic(method.getModifiers()) && method.getName().startsWith("get") && throwable.isAssignableFrom(method.getReturnType()) && (method.getParameterTypes().length == 0)) { //$NON-NLS-1$ |
| 269 |
try { |
| 270 |
Throwable nested = (Throwable) method.invoke(t, null); |
| 271 |
|
| 272 |
if ((nested != null) && (nested != t)) { |
| 273 |
out.println(ConsoleMsg.CONSOLE_NESTED_EXCEPTION); |
| 274 |
printStackTrace(nested); |
| 275 |
} |
| 276 |
} catch (IllegalAccessException e) { |
| 277 |
} catch (InvocationTargetException e) { |
| 278 |
} |
| 279 |
} |
| 280 |
} |
| 281 |
} |
| 282 |
|
| 283 |
/** |
| 284 |
* Prints an object to the output medium (appended with newline character). |
| 285 |
* <p> |
| 286 |
* If running on the target environment, the user is prompted with '--more' |
| 287 |
* if more than the configured number of lines have been printed without user prompt. |
| 288 |
* This enables the user of the program to have control over scrolling. |
| 289 |
* <p> |
| 290 |
* For this to work properly you should not embed "\n" etc. into the string. |
| 291 |
* |
| 292 |
* @param o the object to be printed |
| 293 |
*/ |
| 294 |
public void println(Object o) { |
| 295 |
if (o == null) { |
| 296 |
return; |
| 297 |
} |
| 298 |
synchronized (out) { |
| 299 |
check4More(); |
| 300 |
printline(o); |
| 301 |
currentLineCount++; |
| 302 |
currentLineCount += o.toString().length() / 80; |
| 303 |
} |
| 304 |
} |
| 305 |
|
| 306 |
/** |
| 307 |
* Prints the given dictionary sorted by keys. |
| 308 |
* |
| 309 |
* @param dic the dictionary to print |
| 310 |
* @param title the header to print above the key/value pairs |
| 311 |
*/ |
| 312 |
public void printDictionary(Dictionary dic, String title) { |
| 313 |
if (dic == null) |
| 314 |
return; |
| 315 |
|
| 316 |
int count = dic.size(); |
| 317 |
String[] keys = new String[count]; |
| 318 |
Enumeration keysEnum = dic.keys(); |
| 319 |
int i = 0; |
| 320 |
while (keysEnum.hasMoreElements()) { |
| 321 |
keys[i++] = (String) keysEnum.nextElement(); |
| 322 |
} |
| 323 |
Util.sort(keys); |
| 324 |
|
| 325 |
if (title != null) { |
| 326 |
println(title); |
| 327 |
} |
| 328 |
for (i = 0; i < count; i++) { |
| 329 |
println(" " + keys[i] + " = " + dic.get(keys[i])); //$NON-NLS-1$//$NON-NLS-2$ |
| 330 |
} |
| 331 |
println(); |
| 332 |
} |
| 333 |
|
| 334 |
/** |
| 335 |
* Prints the given bundle resource if it exists |
| 336 |
* |
| 337 |
* @param bundle the bundle containing the resource |
| 338 |
* @param resource the resource to print |
| 339 |
*/ |
| 340 |
public void printBundleResource(Bundle bundle, String resource) { |
| 341 |
URL entry = null; |
| 342 |
entry = bundle.getEntry(resource); |
| 343 |
if (entry != null) { |
| 344 |
try { |
| 345 |
println(resource); |
| 346 |
InputStream in = entry.openStream(); |
| 347 |
byte[] buffer = new byte[1024]; |
| 348 |
int read = 0; |
| 349 |
try { |
| 350 |
while ((read = in.read(buffer)) != -1) |
| 351 |
print(new String(buffer, 0, read)); |
| 352 |
} finally { |
| 353 |
if (in != null) { |
| 354 |
try { |
| 355 |
in.close(); |
| 356 |
} catch (IOException e) { |
| 357 |
} |
| 358 |
} |
| 359 |
} |
| 360 |
} catch (Exception e) { |
| 361 |
System.err.println(NLS.bind(ConsoleMsg.CONSOLE_ERROR_READING_RESOURCE, resource)); |
| 362 |
} |
| 363 |
} else { |
| 364 |
println(NLS.bind(ConsoleMsg.CONSOLE_RESOURCE_NOT_IN_BUNDLE, resource, bundle.toString())); |
| 365 |
} |
| 366 |
} |
| 367 |
|
| 368 |
/** |
| 369 |
* Displays the more... prompt if the max line count has been reached |
124 |
* Displays the more... prompt if the max line count has been reached |
| 370 |
* and waits for the operator to hit enter. |
125 |
* and waits for the operator to hit enter. |
| 371 |
* |
126 |
* |
| 372 |
*/ |
127 |
*/ |
| 373 |
private void check4More() { |
128 |
protected void check4More() { |
| 374 |
int max = getMaximumLinesToScroll(); |
129 |
int max = getMaximumLinesToScroll(); |
| 375 |
if (max > 0) { |
130 |
if (max > 0) { |
| 376 |
if (currentLineCount >= max) { |
131 |
if (currentLineCount >= max) { |
|
Lines 407-413
Link Here
|
| 407 |
* Toggles the use of the more prompt for displayed output. |
162 |
* Toggles the use of the more prompt for displayed output. |
| 408 |
* |
163 |
* |
| 409 |
*/ |
164 |
*/ |
| 410 |
public void _more() throws Exception { |
165 |
private void _more() throws Exception { |
| 411 |
if (confirm(ConsoleMsg.CONSOLE_CONFIRM_MORE, true)) { |
166 |
if (confirm(ConsoleMsg.CONSOLE_CONFIRM_MORE, true)) { |
| 412 |
int lines = prompt(newline + ConsoleMsg.CONSOLE_MORE_ENTER_LINES, 24); |
167 |
int lines = prompt(newline + ConsoleMsg.CONSOLE_MORE_ENTER_LINES, 24); |
| 413 |
setMaximumLinesToScroll(lines); |
168 |
setMaximumLinesToScroll(lines); |
|
Lines 430-436
Link Here
|
| 430 |
* |
185 |
* |
| 431 |
* @return <code>true</code> if the user confirms; <code>false</code> otherwise. |
186 |
* @return <code>true</code> if the user confirms; <code>false</code> otherwise. |
| 432 |
*/ |
187 |
*/ |
| 433 |
protected boolean confirm(String string, boolean defaultAnswer) { |
188 |
private boolean confirm(String string, boolean defaultAnswer) { |
| 434 |
synchronized (out) { |
189 |
synchronized (out) { |
| 435 |
if (string.length() > 0) { |
190 |
if (string.length() > 0) { |
| 436 |
print(string); |
191 |
print(string); |
|
Lines 461-467
Link Here
|
| 461 |
* @return The user provided string or the defaultAnswer, |
216 |
* @return The user provided string or the defaultAnswer, |
| 462 |
* if user provided string was empty. |
217 |
* if user provided string was empty. |
| 463 |
*/ |
218 |
*/ |
| 464 |
protected String prompt(String string, String defaultAnswer) { |
219 |
private String prompt(String string, String defaultAnswer) { |
| 465 |
if (string.length() > 0) { |
220 |
if (string.length() > 0) { |
| 466 |
if (defaultAnswer.length() > 0) { |
221 |
if (defaultAnswer.length() > 0) { |
| 467 |
StringBuffer buf = new StringBuffer(256); |
222 |
StringBuffer buf = new StringBuffer(256); |
|
Lines 493-499
Link Here
|
| 493 |
* @return The user provided integer or the defaultAnswer, |
248 |
* @return The user provided integer or the defaultAnswer, |
| 494 |
* if user provided an empty input. |
249 |
* if user provided an empty input. |
| 495 |
*/ |
250 |
*/ |
| 496 |
protected int prompt(String string, int defaultAnswer) { |
251 |
private int prompt(String string, int defaultAnswer) { |
| 497 |
Integer i = new Integer(defaultAnswer); |
252 |
Integer i = new Integer(defaultAnswer); |
| 498 |
int answer; |
253 |
int answer; |
| 499 |
for (int j = 0; j < 3; j++) { |
254 |
for (int j = 0; j < 3; j++) { |
|
Lines 510-513
Link Here
|
| 510 |
println(ConsoleMsg.CONSOLE_TOO_MUCH_INVALID_INPUT); |
265 |
println(ConsoleMsg.CONSOLE_TOO_MUCH_INVALID_INPUT); |
| 511 |
return defaultAnswer; |
266 |
return defaultAnswer; |
| 512 |
} |
267 |
} |
|
|
268 |
|
| 269 |
protected CommandInterpreter getInnerCommandInterpreter(String cmd) { |
| 270 |
return new FrameworkCommandInterpreter(cmd, commandProviders, con); |
| 271 |
} |
| 272 |
|
| 273 |
protected void incrementLineCount(int i) { |
| 274 |
currentLineCount += i; |
| 275 |
} |
| 513 |
} |
276 |
} |