1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be |
2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. |
3 // found in the LICENSE file. |
4 |
4 |
5 package org.chromium.debug.core.model; |
5 package org.chromium.debug.core.model; |
6 |
6 |
|
7 import java.util.ArrayList; |
7 import java.util.HashMap; |
8 import java.util.HashMap; |
8 import java.util.LinkedList; |
|
9 import java.util.List; |
9 import java.util.List; |
10 import java.util.Map; |
10 import java.util.Map; |
11 |
11 |
12 import org.chromium.debug.core.ChromiumDebugPlugin; |
12 import org.chromium.debug.core.ChromiumDebugPlugin; |
13 import org.chromium.debug.core.model.BreakpointRegistry.BreakpointEntry; |
|
14 import org.chromium.debug.core.model.BreakpointRegistry.ScriptIdentifier; |
|
15 import org.chromium.debug.core.util.ChromiumDebugPluginUtil; |
13 import org.chromium.debug.core.util.ChromiumDebugPluginUtil; |
16 import org.chromium.sdk.Script; |
14 import org.chromium.sdk.Script; |
17 import org.eclipse.core.resources.IFile; |
15 import org.eclipse.core.resources.IFile; |
18 import org.eclipse.core.resources.IProject; |
16 import org.eclipse.core.resources.IProject; |
19 import org.eclipse.core.resources.ResourcesPlugin; |
17 import org.eclipse.core.resources.ResourcesPlugin; |
20 import org.eclipse.core.runtime.CoreException; |
18 import org.eclipse.core.runtime.CoreException; |
21 import org.eclipse.debug.core.DebugPlugin; |
|
22 |
19 |
23 /** |
20 /** |
24 * This object handles the mapping between {@link Script}s and their corresponding resources |
21 * This object handles the mapping between {@link Script}s and their corresponding resources |
25 * inside Eclipse. |
22 * inside Eclipse. |
26 */ |
23 */ |
27 public class ResourceManager { |
24 public class ResourceManager { |
28 private final Map<IFile, Script> resourceToScript = new HashMap<IFile, Script>(); |
|
29 private final Map<ScriptIdentifier, IFile> scriptIdToResource = |
|
30 new HashMap<ScriptIdentifier, IFile>(); |
|
31 private final IProject debugProject; |
25 private final IProject debugProject; |
32 private final BreakpointRegistry breakpointRegistry; |
|
33 private Object fileBeingAdded; |
|
34 |
26 |
35 public ResourceManager(IProject debugProject, BreakpointRegistry breakpointRegistry) { |
27 private final Map<VmResourceId, VmResourceInfo> vmResourceId2Info = |
|
28 new HashMap<VmResourceId, VmResourceInfo>(); |
|
29 private final Map<IFile, VmResourceInfo> file2Info = new HashMap<IFile, VmResourceInfo>(); |
|
30 |
|
31 public ResourceManager(IProject debugProject) { |
36 this.debugProject = debugProject; |
32 this.debugProject = debugProject; |
37 this.breakpointRegistry = breakpointRegistry; |
|
38 } |
33 } |
39 |
34 |
40 public synchronized void putScript(Script script, IFile resource) { |
35 public synchronized VmResource getVmResource(VmResourceId id) { |
41 ScriptIdentifier scriptId = ScriptIdentifier.forScript(script); |
36 VmResourceInfo info = vmResourceId2Info.get(id); |
42 resourceToScript.put(resource, script); |
37 if (info == null) { |
43 scriptIdToResource.put(scriptId, resource); |
38 return null; |
|
39 } |
|
40 return info.vmResourceImpl; |
44 } |
41 } |
45 |
42 |
46 public synchronized Script getScript(IFile resource) { |
43 /** |
47 return resourceToScript.get(resource); |
44 * @param eclipseSourceName eclipse source file name |
|
45 * (what {@link VmResourceId#getEclipseSourceName()} returns) |
|
46 */ |
|
47 public IFile getFile(String eclipseSourceName) { |
|
48 VmResourceId id = VmResourceId.parseString(eclipseSourceName); |
|
49 VmResourceInfo info = vmResourceId2Info.get(id); |
|
50 if (info == null) { |
|
51 return null; |
|
52 } |
|
53 return info.file; |
48 } |
54 } |
49 |
55 |
50 public synchronized IFile getResource(Script script) { |
56 public synchronized VmResourceId getResourceId(IFile resource) { |
51 return scriptIdToResource.get(ScriptIdentifier.forScript(script)); |
57 VmResourceInfo info = file2Info.get(resource); |
|
58 if (info == null) { |
|
59 return null; |
|
60 } |
|
61 return info.id; |
52 } |
62 } |
53 |
63 |
54 public synchronized boolean scriptHasResource(Script script) { |
64 public synchronized void addScript(Script newScript) { |
55 return getResource(script) != null; |
65 VmResourceId id = VmResourceId.forScript(newScript); |
|
66 VmResourceInfo info = vmResourceId2Info.get(id); |
|
67 if (info == null) { |
|
68 String fileNameTemplate = createFileNameTemplate(id, newScript); |
|
69 IFile scriptFile = ChromiumDebugPluginUtil.createFile(debugProject, fileNameTemplate); |
|
70 info = new VmResourceInfo(scriptFile, id); |
|
71 vmResourceId2Info.put(id, info); |
|
72 file2Info.put(scriptFile, info); |
|
73 |
|
74 info.scripts.add(newScript); |
|
75 writeScriptSource(info.scripts, info.file); |
|
76 } else { |
|
77 // TODO(peter.rybin): support adding scripts to one resource at once not to rewrite file |
|
78 // every time. |
|
79 info.scripts.add(newScript); |
|
80 writeScriptSource(info.scripts, info.file); |
|
81 } |
|
82 } |
|
83 |
|
84 public synchronized void reloadScript(Script script) { |
|
85 VmResourceId id = VmResourceId.forScript(script); |
|
86 VmResourceInfo info = vmResourceId2Info.get(id); |
|
87 if (info == null) { |
|
88 throw new RuntimeException("Script file not found"); //$NON-NLS-1$ |
|
89 } |
|
90 if (!info.scripts.contains(script)) { |
|
91 throw new RuntimeException("Script not found in internal list"); //$NON-NLS-1$ |
|
92 } |
|
93 writeScriptSource(info.scripts, info.file); |
56 } |
94 } |
57 |
95 |
58 public synchronized void clear() { |
96 public synchronized void clear() { |
59 deleteAllScriptFiles(); |
97 deleteAllScriptFiles(); |
60 resourceToScript.clear(); |
98 |
61 scriptIdToResource.clear(); |
99 vmResourceId2Info.clear(); |
|
100 file2Info.clear(); |
62 } |
101 } |
63 |
102 |
64 private void deleteAllScriptFiles() { |
103 private void deleteAllScriptFiles() { |
65 if (!resourceToScript.isEmpty()) { |
104 try { |
66 try { |
105 ResourcesPlugin.getWorkspace().delete( |
67 ResourcesPlugin.getWorkspace().delete( |
106 file2Info.keySet().toArray(new IFile[file2Info.size()]), true, null); |
68 resourceToScript.keySet().toArray(new IFile[resourceToScript.size()]), true, null); |
107 } catch (CoreException e) { |
69 } catch (CoreException e) { |
108 ChromiumDebugPlugin.log(e); |
70 ChromiumDebugPlugin.log(e); |
|
71 } |
|
72 } |
109 } |
73 } |
110 } |
74 |
111 |
75 public synchronized void addScript(Script script) { |
112 private String createFileNameTemplate(VmResourceId id, Script newScript) { |
76 IFile scriptFile = getResource(script); |
113 return id.createFileNameTemplate(true); |
77 if (scriptFile == null) { |
114 } |
78 scriptFile = ChromiumDebugPluginUtil.createFile(debugProject, getScriptResourceName(script)); |
115 |
79 fileBeingAdded = scriptFile; |
116 private static void writeScriptSource(List<Script> scripts, IFile file) { |
80 try { |
117 String fileSource = MockUpResourceWriter.writeScriptSource(scripts); |
81 putScript(script, scriptFile); |
118 |
82 writeScriptSource(script, scriptFile); |
119 try { |
83 // Perhaps restore breakpoints for the reloaded script |
120 ChromiumDebugPluginUtil.writeFile(file, fileSource); |
84 List<ChromiumLineBreakpoint> breakpoints = new LinkedList<ChromiumLineBreakpoint>(); |
121 } catch (final CoreException e) { |
85 for (BreakpointEntry entry : breakpointRegistry.getBreakpointEntries(script)) { |
122 ChromiumDebugPlugin.log(e); |
86 ChromiumLineBreakpoint lineBreakpoint; |
|
87 try { |
|
88 lineBreakpoint = new ChromiumLineBreakpoint(scriptFile, entry.line + 1); |
|
89 } catch (CoreException e) { |
|
90 ChromiumDebugPlugin.log(e); |
|
91 continue; |
|
92 } |
|
93 lineBreakpoint.setBreakpoint(entry.breakpoint); |
|
94 breakpoints.add(lineBreakpoint); |
|
95 } |
|
96 if (!breakpoints.isEmpty()) { |
|
97 try { |
|
98 DebugPlugin.getDefault().getBreakpointManager().addBreakpoints( |
|
99 breakpoints.toArray(new ChromiumLineBreakpoint[breakpoints.size()])); |
|
100 } catch (CoreException e) { |
|
101 ChromiumDebugPlugin.log(e); |
|
102 } |
|
103 } |
|
104 } finally { |
|
105 fileBeingAdded = null; |
|
106 } |
|
107 } |
123 } |
108 } |
124 } |
109 |
125 |
110 private String getScriptResourceName(Script script) { |
126 private class VmResourceInfo { |
111 String name = script.getName(); |
127 final IFile file; |
112 if (name == null) { |
128 final VmResourceId id; |
113 name = Messages.ResourceManager_UnnamedScriptName; |
129 final ArrayList<Script> scripts = new ArrayList<Script>(1); |
|
130 VmResourceInfo(IFile file, VmResourceId id) { |
|
131 this.file = file; |
|
132 this.id = id; |
114 } |
133 } |
115 return name; |
|
116 } |
|
117 |
134 |
118 private static void writeScriptSource(Script script, IFile file) { |
135 final VmResource vmResourceImpl = new VmResource() { |
119 if (script.hasSource()) { |
136 public VmResourceId getId() { |
120 try { |
137 return id; |
121 ChromiumDebugPluginUtil.writeFile(file, script.getSource()); |
|
122 } catch (final CoreException e) { |
|
123 ChromiumDebugPlugin.log(e); |
|
124 } |
138 } |
125 } |
|
126 } |
|
127 |
139 |
128 /** |
140 public Script getScript() { |
129 * @return whether the given file is being added to the target project |
141 synchronized (ResourceManager.this) { |
130 */ |
142 if (scripts.size() != 1) { |
131 public boolean isAddingFile(IFile file) { |
143 throw new UnsupportedOperationException( |
132 return file.equals(fileBeingAdded); |
144 "Not supported for complex resources"); //$NON-NLS-1$ |
|
145 } |
|
146 return scripts.get(0); |
|
147 } |
|
148 } |
|
149 public String getFileName() { |
|
150 return file.getName(); |
|
151 } |
|
152 }; |
133 } |
153 } |
134 } |
154 } |