org.chromium.sdk/src/org/chromium/sdk/internal/ScriptImpl.java
changeset 355 8726e95bcbba
parent 276 f2f4a1259de8
--- a/org.chromium.sdk/src/org/chromium/sdk/internal/ScriptImpl.java	Mon Jun 07 16:33:07 2010 -0700
+++ b/org.chromium.sdk/src/org/chromium/sdk/internal/ScriptImpl.java	Mon Jun 07 16:51:19 2010 -0700
@@ -4,20 +4,37 @@
 
 package org.chromium.sdk.internal;
 
+import java.util.Collections;
 import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
+import org.chromium.sdk.LiveEditDebugEventListener;
+import org.chromium.sdk.LiveEditExtension;
 import org.chromium.sdk.Script;
+import org.chromium.sdk.SyncCallback;
+import org.chromium.sdk.UpdatableScript;
+import org.chromium.sdk.internal.protocol.ChangeLiveBody;
+import org.chromium.sdk.internal.protocol.SuccessCommandResponse;
 import org.chromium.sdk.internal.protocol.data.ScriptHandle;
 import org.chromium.sdk.internal.protocol.data.SomeHandle;
 import org.chromium.sdk.internal.protocolparser.JsonProtocolParseException;
+import org.chromium.sdk.internal.tools.v8.V8CommandCallbackBase;
+import org.chromium.sdk.internal.tools.v8.V8CommandProcessor;
+import org.chromium.sdk.internal.tools.v8.V8Helper;
 import org.chromium.sdk.internal.tools.v8.V8ProtocolUtil;
+import org.chromium.sdk.internal.tools.v8.V8Helper.ScriptLoadCallback;
+import org.chromium.sdk.internal.tools.v8.request.ChangeLiveMessage;
 
 /**
  * An objects that holds data for a "script" which is a part of a resource
  * loaded into the browser, identified by its original document URL, line offset
  * in the original document, and the line count this script spans.
  */
-public class ScriptImpl implements Script {
+public class ScriptImpl implements Script, UpdatableScript {
+
+  /** The class logger. */
+  private static final Logger LOGGER = Logger.getLogger(ScriptImpl.class.getName());
 
   /**
    * An object containing data that uniquely identify a V8 script chunk.
@@ -29,15 +46,19 @@
 
     public final int lineOffset;
 
+    public final int columnOffset;
+
     public final int endLine;
 
     public final long id;
 
-    public Descriptor(Type type, long id, String name, int lineOffset, int lineCount) {
+    public Descriptor(Type type, long id, String name, int lineOffset, int columnOffset,
+        int lineCount) {
       this.type = type;
       this.id = id;
       this.name = name;
       this.lineOffset = lineOffset;
+      this.columnOffset = columnOffset;
       this.endLine = lineOffset + lineCount - 1;
     }
 
@@ -45,8 +66,8 @@
     public int hashCode() {
       return
           name != null ? name.hashCode() : (int) id * 0x101 +
-          lineOffset * 0x1001 +
-          endLine * 0x10001;
+          lineOffset * 0x1001 + columnOffset * 0x10001 +
+          endLine * 0x100001;
     }
 
     @Override
@@ -61,6 +82,7 @@
       // The id equality is stronger than the name equality.
       return this.id == that.id &&
           this.lineOffset == that.lineOffset &&
+          this.columnOffset == that.columnOffset &&
           this.endLine == that.endLine;
     }
 
@@ -78,9 +100,10 @@
           return null;
         }
         int lineOffset = (int) script.lineOffset();
+        int columnOffset = (int) script.columnOffset();
         int lineCount = (int) script.lineCount();
         int id = V8ProtocolUtil.getScriptIdFromResponse(script).intValue();
-        return new Descriptor(type, id, name, lineOffset, lineCount);
+        return new Descriptor(type, id, name, lineOffset, columnOffset, lineCount);
       } catch (Exception e) {
         // not a script object has been passed in
         return null;
@@ -92,12 +115,15 @@
 
   private volatile String source = null;
 
+  private final DebugSession debugSession;
+
   /**
    * @param descriptor of the script retrieved from a "scripts" response
    */
-  public ScriptImpl(Descriptor descriptor) {
+  public ScriptImpl(Descriptor descriptor, DebugSession debugSession) {
     this.descriptor = descriptor;
     this.source = null;
+    this.debugSession = debugSession;
   }
 
   public Type getType() {
@@ -112,6 +138,10 @@
     return descriptor.lineOffset;
   }
 
+  public int getStartColumn() {
+    return descriptor.columnOffset;
+  }
+
   public int getEndLine() {
     return descriptor.endLine;
   }
@@ -132,6 +162,56 @@
     this.source = source;
   }
 
+  public void setSourceOnRemote(String newSource, UpdateCallback callback,
+      SyncCallback syncCallback) {
+    V8CommandProcessor.V8HandlerCallback v8Callback = createScriptUpdateCallback(callback);
+    debugSession.sendMessageAsync(new ChangeLiveMessage(getId(), newSource),
+        true, v8Callback, syncCallback);
+  }
+
+  private V8CommandProcessor.V8HandlerCallback createScriptUpdateCallback(
+      final UpdateCallback callback) {
+    if (callback == null) {
+      return null;
+    }
+    return new V8CommandCallbackBase() {
+      @Override
+      public void success(SuccessCommandResponse successResponse) {
+        ChangeLiveBody body;
+        try {
+          body = successResponse.getBody().asChangeLiveBody();
+        } catch (JsonProtocolParseException e) {
+          throw new RuntimeException(e);
+        }
+
+        ScriptLoadCallback scriptCallback = new ScriptLoadCallback() {
+          public void failure(String message) {
+            LOGGER.log(Level.SEVERE,
+                "Failed to reload script after LiveEdit script update; " + message);
+          }
+          public void success() {
+            LiveEditDebugEventListener listener =
+                LiveEditExtension.castToLiveEditListener(debugSession.getDebugEventListener());
+            if (listener != null) {
+              listener.scriptContentChanged(ScriptImpl.this);
+            }
+          }
+        };
+        V8Helper.reloadScriptAsync(debugSession, Collections.singletonList(getId()),
+            scriptCallback, null);
+
+        debugSession.recreateCurrentContext();
+
+        callback.success(body.getChangeLog());
+      }
+
+      @Override
+      public void failure(String message) {
+        callback.failure(message);
+      }
+    };
+  }
+
   @Override
   public int hashCode() {
     return