org.chromium.debug.core/src/org/chromium/debug/core/model/ResourceManager.java
changeset 355 8726e95bcbba
parent 52 f577ea64429e
--- a/org.chromium.debug.core/src/org/chromium/debug/core/model/ResourceManager.java	Mon Jun 07 16:33:07 2010 -0700
+++ b/org.chromium.debug.core/src/org/chromium/debug/core/model/ResourceManager.java	Mon Jun 07 16:51:19 2010 -0700
@@ -1,134 +1,154 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 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.debug.core.model;
 
+import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 
 import org.chromium.debug.core.ChromiumDebugPlugin;
-import org.chromium.debug.core.model.BreakpointRegistry.BreakpointEntry;
-import org.chromium.debug.core.model.BreakpointRegistry.ScriptIdentifier;
 import org.chromium.debug.core.util.ChromiumDebugPluginUtil;
 import org.chromium.sdk.Script;
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
-import org.eclipse.debug.core.DebugPlugin;
 
 /**
  * This object handles the mapping between {@link Script}s and their corresponding resources
  * inside Eclipse.
  */
 public class ResourceManager {
-  private final Map<IFile, Script> resourceToScript = new HashMap<IFile, Script>();
-  private final Map<ScriptIdentifier, IFile> scriptIdToResource =
-      new HashMap<ScriptIdentifier, IFile>();
   private final IProject debugProject;
-  private final BreakpointRegistry breakpointRegistry;
-  private Object fileBeingAdded;
+
+  private final Map<VmResourceId, VmResourceInfo> vmResourceId2Info =
+      new HashMap<VmResourceId, VmResourceInfo>();
+  private final Map<IFile, VmResourceInfo> file2Info = new HashMap<IFile, VmResourceInfo>();
+
+  public ResourceManager(IProject debugProject) {
+    this.debugProject = debugProject;
+  }
 
-  public ResourceManager(IProject debugProject, BreakpointRegistry breakpointRegistry) {
-    this.debugProject = debugProject;
-    this.breakpointRegistry = breakpointRegistry;
+  public synchronized VmResource getVmResource(VmResourceId id) {
+    VmResourceInfo info = vmResourceId2Info.get(id);
+    if (info == null) {
+      return null;
+    }
+    return info.vmResourceImpl;
+  }
+
+  /**
+   * @param eclipseSourceName eclipse source file name
+   *   (what {@link VmResourceId#getEclipseSourceName()} returns)
+   */
+  public IFile getFile(String eclipseSourceName) {
+    VmResourceId id = VmResourceId.parseString(eclipseSourceName);
+    VmResourceInfo info = vmResourceId2Info.get(id);
+    if (info == null) {
+      return null;
+    }
+    return info.file;
   }
 
-  public synchronized void putScript(Script script, IFile resource) {
-    ScriptIdentifier scriptId = ScriptIdentifier.forScript(script);
-    resourceToScript.put(resource, script);
-    scriptIdToResource.put(scriptId, resource);
+  public synchronized VmResourceId getResourceId(IFile resource) {
+    VmResourceInfo info = file2Info.get(resource);
+    if (info == null) {
+      return null;
+    }
+    return info.id;
   }
 
-  public synchronized Script getScript(IFile resource) {
-    return resourceToScript.get(resource);
+  public synchronized void addScript(Script newScript) {
+    VmResourceId id = VmResourceId.forScript(newScript);
+    VmResourceInfo info = vmResourceId2Info.get(id);
+    if (info == null) {
+      String fileNameTemplate = createFileNameTemplate(id, newScript);
+      IFile scriptFile = ChromiumDebugPluginUtil.createFile(debugProject, fileNameTemplate);
+      info = new VmResourceInfo(scriptFile, id);
+      vmResourceId2Info.put(id, info);
+      file2Info.put(scriptFile, info);
+
+      info.scripts.add(newScript);
+      writeScriptSource(info.scripts, info.file);
+    } else {
+      // TODO(peter.rybin): support adding scripts to one resource at once not to rewrite file
+      // every time.
+      info.scripts.add(newScript);
+      writeScriptSource(info.scripts, info.file);
+    }
   }
 
-  public synchronized IFile getResource(Script script) {
-    return scriptIdToResource.get(ScriptIdentifier.forScript(script));
-  }
-
-  public synchronized boolean scriptHasResource(Script script) {
-    return getResource(script) != null;
+  public synchronized void reloadScript(Script script) {
+    VmResourceId id = VmResourceId.forScript(script);
+    VmResourceInfo info = vmResourceId2Info.get(id);
+    if (info == null) {
+      throw new RuntimeException("Script file not found"); //$NON-NLS-1$
+    }
+    if (!info.scripts.contains(script)) {
+      throw new RuntimeException("Script not found in internal list"); //$NON-NLS-1$
+    }
+    writeScriptSource(info.scripts, info.file);
   }
 
   public synchronized void clear() {
     deleteAllScriptFiles();
-    resourceToScript.clear();
-    scriptIdToResource.clear();
+
+    vmResourceId2Info.clear();
+    file2Info.clear();
   }
 
   private void deleteAllScriptFiles() {
-    if (!resourceToScript.isEmpty()) {
-      try {
-        ResourcesPlugin.getWorkspace().delete(
-            resourceToScript.keySet().toArray(new IFile[resourceToScript.size()]), true, null);
-      } catch (CoreException e) {
-        ChromiumDebugPlugin.log(e);
-      }
+    try {
+      ResourcesPlugin.getWorkspace().delete(
+          file2Info.keySet().toArray(new IFile[file2Info.size()]), true, null);
+    } catch (CoreException e) {
+      ChromiumDebugPlugin.log(e);
+    }
+  }
+
+  private String createFileNameTemplate(VmResourceId id, Script newScript) {
+    return id.createFileNameTemplate(true);
+  }
+
+  private static void writeScriptSource(List<Script> scripts, IFile file) {
+    String fileSource = MockUpResourceWriter.writeScriptSource(scripts);
+
+    try {
+      ChromiumDebugPluginUtil.writeFile(file, fileSource);
+    } catch (final CoreException e) {
+      ChromiumDebugPlugin.log(e);
     }
   }
 
-  public synchronized void addScript(Script script) {
-    IFile scriptFile = getResource(script);
-    if (scriptFile == null) {
-      scriptFile = ChromiumDebugPluginUtil.createFile(debugProject, getScriptResourceName(script));
-      fileBeingAdded = scriptFile;
-      try {
-        putScript(script, scriptFile);
-        writeScriptSource(script, scriptFile);
-        // Perhaps restore breakpoints for the reloaded script
-        List<ChromiumLineBreakpoint> breakpoints = new LinkedList<ChromiumLineBreakpoint>();
-        for (BreakpointEntry entry : breakpointRegistry.getBreakpointEntries(script)) {
-          ChromiumLineBreakpoint lineBreakpoint;
-          try {
-            lineBreakpoint = new ChromiumLineBreakpoint(scriptFile, entry.line + 1);
-          } catch (CoreException e) {
-            ChromiumDebugPlugin.log(e);
-            continue;
+  private class VmResourceInfo {
+    final IFile file;
+    final VmResourceId id;
+    final ArrayList<Script> scripts = new ArrayList<Script>(1);
+    VmResourceInfo(IFile file, VmResourceId id) {
+      this.file = file;
+      this.id = id;
+    }
+
+    final VmResource vmResourceImpl = new VmResource() {
+      public VmResourceId getId() {
+        return id;
+      }
+
+      public Script getScript() {
+        synchronized (ResourceManager.this) {
+          if (scripts.size() != 1) {
+            throw new UnsupportedOperationException(
+                "Not supported for complex resources"); //$NON-NLS-1$
           }
-          lineBreakpoint.setBreakpoint(entry.breakpoint);
-          breakpoints.add(lineBreakpoint);
-        }
-        if (!breakpoints.isEmpty()) {
-          try {
-            DebugPlugin.getDefault().getBreakpointManager().addBreakpoints(
-                breakpoints.toArray(new ChromiumLineBreakpoint[breakpoints.size()]));
-          } catch (CoreException e) {
-            ChromiumDebugPlugin.log(e);
-          }
+          return scripts.get(0);
         }
-      } finally {
-        fileBeingAdded = null;
       }
-    }
-  }
-
-  private String getScriptResourceName(Script script) {
-    String name = script.getName();
-    if (name == null) {
-      name = Messages.ResourceManager_UnnamedScriptName;
-    }
-    return name;
-  }
-
-  private static void writeScriptSource(Script script, IFile file) {
-    if (script.hasSource()) {
-      try {
-        ChromiumDebugPluginUtil.writeFile(file, script.getSource());
-      } catch (final CoreException e) {
-        ChromiumDebugPlugin.log(e);
+      public String getFileName() {
+        return file.getName();
       }
-    }
-  }
-
-  /**
-   * @return whether the given file is being added to the target project
-   */
-  public boolean isAddingFile(IFile file) {
-    return file.equals(fileBeingAdded);
+    };
   }
 }