org.chromium.debug.ui/src/org/chromium/debug/ui/launcher/LaunchTypeBase.java
changeset 2 e4420d2515f1
child 52 f577ea64429e
equal deleted inserted replaced
1:ef76fc2ac88c 2:e4420d2515f1
       
     1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
       
     2 // Use of this source code is governed by a BSD-style license that can be
       
     3 // found in the LICENSE file.
       
     4 
       
     5 package org.chromium.debug.ui.launcher;
       
     6 
       
     7 import java.util.concurrent.atomic.AtomicBoolean;
       
     8 
       
     9 import org.chromium.debug.core.model.ConnectionLoggerImpl;
       
    10 import org.chromium.debug.core.model.ConsolePseudoProcess;
       
    11 import org.chromium.debug.core.model.DebugTargetImpl;
       
    12 import org.chromium.debug.core.model.Destructable;
       
    13 import org.chromium.debug.core.model.DestructingGuard;
       
    14 import org.chromium.debug.core.model.JavascriptVmEmbedder;
       
    15 import org.chromium.debug.core.model.NamedConnectionLoggerFactory;
       
    16 import org.chromium.debug.ui.PluginUtil;
       
    17 import org.chromium.sdk.ConnectionLogger;
       
    18 import org.eclipse.core.runtime.CoreException;
       
    19 import org.eclipse.core.runtime.IProgressMonitor;
       
    20 import org.eclipse.debug.core.DebugPlugin;
       
    21 import org.eclipse.debug.core.ILaunch;
       
    22 import org.eclipse.debug.core.ILaunchConfiguration;
       
    23 import org.eclipse.debug.core.ILaunchManager;
       
    24 import org.eclipse.debug.core.model.ILaunchConfigurationDelegate;
       
    25 
       
    26 /**
       
    27  * A launch configuration delegate for the JavaScript debugging.
       
    28  */
       
    29 public abstract class LaunchTypeBase implements ILaunchConfigurationDelegate {
       
    30 
       
    31   /** Launch configuration attribute (debug port). */
       
    32   public static final String CHROMIUM_DEBUG_PORT = "debug_port"; //$NON-NLS-1$
       
    33 
       
    34   public static final String ADD_NETWORK_CONSOLE = "add_network_console"; //$NON-NLS-1$
       
    35 
       
    36   public void launch(ILaunchConfiguration config, String mode, final ILaunch launch,
       
    37       IProgressMonitor monitor) throws CoreException {
       
    38     if (!mode.equals(ILaunchManager.DEBUG_MODE)) {
       
    39       // Chromium JavaScript launch is only supported for debugging.
       
    40       return;
       
    41     } 
       
    42     
       
    43     int port =
       
    44         config.getAttribute(LaunchTypeBase.CHROMIUM_DEBUG_PORT,
       
    45             PluginVariablesUtil.getValueAsInt(PluginVariablesUtil.DEFAULT_PORT));
       
    46 
       
    47     boolean addNetworkConsole = config.getAttribute(LaunchTypeBase.ADD_NETWORK_CONSOLE, false);
       
    48   
       
    49     JavascriptVmEmbedder.ConnectionToRemote remoteServer =
       
    50         createConnectionToRemote(port, launch, addNetworkConsole);
       
    51     try {
       
    52   
       
    53       String projectNameBase = config.getName();
       
    54   
       
    55       DestructingGuard destructingGuard = new DestructingGuard();
       
    56       try {
       
    57         Destructable lauchDestructor = new Destructable() {
       
    58           public void destruct() {
       
    59             if (!launch.hasChildren()) {
       
    60               DebugPlugin.getDefault().getLaunchManager().removeLaunch(launch);
       
    61             }
       
    62           }
       
    63         };
       
    64   
       
    65         destructingGuard.addValue(lauchDestructor);
       
    66   
       
    67         final DebugTargetImpl target = new DebugTargetImpl(launch);
       
    68   
       
    69         Destructable targetDestructor = new Destructable() {
       
    70           public void destruct() {
       
    71             terminateTarget(target);
       
    72           }
       
    73         };
       
    74         destructingGuard.addValue(targetDestructor);
       
    75         boolean attached = target.attach(
       
    76             projectNameBase, remoteServer, destructingGuard,
       
    77             new Runnable() {
       
    78               public void run() {
       
    79                 PluginUtil.openProjectExplorerView();
       
    80               }
       
    81             },
       
    82             monitor);
       
    83         if (!attached) {
       
    84           // Error
       
    85           return;
       
    86         }
       
    87   
       
    88         launch.setSourceLocator(target.getSourceLocator());
       
    89   
       
    90         launch.addDebugTarget(target);
       
    91         monitor.done();
       
    92   
       
    93         // All OK
       
    94         destructingGuard.discharge();
       
    95       } finally {
       
    96         destructingGuard.doFinally();
       
    97       }
       
    98   
       
    99     } finally {
       
   100       remoteServer.disposeConnection();
       
   101     }
       
   102   }
       
   103 
       
   104   protected abstract JavascriptVmEmbedder.ConnectionToRemote createConnectionToRemote(int port,
       
   105       ILaunch launch, boolean addConsoleLogger) throws CoreException;
       
   106 
       
   107   private static void terminateTarget(DebugTargetImpl target) {
       
   108     target.setDisconnected(true);
       
   109     target.fireTerminateEvent();
       
   110   }
       
   111 
       
   112   static ConnectionLogger createConsoleAndLogger(final ILaunch launch,
       
   113       final boolean addLaunchToManager, final String title) {
       
   114     final ConsolePseudoProcess.Retransmitter consoleRetransmitter =
       
   115         new ConsolePseudoProcess.Retransmitter();
       
   116 
       
   117     // This controller is responsible for creating ConsolePseudoProcess only on
       
   118     // logStarted call. Before this ConnectionLoggerImpl with all it fields should stay
       
   119     // garbage-collectible, because connection may not even start.
       
   120     ConnectionLoggerImpl.LogLifecycleListener consoleController =
       
   121         new ConnectionLoggerImpl.LogLifecycleListener() {
       
   122       private final AtomicBoolean alreadyStarted = new AtomicBoolean(false);
       
   123 
       
   124       public void logClosed() {
       
   125         consoleRetransmitter.processClosed();
       
   126       }
       
   127 
       
   128       public void logStarted(ConnectionLoggerImpl connectionLogger) {
       
   129         boolean res = alreadyStarted.compareAndSet(false, true);
       
   130         if (!res) {
       
   131           throw new IllegalStateException();
       
   132         }
       
   133         ConsolePseudoProcess consolePseudoProcess = new ConsolePseudoProcess(launch, title,
       
   134             consoleRetransmitter, connectionLogger.getConnectionTerminate());
       
   135         consoleRetransmitter.startFlushing();
       
   136         if (addLaunchToManager) {
       
   137           // Active the launch (again if it has already been removed)
       
   138           DebugPlugin.getDefault().getLaunchManager().addLaunch(launch);
       
   139        }
       
   140       }
       
   141     };
       
   142 
       
   143     return new ConnectionLoggerImpl(consoleRetransmitter, consoleController);
       
   144   }
       
   145 
       
   146   static final NamedConnectionLoggerFactory NO_CONNECTION_LOGGER_FACTORY =
       
   147       new NamedConnectionLoggerFactory() {
       
   148     public ConnectionLogger createLogger(String title) {
       
   149       return null;
       
   150     }
       
   151   };
       
   152 }