--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/org.chromium.sdk/src/org/chromium/sdk/internal/ScriptManager.java Wed Dec 23 17:13:18 2009 -0800
@@ -0,0 +1,153 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.sdk.internal;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+import org.chromium.sdk.Script;
+import org.chromium.sdk.internal.ScriptImpl.Descriptor;
+import org.chromium.sdk.internal.protocol.data.ScriptHandle;
+import org.chromium.sdk.internal.protocol.data.SomeHandle;
+import org.chromium.sdk.internal.tools.v8.V8ProtocolUtil;
+
+/**
+ * Manages scripts known in the corresponding browser tab.
+ */
+public class ScriptManager {
+
+ public interface Callback {
+ /**
+ * This method gets invoked for every script in the manager.
+ *
+ * @param script to process
+ * @return whether other scripts should be processed. If false, the #forEach
+ * method terminates.
+ */
+ boolean process(Script script);
+ }
+
+ /**
+ * Maps script id's to scripts.
+ */
+ private final Map<Long, ScriptImpl> idToScript =
+ Collections.synchronizedMap(new HashMap<Long, ScriptImpl>());
+
+ private final V8ContextFilter contextFilter;
+
+ ScriptManager(V8ContextFilter contextFilter) {
+ this.contextFilter = contextFilter;
+ }
+
+ /**
+ * Adds a script using a "script" V8 response.
+ *
+ * @param scriptBody to add the script from
+ * @param refs that contain the associated script debug context
+ * @return the new script, or {@code null} if the response does not contain
+ * a valid script JSON
+ */
+ public synchronized Script addScript(ScriptHandle scriptBody, List<SomeHandle> refs) {
+
+ ScriptImpl theScript = findById(V8ProtocolUtil.getScriptIdFromResponse(scriptBody));
+
+ if (theScript == null) {
+ Descriptor desc = Descriptor.forResponse(scriptBody, refs, contextFilter);
+ if (desc == null) {
+ return null;
+ }
+ theScript = new ScriptImpl(desc);
+ idToScript.put(desc.id, theScript);
+ }
+ if (scriptBody.source() != null) {
+ setSourceCode(scriptBody, theScript);
+ }
+
+ return theScript;
+ }
+
+ /**
+ * Associates a source received in a "source" V8 response with the given
+ * script.
+ *
+ * @param scriptBody the JSON response body
+ * @param script the script to associate the source with
+ */
+ public void setSourceCode(ScriptHandle body, ScriptImpl script) {
+ String src = body.source();
+ if (src == null) {
+ return;
+ }
+ if (script != null) {
+ script.setSource(src);
+ }
+ }
+
+ /**
+ * @param id of the script to find
+ * @return the script with {@code id == ref} or {@code null} if none found
+ */
+ public ScriptImpl findById(Long id) {
+ return idToScript.get(id);
+ }
+
+ /**
+ * Determines whether all scripts added into this manager have associated
+ * sources.
+ *
+ * @return whether all known scripts have associated sources
+ */
+ public boolean isAllSourcesLoaded() {
+ final boolean[] result = new boolean[1];
+ result[0] = true;
+ forEach(new Callback() {
+ public boolean process(Script script) {
+ if (!script.hasSource()) {
+ result[0] = false;
+ return false;
+ }
+ return true;
+ }
+ });
+ return result[0];
+ }
+
+ public Collection<Script> allScripts() {
+ final Collection<Script> result = new HashSet<Script>();
+ forEach(new Callback() {
+ public boolean process(Script script) {
+ result.add(script);
+ return true;
+ }
+ });
+ return result;
+ }
+
+ /**
+ * This method allows running the same code for all scripts in the manager.
+ *
+ * @param callback to invoke for every script, until
+ * {@link Callback#process(Script)} returns {@code false}.
+ */
+ public synchronized void forEach(Callback callback) {
+ for (Script script : idToScript.values()) {
+ if (!callback.process(script)) {
+ return;
+ }
+ }
+ }
+
+ public void reset() {
+ idToScript.clear();
+ }
+
+ public V8ContextFilter getContextFilter() {
+ return contextFilter;
+ }
+}