1 11 package org.eclipse.core.commands; 12 13 import java.io.BufferedWriter ; 14 import java.io.IOException ; 15 import java.io.StringWriter ; 16 17 import org.eclipse.core.commands.common.NotDefinedException; 18 import org.eclipse.core.commands.util.Tracing; 19 import org.eclipse.core.internal.commands.util.Util; 20 import org.eclipse.core.runtime.ISafeRunnable; 21 import org.eclipse.core.runtime.ListenerList; 22 import org.eclipse.core.runtime.SafeRunner; 23 24 53 public final class Command extends NamedHandleObjectWithState implements 54 Comparable { 55 56 60 public static boolean DEBUG_COMMAND_EXECUTION = false; 61 62 66 public static boolean DEBUG_HANDLERS = false; 67 68 73 public static String DEBUG_HANDLERS_COMMAND_ID = null; 74 75 79 private Category category = null; 80 81 85 private transient ListenerList executionListeners = null; 86 87 91 private transient IHandler handler = null; 92 93 100 private String helpContextId; 101 102 107 private IParameter[] parameters = null; 108 109 115 private ParameterType returnType = null; 116 117 123 private IHandlerListener handlerListener; 124 125 135 Command(final String id) { 136 super(id); 137 } 138 139 146 public final void addCommandListener(final ICommandListener commandListener) { 147 if (commandListener == null) { 148 throw new NullPointerException ("Cannot add a null command listener"); } 150 addListenerObject(commandListener); 151 } 152 153 160 public final void addExecutionListener( 161 final IExecutionListener executionListener) { 162 if (executionListener == null) { 163 throw new NullPointerException ( 164 "Cannot add a null execution listener"); } 166 167 if (executionListeners == null) { 168 executionListeners = new ListenerList(ListenerList.IDENTITY); 169 } 170 171 executionListeners.add(executionListener); 172 } 173 174 191 public void addState(final String id, final State state) { 192 super.addState(id, state); 193 state.setId(id); 194 if (handler instanceof IObjectWithState) { 195 ((IObjectWithState) handler).addState(id, state); 196 } 197 } 198 199 209 public final int compareTo(final Object object) { 210 final Command castedObject = (Command) object; 211 int compareTo = Util.compare(category, castedObject.category); 212 if (compareTo == 0) { 213 compareTo = Util.compare(defined, castedObject.defined); 214 if (compareTo == 0) { 215 compareTo = Util.compare(description, castedObject.description); 216 if (compareTo == 0) { 217 compareTo = Util.compare(handler, castedObject.handler); 218 if (compareTo == 0) { 219 compareTo = Util.compare(id, castedObject.id); 220 if (compareTo == 0) { 221 compareTo = Util.compare(name, castedObject.name); 222 if (compareTo == 0) { 223 compareTo = Util.compare(parameters, 224 castedObject.parameters); 225 } 226 } 227 } 228 } 229 } 230 } 231 return compareTo; 232 } 233 234 251 public final void define(final String name, final String description, 252 final Category category) { 253 define(name, description, category, null); 254 } 255 256 276 public final void define(final String name, final String description, 277 final Category category, final IParameter[] parameters) { 278 define(name, description, category, parameters, null); 279 } 280 281 306 public final void define(final String name, final String description, 307 final Category category, final IParameter[] parameters, 308 ParameterType returnType) { 309 define(name, description, category, parameters, returnType, null); 310 } 311 312 341 public final void define(final String name, final String description, 342 final Category category, final IParameter[] parameters, 343 ParameterType returnType, final String helpContextId) { 344 if (name == null) { 345 throw new NullPointerException ( 346 "The name of a command cannot be null"); } 348 349 if (category == null) { 350 throw new NullPointerException ( 351 "The category of a command cannot be null"); } 353 354 final boolean definedChanged = !this.defined; 355 this.defined = true; 356 357 final boolean nameChanged = !Util.equals(this.name, name); 358 this.name = name; 359 360 final boolean descriptionChanged = !Util.equals(this.description, 361 description); 362 this.description = description; 363 364 final boolean categoryChanged = !Util.equals(this.category, category); 365 this.category = category; 366 367 final boolean parametersChanged = !Util.equals(this.parameters, 368 parameters); 369 this.parameters = parameters; 370 371 final boolean returnTypeChanged = !Util.equals(this.returnType, 372 returnType); 373 this.returnType = returnType; 374 375 final boolean helpContextIdChanged = !Util.equals(this.helpContextId, 376 helpContextId); 377 this.helpContextId = helpContextId; 378 379 fireCommandChanged(new CommandEvent(this, categoryChanged, 380 definedChanged, descriptionChanged, false, nameChanged, 381 parametersChanged, returnTypeChanged, helpContextIdChanged)); 382 } 383 384 404 public final Object execute(final ExecutionEvent event) 405 throws ExecutionException, NotHandledException { 406 firePreExecute(event); 407 final IHandler handler = this.handler; 408 409 if ((handler != null) && (handler.isHandled())) { 411 try { 412 final Object returnValue = handler.execute(event); 413 firePostExecuteSuccess(returnValue); 414 return returnValue; 415 } catch (final ExecutionException e) { 416 firePostExecuteFailure(e); 417 throw e; 418 } 419 } 420 421 final NotHandledException e = new NotHandledException( 422 "There is no handler to execute. " + getId()); fireNotHandled(e); 424 throw e; 425 } 426 427 451 public final Object executeWithChecks(final ExecutionEvent event) 452 throws ExecutionException, NotDefinedException, 453 NotEnabledException, NotHandledException { 454 firePreExecute(event); 455 final IHandler handler = this.handler; 456 457 if (!isDefined()) { 458 final NotDefinedException exception = new NotDefinedException( 459 "Trying to execute a command that is not defined. " + getId()); 461 fireNotDefined(exception); 462 throw exception; 463 } 464 465 if ((handler != null) && (handler.isHandled())) { 467 if (!isEnabled()) { 468 final NotEnabledException exception = new NotEnabledException( 469 "Trying to execute the disabled command " + getId()); fireNotEnabled(exception); 471 throw exception; 472 } 473 474 try { 475 final Object returnValue = handler.execute(event); 476 firePostExecuteSuccess(returnValue); 477 return returnValue; 478 } catch (final ExecutionException e) { 479 firePostExecuteFailure(e); 480 throw e; 481 } 482 } 483 484 final NotHandledException e = new NotHandledException( 485 "There is no handler to execute for command " + getId()); fireNotHandled(e); 487 throw e; 488 } 489 490 497 private final void fireCommandChanged(final CommandEvent commandEvent) { 498 if (commandEvent == null) { 499 throw new NullPointerException ("Cannot fire a null event"); } 501 502 final Object [] listeners = getListeners(); 503 for (int i = 0; i < listeners.length; i++) { 504 final ICommandListener listener = (ICommandListener) listeners[i]; 505 SafeRunner.run(new ISafeRunnable() { 506 public void handleException(Throwable exception) { 507 } 508 509 public void run() throws Exception { 510 listener.commandChanged(commandEvent); 511 } 512 }); 513 } 514 } 515 516 525 private final void fireNotDefined(final NotDefinedException e) { 526 if (DEBUG_COMMAND_EXECUTION) { 528 Tracing.printTrace("COMMANDS", "execute" + Tracing.SEPARATOR + "not defined: id=" + getId() + "; exception=" + e); } 531 532 if (executionListeners != null) { 533 final Object [] listeners = executionListeners.getListeners(); 534 for (int i = 0; i < listeners.length; i++) { 535 final Object object = listeners[i]; 536 if (object instanceof IExecutionListenerWithChecks) { 537 final IExecutionListenerWithChecks listener = (IExecutionListenerWithChecks) object; 538 listener.notDefined(getId(), e); 539 } 540 } 541 } 542 } 543 544 553 private final void fireNotEnabled(final NotEnabledException e) { 554 if (DEBUG_COMMAND_EXECUTION) { 556 Tracing.printTrace("COMMANDS", "execute" + Tracing.SEPARATOR + "not enabled: id=" + getId() + "; exception=" + e); } 559 560 if (executionListeners != null) { 561 final Object [] listeners = executionListeners.getListeners(); 562 for (int i = 0; i < listeners.length; i++) { 563 final Object object = listeners[i]; 564 if (object instanceof IExecutionListenerWithChecks) { 565 final IExecutionListenerWithChecks listener = (IExecutionListenerWithChecks) object; 566 listener.notEnabled(getId(), e); 567 } 568 } 569 } 570 } 571 572 580 private final void fireNotHandled(final NotHandledException e) { 581 if (DEBUG_COMMAND_EXECUTION) { 583 Tracing.printTrace("COMMANDS", "execute" + Tracing.SEPARATOR + "not handled: id=" + getId() + "; exception=" + e); } 586 587 if (executionListeners != null) { 588 final Object [] listeners = executionListeners.getListeners(); 589 for (int i = 0; i < listeners.length; i++) { 590 final IExecutionListener listener = (IExecutionListener) listeners[i]; 591 listener.notHandled(getId(), e); 592 } 593 } 594 } 595 596 605 private final void firePostExecuteFailure(final ExecutionException e) { 606 if (DEBUG_COMMAND_EXECUTION) { 608 Tracing.printTrace("COMMANDS", "execute" + Tracing.SEPARATOR + "failure: id=" + getId() + "; exception=" + e); } 611 612 if (executionListeners != null) { 613 final Object [] listeners = executionListeners.getListeners(); 614 for (int i = 0; i < listeners.length; i++) { 615 final IExecutionListener listener = (IExecutionListener) listeners[i]; 616 listener.postExecuteFailure(getId(), e); 617 } 618 } 619 } 620 621 628 private final void firePostExecuteSuccess(final Object returnValue) { 629 if (DEBUG_COMMAND_EXECUTION) { 631 Tracing.printTrace("COMMANDS", "execute" + Tracing.SEPARATOR + "success: id=" + getId() + "; returnValue=" + returnValue); 634 } 635 636 if (executionListeners != null) { 637 final Object [] listeners = executionListeners.getListeners(); 638 for (int i = 0; i < listeners.length; i++) { 639 final IExecutionListener listener = (IExecutionListener) listeners[i]; 640 listener.postExecuteSuccess(getId(), returnValue); 641 } 642 } 643 } 644 645 652 private final void firePreExecute(final ExecutionEvent event) { 653 if (DEBUG_COMMAND_EXECUTION) { 655 Tracing.printTrace("COMMANDS", "execute" + Tracing.SEPARATOR + "starting: id=" + getId() + "; event=" + event); } 658 659 if (executionListeners != null) { 660 final Object [] listeners = executionListeners.getListeners(); 661 for (int i = 0; i < listeners.length; i++) { 662 final IExecutionListener listener = (IExecutionListener) listeners[i]; 663 listener.preExecute(getId(), event); 664 } 665 } 666 } 667 668 675 public final Category getCategory() throws NotDefinedException { 676 if (!isDefined()) { 677 throw new NotDefinedException( 678 "Cannot get the category from an undefined command. " + id); 680 } 681 682 return category; 683 } 684 685 696 public final IHandler getHandler() { 697 return handler; 698 } 699 700 709 final String getHelpContextId() { 710 return helpContextId; 711 } 712 713 725 public final IParameter getParameter(final String parameterId) 726 throws NotDefinedException { 727 if (!isDefined()) { 728 throw new NotDefinedException( 729 "Cannot get a parameter from an undefined command. " + id); 731 } 732 733 if (parameters == null) { 734 return null; 735 } 736 737 for (int i = 0; i < parameters.length; i++) { 738 final IParameter parameter = parameters[i]; 739 if (parameter.getId().equals(parameterId)) { 740 return parameter; 741 } 742 } 743 744 return null; 745 } 746 747 756 public final IParameter[] getParameters() throws NotDefinedException { 757 if (!isDefined()) { 758 throw new NotDefinedException( 759 "Cannot get the parameters from an undefined command. " + id); 761 } 762 763 if ((parameters == null) || (parameters.length == 0)) { 764 return null; 765 } 766 767 final IParameter[] returnValue = new IParameter[parameters.length]; 768 System.arraycopy(parameters, 0, returnValue, 0, parameters.length); 769 return returnValue; 770 } 771 772 787 public final ParameterType getParameterType(final String parameterId) 788 throws NotDefinedException { 789 final IParameter parameter = getParameter(parameterId); 790 if (parameter instanceof ITypedParameter) { 791 final ITypedParameter parameterWithType = (ITypedParameter) parameter; 792 return parameterWithType.getParameterType(); 793 } 794 return null; 795 } 796 797 809 public final ParameterType getReturnType() throws NotDefinedException { 810 if (!isDefined()) { 811 throw new NotDefinedException( 812 "Cannot get the return type of an undefined command. " + id); 814 } 815 816 return returnType; 817 } 818 819 826 public final boolean isEnabled() { 827 if (handler == null) { 828 return false; 829 } 830 831 return handler.isEnabled(); 832 } 833 834 841 public final boolean isHandled() { 842 if (handler == null) { 843 return false; 844 } 845 846 return handler.isHandled(); 847 } 848 849 856 public final void removeCommandListener( 857 final ICommandListener commandListener) { 858 if (commandListener == null) { 859 throw new NullPointerException ( 860 "Cannot remove a null command listener"); } 862 863 removeListenerObject(commandListener); 864 } 865 866 873 public final void removeExecutionListener( 874 final IExecutionListener executionListener) { 875 if (executionListener == null) { 876 throw new NullPointerException ( 877 "Cannot remove a null execution listener"); } 879 880 if (executionListeners != null) { 881 executionListeners.remove(executionListener); 882 if (executionListeners.isEmpty()) { 883 executionListeners = null; 884 } 885 } 886 } 887 888 900 public void removeState(final String stateId) { 901 if (handler instanceof IObjectWithState) { 902 ((IObjectWithState) handler).removeState(stateId); 903 } 904 super.removeState(stateId); 905 } 906 907 918 public final boolean setHandler(final IHandler handler) { 919 if (Util.equals(handler, this.handler)) { 920 return false; 921 } 922 923 final String [] stateIds = getStateIds(); 925 if (stateIds != null) { 926 for (int i = 0; i < stateIds.length; i++) { 927 final String stateId = stateIds[i]; 928 if (this.handler instanceof IObjectWithState) { 929 ((IObjectWithState) this.handler).removeState(stateId); 930 } 931 if (handler instanceof IObjectWithState) { 932 final State stateToAdd = getState(stateId); 933 ((IObjectWithState) handler).addState(stateId, stateToAdd); 934 } 935 } 936 } 937 938 boolean enabled = isEnabled(); 939 if (this.handler != null) { 940 this.handler.removeHandlerListener(getHandlerListener()); 941 } 942 943 this.handler = handler; 945 if (this.handler != null) { 946 this.handler.addHandlerListener(getHandlerListener()); 947 } 948 string = null; 949 950 if ((DEBUG_HANDLERS) 952 && ((DEBUG_HANDLERS_COMMAND_ID == null) || (DEBUG_HANDLERS_COMMAND_ID 953 .equals(id)))) { 954 final StringBuffer buffer = new StringBuffer ("Command('"); buffer.append(id); 956 buffer.append("') has changed to "); if (handler == null) { 958 buffer.append("no handler"); } else { 960 buffer.append('\''); 961 buffer.append(handler); 962 buffer.append("' as its handler"); } 964 Tracing.printTrace("HANDLERS", buffer.toString()); } 966 967 fireCommandChanged(new CommandEvent(this, false, false, false, true, 969 false, false, false, false, enabled != isEnabled())); 970 971 return true; 972 } 973 974 977 private IHandlerListener getHandlerListener() { 978 if (handlerListener == null) { 979 handlerListener = new IHandlerListener() { 980 public void handlerChanged(HandlerEvent handlerEvent) { 981 boolean enabledChanged = handlerEvent.isEnabledChanged(); 982 boolean handledChanged = handlerEvent.isHandledChanged(); 983 fireCommandChanged(new CommandEvent(Command.this, false, 984 false, false, handledChanged, false, false, false, 985 false, enabledChanged)); 986 } 987 }; 988 } 989 return handlerListener; 990 } 991 992 998 public final String toString() { 999 if (string == null) { 1000 final StringWriter sw = new StringWriter (); 1001 final BufferedWriter buffer = new BufferedWriter (sw); 1002 try { 1003 buffer.write("Command("); buffer.write(id); 1005 buffer.write(','); 1006 buffer.write(name==null?"":name); buffer.write(','); 1008 buffer.newLine(); 1009 buffer.write("\t\t"); buffer.write(description==null?"":description); buffer.write(','); 1012 buffer.newLine(); 1013 buffer.write("\t\t"); buffer.write(category==null?"":category.toString()); buffer.write(','); 1016 buffer.newLine(); 1017 buffer.write("\t\t"); buffer.write(handler==null?"":handler.toString()); buffer.write(','); 1020 buffer.newLine(); 1021 buffer.write("\t\t"); buffer.write(parameters==null?"":parameters.toString()); buffer.write(','); 1024 buffer.write(returnType==null?"":returnType.toString()); buffer.write(','); 1026 buffer.write(""+defined); buffer.write(')'); 1028 buffer.flush(); 1029 } catch (IOException e) { 1030 } 1032 string = sw.toString(); 1033 } 1034 return string; 1035 } 1036 1037 1042 public final void undefine() { 1043 boolean enabledChanged = isEnabled(); 1044 1045 string = null; 1046 1047 final boolean definedChanged = defined; 1048 defined = false; 1049 1050 final boolean nameChanged = name != null; 1051 name = null; 1052 1053 final boolean descriptionChanged = description != null; 1054 description = null; 1055 1056 final boolean categoryChanged = category != null; 1057 category = null; 1058 1059 final boolean parametersChanged = parameters != null; 1060 parameters = null; 1061 1062 final boolean returnTypeChanged = returnType != null; 1063 returnType = null; 1064 1065 final String [] stateIds = getStateIds(); 1066 if (stateIds != null) { 1067 if (handler instanceof IObjectWithState) { 1068 final IObjectWithState handlerWithState = (IObjectWithState) handler; 1069 for (int i = 0; i < stateIds.length; i++) { 1070 final String stateId = stateIds[i]; 1071 handlerWithState.removeState(stateId); 1072 1073 final State state = getState(stateId); 1074 removeState(stateId); 1075 state.dispose(); 1076 } 1077 } else { 1078 for (int i = 0; i < stateIds.length; i++) { 1079 final String stateId = stateIds[i]; 1080 final State state = getState(stateId); 1081 removeState(stateId); 1082 state.dispose(); 1083 } 1084 } 1085 } 1086 1087 fireCommandChanged(new CommandEvent(this, categoryChanged, 1088 definedChanged, descriptionChanged, false, nameChanged, 1089 parametersChanged, returnTypeChanged, false, enabledChanged)); 1090 } 1091} 1092 | Popular Tags |