/* (non-Javadoc)
   * @see org.eclipse.tcf.te.tcf.core.scripting.interfaces.IScriptLauncher#dispose()
   */
  @Override
  public void dispose() {
    if (channel != null) {
      // Remove the trace listener
      if (traceListener != null) {
        ((AbstractChannel) channel).removeTraceListener(traceListener);
        traceListener = null;
      }

      // Close the channel as all disposal is done
      Tcf.getChannelManager().closeChannel(channel);

      // Fire the stop event
      ScriptEvent event = new ScriptEvent(ScriptLauncher.this, ScriptEvent.Type.STOP, null);
      EventManager.getInstance().fireEvent(event);

      // Dissociate the channel
      channel = null;
    }
  }
Exemple #2
0
 /*
  * (non-Javadoc)
  * @see org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.Operation#run(org.eclipse.core.runtime.IProgressMonitor)
  */
 @Override
 public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
   IChannel channel = null;
   try {
     channel = openChannel(node.peerNode.getPeer());
     if (channel != null) {
       IFileSystem service = Operation.getBlockingFileSystem(channel);
       if (service != null) {
         final TCFFileSystemException[] errors = new TCFFileSystemException[1];
         String path = node.getLocation(true);
         service.setstat(
             path,
             attrs,
             new DoneSetStat() {
               @Override
               public void doneSetStat(IToken token, FileSystemException error) {
                 if (error == null) {
                   node.setAttributes(attrs);
                 } else {
                   errors[0] = newTCFException(IStatus.WARNING, error);
                 }
               }
             });
         if (errors[0] != null) {
           throw errors[0];
         }
       } else {
         String message =
             NLS.bind(Messages.Operation_NoFileSystemError, node.peerNode.getPeerId());
         throw new TCFFileSystemException(IStatus.ERROR, message);
       }
     }
   } catch (TCFException e) {
     throw new InvocationTargetException(e);
   } finally {
     if (channel != null) Tcf.getChannelManager().closeChannel(channel);
   }
 }
  /* (non-Javadoc)
   * @see org.eclipse.tcf.te.tcf.core.scripting.interfaces.IScriptLauncher#launch(org.eclipse.tcf.protocol.IPeer, org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer, org.eclipse.tcf.te.runtime.interfaces.callback.ICallback)
   */
  @Override
  public void launch(
      final IPeer peer, final IPropertiesContainer properties, final ICallback callback) {
    Assert.isNotNull(peer);
    Assert.isNotNull(properties);

    // Normalize the callback
    if (callback == null) {
      this.callback =
          new Callback() {
            /* (non-Javadoc)
             * @see org.eclipse.tcf.te.runtime.callback.Callback#internalDone(java.lang.Object, org.eclipse.core.runtime.IStatus)
             */
            @Override
            public void internalDone(Object caller, IStatus status) {}
          };
    } else {
      this.callback = callback;
    }

    // Remember the process properties
    this.properties = properties;

    // Open a dedicated channel to the given peer
    Map<String, Boolean> flags = new HashMap<String, Boolean>();
    flags.put(IChannelManager.FLAG_FORCE_NEW, Boolean.TRUE);
    Tcf.getChannelManager()
        .openChannel(
            peer,
            flags,
            new IChannelManager.DoneOpenChannel() {
              /* (non-Javadoc)
               * @see org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager.DoneOpenChannel#doneOpenChannel(java.lang.Throwable, org.eclipse.tcf.protocol.IChannel)
               */
              @Override
              public void doneOpenChannel(Throwable error, IChannel channel) {
                if (error == null) {
                  ScriptLauncher.this.channel = channel;

                  // Fire the start event
                  ScriptEvent event =
                      new ScriptEvent(ScriptLauncher.this, ScriptEvent.Type.START, null);
                  EventManager.getInstance().fireEvent(event);

                  // Attach a channel listener so we can dispose ourself if the channel
                  // is closed from the remote side.
                  channel.addChannelListener(
                      new IChannelListener() {
                        /* (non-Javadoc)
                         * @see org.eclipse.tcf.protocol.IChannel.IChannelListener#onChannelOpened()
                         */
                        @Override
                        public void onChannelOpened() {}
                        /* (non-Javadoc)
                         * @see org.eclipse.tcf.protocol.IChannel.IChannelListener#onChannelClosed(java.lang.Throwable)
                         */
                        @Override
                        public void onChannelClosed(Throwable error) {
                          if (traceListener != null && ScriptLauncher.this.channel != null) {
                            ((AbstractChannel) ScriptLauncher.this.channel)
                                .removeTraceListener(traceListener);
                            traceListener = null;
                          }
                          if (error != null) {
                            IStatus status =
                                new Status(
                                    IStatus.ERROR,
                                    CoreBundleActivator.getUniqueIdentifier(),
                                    NLS.bind(
                                        Messages.ScriptLauncher_error_channelConnectFailed,
                                        peer.getID(),
                                        error.getLocalizedMessage()),
                                    error);
                            invokeCallback(status, null);
                          }
                        }
                        /* (non-Javadoc)
                         * @see org.eclipse.tcf.protocol.IChannel.IChannelListener#congestionLevel(int)
                         */
                        @Override
                        public void congestionLevel(int level) {}
                      });

                  // Create the trace listener instance
                  traceListener =
                      new TraceListener() {

                        @Override
                        public void onMessageSent(
                            char type, String token, String service, String name, byte[] data) {
                          if (isFiltered(type, name)) return;
                          String message = formatMessage(type, token, service, name, data, false);
                          ScriptEvent event =
                              new ScriptEvent(
                                  ScriptLauncher.this,
                                  ScriptEvent.Type.OUTPUT,
                                  new ScriptEvent.Message(type, message));
                          EventManager.getInstance().fireEvent(event);
                        }

                        @Override
                        public void onMessageReceived(
                            char type, String token, String service, String name, byte[] data) {
                          if (isFiltered(type, name)) return;
                          String message = formatMessage(type, token, service, name, data, true);
                          ScriptEvent event =
                              new ScriptEvent(
                                  ScriptLauncher.this,
                                  ScriptEvent.Type.OUTPUT,
                                  new ScriptEvent.Message(type, message));
                          EventManager.getInstance().fireEvent(event);
                        }

                        @Override
                        public void onChannelClosed(Throwable error) {}

                        /**
                         * Checks if a given message is filtered. Filtered messages are not send to
                         * the script output console.
                         *
                         * @param type The message type.
                         * @param name The message name.
                         * @return <code>True</code> if the message is filtered, <code>false</code>
                         *     otherwise.
                         */
                        private boolean isFiltered(char type, String name) {
                          boolean filtered = false;

                          // Filter out the heart beat and framework messages
                          if (type == 'F'
                              || (name != null
                                  && name.toLowerCase().contains("heartbeat"))) { // $NON-NLS-1$
                            filtered = true;
                          }

                          return filtered;
                        }

                        /** Format the trace message. */
                        protected String formatMessage(
                            char type,
                            String token,
                            String service,
                            String name,
                            byte[] data,
                            boolean received) {
                          // Decode the arguments again for tracing purpose
                          String args = JSONUtils.decodeStringFromByteArray(data);

                          // Construct the full message
                          //
                          // The message format is: [<---|--->] <type> <token> <service>#<name>
                          // <args>
                          StringBuilder message = new StringBuilder();
                          message.append(received ? "<---" : "--->"); // $NON-NLS-1$ //$NON-NLS-2$
                          message.append(" ").append(Character.valueOf(type)); // $NON-NLS-1$
                          if (token != null) message.append(" ").append(token); // $NON-NLS-1$
                          if (service != null) message.append(" ").append(service); // $NON-NLS-1$
                          if (name != null) message.append(" ").append(name); // $NON-NLS-1$
                          if (args != null && args.trim().length() > 0)
                            message.append(" ").append(args.trim()); // $NON-NLS-1$

                          return message.toString();
                        }
                      };

                  // Register the trace listener
                  ((AbstractChannel) channel).addTraceListener(traceListener);

                  // Check if the channel is in connected state
                  if (channel.getState() != IChannel.STATE_OPEN) {
                    IStatus status =
                        new Status(
                            IStatus.ERROR,
                            CoreBundleActivator.getUniqueIdentifier(),
                            Messages.ScriptLauncher_error_channelNotConnected,
                            new IllegalStateException());
                    invokeCallback(status, null);
                    return;
                  }

                  // Do some very basic sanity checking on the script properties
                  if (properties.getStringProperty(IScriptLauncherProperties.PROP_SCRIPT) == null) {
                    IStatus status =
                        new Status(
                            IStatus.ERROR,
                            CoreBundleActivator.getUniqueIdentifier(),
                            Messages.ScriptLauncher_error_missingScript,
                            new IllegalArgumentException(IScriptLauncherProperties.PROP_SCRIPT));
                    invokeCallback(status, null);
                    return;
                  }

                  // Execute the launch now
                  executeLaunch();
                } else {
                  IStatus status =
                      new Status(
                          IStatus.ERROR,
                          CoreBundleActivator.getUniqueIdentifier(),
                          NLS.bind(
                              Messages.ScriptLauncher_error_channelConnectFailed,
                              peer.getID(),
                              error.getLocalizedMessage()),
                          error);
                  invokeCallback(status, null);
                }
              }
            });
  }