View | Details | Raw Unified | Return to bug 361315 | Differences between
and this patch

Collapse All | Expand All

(-)plugin.xml (+7 lines)
Lines 13-18 Link Here
13
<plugin>
13
<plugin>
14
   <extension-point id="launchingConnectors" name="%connectorsExtPoint.name" schema="schema/launchingConnectors.exsd"/>
14
   <extension-point id="launchingConnectors" name="%connectorsExtPoint.name" schema="schema/launchingConnectors.exsd"/>
15
   <extension-point id="breakpointParticipants" name="%breakpointParticipantsExt.name" schema="schema/breakpointParticipants.exsd"/>
15
   <extension-point id="breakpointParticipants" name="%breakpointParticipantsExt.name" schema="schema/breakpointParticipants.exsd"/>
16
   <extension-point id="scriptResolvers" name="scriptResolvers" schema="schema/scriptResolvers.exsd"/>
16
   <extension
17
   <extension
17
         point="org.eclipse.debug.core.launchConfigurationTypes">
18
         point="org.eclipse.debug.core.launchConfigurationTypes">
18
      <launchConfigurationType
19
      <launchConfigurationType
Lines 161-165 Link Here
161
            id="org.eclipse.wst.jsdt.debug.core.source.path.computer">
162
            id="org.eclipse.wst.jsdt.debug.core.source.path.computer">
162
      </sourcePathComputer>
163
      </sourcePathComputer>
163
   </extension>
164
   </extension>
165
   <extension
166
         point="org.eclipse.wst.jsdt.debug.core.scriptResolvers">
167
      <scriptResolver
168
            class="org.eclipse.wst.jsdt.debug.internal.core.model.DefaultScriptResolver">
169
      </scriptResolver>
170
   </extension>
164
171
165
</plugin>
172
</plugin>
(-)schema/scriptResolvers.exsd (+128 lines)
Added Link Here
1
<?xml version='1.0' encoding='UTF-8'?>
2
<!-- Schema file written by PDE -->
3
<schema targetNamespace="org.eclipse.wst.jsdt.debug.core" xmlns="http://www.w3.org/2001/XMLSchema">
4
<annotation>
5
      <appinfo>
6
         <meta.schema plugin="org.eclipse.wst.jsdt.debug.core" id="scriptResolvers" name="scriptResolvers"/>
7
      </appinfo>
8
      <documentation>
9
         This extension point is used to contribute a script solver that is consulted any place in JSDT where a &lt;code&gt;ScriptReference&lt;/code&gt; must be resolved to a workspace-local &lt;code&gt;IFile&lt;/code&gt;.
10
&lt;br&gt;&lt;br&gt;
11
An example of typical usage is resolving if a breakpoint&apos;s workspace path matches that of a given &lt;code&gt;ScriptReference&lt;/code&gt;
12
      </documentation>
13
   </annotation>
14
15
   <element name="extension">
16
      <annotation>
17
         <appinfo>
18
            <meta.element />
19
         </appinfo>
20
      </annotation>
21
      <complexType>
22
         <sequence minOccurs="1" maxOccurs="unbounded">
23
            <element ref="scriptResolver"/>
24
         </sequence>
25
         <attribute name="point" type="string" use="required">
26
            <annotation>
27
               <documentation>
28
                  
29
               </documentation>
30
            </annotation>
31
         </attribute>
32
         <attribute name="id" type="string">
33
            <annotation>
34
               <documentation>
35
                  
36
               </documentation>
37
            </annotation>
38
         </attribute>
39
         <attribute name="name" type="string">
40
            <annotation>
41
               <documentation>
42
                  
43
               </documentation>
44
               <appinfo>
45
                  <meta.attribute translatable="true"/>
46
               </appinfo>
47
            </annotation>
48
         </attribute>
49
      </complexType>
50
   </element>
51
52
   <element name="scriptResolver">
53
      <annotation>
54
         <documentation>
55
            A resolver that can help determine equality between workspace-local IFiles and JavaScript ScriptReferences
56
         </documentation>
57
      </annotation>
58
      <complexType>
59
         <attribute name="class" type="string" use="required">
60
            <annotation>
61
               <documentation>
62
                  The fully qualified name of the Java class that implements org.eclipse.wst.jsdt.debug.core.model.IScriptResolver
63
               </documentation>
64
               <appinfo>
65
                  <meta.attribute kind="java" basedOn=":org.eclipse.wst.jsdt.debug.core.model.IScriptResolver"/>
66
               </appinfo>
67
            </annotation>
68
         </attribute>
69
      </complexType>
70
   </element>
71
72
   <annotation>
73
      <appinfo>
74
         <meta.section type="since"/>
75
      </appinfo>
76
      <documentation>
77
         3.4
78
      </documentation>
79
   </annotation>
80
81
   <annotation>
82
      <appinfo>
83
         <meta.section type="examples"/>
84
      </appinfo>
85
      <documentation>
86
         The following is an example of the default script resolver:
87
&lt;pre&gt;
88
   &lt;extension point=&quot;org.eclipse.wst.jsdt.debug.core.scriptResolvers&quot;&gt;
89
      &lt;scriptResolver
90
            class=&quot;org.eclipse.wst.jsdt.debug.internal.core.model.DefaultScriptResolver&quot;&gt;
91
      &lt;/scriptResolver&gt;
92
   &lt;/extension&gt;
93
&lt;/pre&gt;
94
      </documentation>
95
   </annotation>
96
97
   <annotation>
98
      <appinfo>
99
         <meta.section type="apiinfo"/>
100
      </appinfo>
101
      <documentation>
102
         The class field must specify the fully qualified name of the the class the implements &lt;code&gt;org.eclipse.wst.jsdt.debug.core.model.IScriptResolver.java&lt;/code&gt;.
103
      </documentation>
104
   </annotation>
105
106
   <annotation>
107
      <appinfo>
108
         <meta.section type="implementation"/>
109
      </appinfo>
110
      <documentation>
111
         [Enter information about supplied implementation of this extension point.]
112
      </documentation>
113
   </annotation>
114
115
   <annotation>
116
      <appinfo>
117
         <meta.section type="copyright"/>
118
      </appinfo>
119
      <documentation>
120
         Copyright (c) 2011 IBM Corporation and others.&lt;br&gt;
121
All rights reserved. This program and the accompanying materials are made 
122
available under the terms of the Eclipse Public License v1.0 which 
123
accompanies this distribution, and is available at 
124
&lt;a href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
125
      </documentation>
126
   </annotation>
127
128
</schema>
(-)src/org/eclipse/wst/jsdt/debug/core/model/IScriptResolver.java (+47 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.wst.jsdt.debug.core.model;
12
13
import java.net.URI;
14
15
import org.eclipse.core.resources.IFile;
16
import org.eclipse.core.runtime.IPath;
17
import org.eclipse.wst.jsdt.debug.core.jsdi.ScriptReference;
18
19
/**
20
 * This resolver allows contributors to plug-in to the process of resolving a {@link ScriptReference}'s 
21
 * {@link URI} to a workspace-local {@link IFile}.
22
23
 * @noextend This interface is not intended to be extended by clients.
24
 * @since 3.4
25
 */
26
public interface IScriptResolver {
27
28
	/**
29
	 * This method determines if the given {@link IPath} matches the {@link URI} from {@link ScriptReference#sourceURI()}.
30
31
	 * @param script the {@link ScriptReference} to compare the source {@link URI} from - never <code>null</code>
32
	 * @param path the path to match against the source {@link URI} - never <code>null</code>
33
	 * 
34
	 * @return <code>true</code> if the source {@link URI} of the given {@link ScriptReference} is considered to match the given {@link IPath}, <code>false</code> otherwise.
35
	 */
36
	public boolean matches(ScriptReference script, IPath path);
37
	
38
	/**
39
	 * This method is used to find the workspace {@link IFile} that corresponds to the source {@link URI} from the given {@link ScriptReference}.
40
	 * <br><br>
41
	 * If no file can be determined the method must return <code>null</code>. The result will be checked for existence.
42
	 * 
43
	 * @param script the {@link ScriptReference} to find the {@link IFile} for
44
	 * @return the {@link IFile} for the {@link ScriptReference} or <code>null</code>
45
	 */
46
	public IFile getFile(ScriptReference script);
47
}
(-)src/org/eclipse/wst/jsdt/debug/internal/core/Constants.java (+5 lines)
Lines 73-78 Link Here
73
	 * The name of the launching connectors extension point
73
	 * The name of the launching connectors extension point
74
	 */
74
	 */
75
	static final String LAUNCHING_CONNECTORS = "launchingConnectors"; //$NON-NLS-1$
75
	static final String LAUNCHING_CONNECTORS = "launchingConnectors"; //$NON-NLS-1$
76
	/**
77
	 * The name of the script resolvers extension point
78
	 * @since 3.4
79
	 */
80
	static final String SCRIPT_RESOLVERS = "scriptResolvers"; //$NON-NLS-1$
76
	
81
	
77
//#########  PREFERENCES  ############
82
//#########  PREFERENCES  ############
78
	/**
83
	/**
(-)src/org/eclipse/wst/jsdt/debug/internal/core/JavaScriptDebugPlugin.java (+17 lines)
Lines 27-32 Link Here
27
import org.eclipse.core.runtime.preferences.InstanceScope;
27
import org.eclipse.core.runtime.preferences.InstanceScope;
28
import org.eclipse.wst.jsdt.debug.internal.core.launching.ConnectorsManager;
28
import org.eclipse.wst.jsdt.debug.internal.core.launching.ConnectorsManager;
29
import org.eclipse.wst.jsdt.debug.internal.core.model.BreakpointParticipantManager;
29
import org.eclipse.wst.jsdt.debug.internal.core.model.BreakpointParticipantManager;
30
import org.eclipse.wst.jsdt.debug.internal.core.model.ScriptResolutionManager;
30
import org.osgi.framework.BundleContext;
31
import org.osgi.framework.BundleContext;
31
32
32
/**
33
/**
Lines 64-69 Link Here
64
	 */
65
	 */
65
	private static JavaScriptPreferencesManager prefmanager = null;
66
	private static JavaScriptPreferencesManager prefmanager = null;
66
	/**
67
	/**
68
	 * Singleton {@link ScriptResolutionManager}
69
	 */
70
	private static ScriptResolutionManager resolutionmanager = null;
71
	/**
67
	 * Handle to the 'External JavaScript Source' project
72
	 * Handle to the 'External JavaScript Source' project
68
	 */
73
	 */
69
	private static IProject extSrcProject = null;
74
	private static IProject extSrcProject = null;
Lines 94-99 Link Here
94
	}
99
	}
95
	
100
	
96
	/**
101
	/**
102
	 * Returns the singleton {@link ScriptResolutionManager}
103
	 * @return the {@link ScriptResolutionManager}
104
	 * @since 3.4
105
	 */
106
	public static synchronized ScriptResolutionManager getResolutionManager() {
107
		if(resolutionmanager == null) {
108
			resolutionmanager = new ScriptResolutionManager();
109
		}
110
		return resolutionmanager;
111
	}
112
	
113
	/**
97
	 * Returns the current handle to the 'External JavaScript Source' project or <code>null</code>. If the project
114
	 * Returns the current handle to the 'External JavaScript Source' project or <code>null</code>. If the project
98
	 * is not accessible it can be created by passing <code>true</code> in for the create parameter.
115
	 * is not accessible it can be created by passing <code>true</code> in for the create parameter.
99
	 * 
116
	 * 
(-)src/org/eclipse/wst/jsdt/debug/internal/core/breakpoints/JavaScriptBreakpoint.java (-26 / +5 lines)
Lines 10-16 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.wst.jsdt.debug.internal.core.breakpoints;
11
package org.eclipse.wst.jsdt.debug.internal.core.breakpoints;
12
12
13
import java.net.URI;
14
import java.net.URISyntaxException;
13
import java.net.URISyntaxException;
15
import java.util.ArrayList;
14
import java.util.ArrayList;
16
import java.util.HashMap;
15
import java.util.HashMap;
Lines 20-26 Link Here
20
19
21
import org.eclipse.core.resources.IMarker;
20
import org.eclipse.core.resources.IMarker;
22
import org.eclipse.core.resources.IWorkspace;
21
import org.eclipse.core.resources.IWorkspace;
23
import org.eclipse.core.resources.IWorkspaceRoot;
24
import org.eclipse.core.resources.IWorkspaceRunnable;
22
import org.eclipse.core.resources.IWorkspaceRunnable;
25
import org.eclipse.core.resources.ResourcesPlugin;
23
import org.eclipse.core.resources.ResourcesPlugin;
26
import org.eclipse.core.runtime.CoreException;
24
import org.eclipse.core.runtime.CoreException;
Lines 43-49 Link Here
43
import org.eclipse.wst.jsdt.debug.core.model.JavaScriptDebugModel;
41
import org.eclipse.wst.jsdt.debug.core.model.JavaScriptDebugModel;
44
import org.eclipse.wst.jsdt.debug.internal.core.Constants;
42
import org.eclipse.wst.jsdt.debug.internal.core.Constants;
45
import org.eclipse.wst.jsdt.debug.internal.core.JavaScriptDebugPlugin;
43
import org.eclipse.wst.jsdt.debug.internal.core.JavaScriptDebugPlugin;
46
import org.eclipse.wst.jsdt.debug.internal.core.Messages;
47
import org.eclipse.wst.jsdt.debug.internal.core.launching.SourceLookup;
44
import org.eclipse.wst.jsdt.debug.internal.core.launching.SourceLookup;
48
import org.eclipse.wst.jsdt.debug.internal.core.model.IJavaScriptEventListener;
45
import org.eclipse.wst.jsdt.debug.internal.core.model.IJavaScriptEventListener;
49
import org.eclipse.wst.jsdt.debug.internal.core.model.JavaScriptDebugTarget;
46
import org.eclipse.wst.jsdt.debug.internal.core.model.JavaScriptDebugTarget;
Lines 61-67 Link Here
61
	 * The total count of all of the targets this breakpoint is installed in
58
	 * The total count of all of the targets this breakpoint is installed in
62
	 */
59
	 */
63
	public static final String INSTALL_COUNT = JavaScriptDebugPlugin.PLUGIN_ID + ".install_count"; //$NON-NLS-1$
60
	public static final String INSTALL_COUNT = JavaScriptDebugPlugin.PLUGIN_ID + ".install_count"; //$NON-NLS-1$
64
61
	
65
	private HashSet targets = null;
62
	private HashSet targets = null;
66
	private HashMap requestspertarget = new HashMap(4);
63
	private HashMap requestspertarget = new HashMap(4);
67
64
Lines 165-172 Link Here
165
			boolean success = true;
162
			boolean success = true;
166
			for (Iterator iter = scripts.iterator(); iter.hasNext();) {
163
			for (Iterator iter = scripts.iterator(); iter.hasNext();) {
167
				ScriptReference script = (ScriptReference) iter.next();
164
				ScriptReference script = (ScriptReference) iter.next();
168
				if (scriptPathMatches(script))
165
				if (JavaScriptDebugPlugin.getResolutionManager().matches(script, new Path(getScriptPath()))) {
169
					success &= createRequest(target, script);
166
					success &= createRequest(target, script);
167
				}
170
			}
168
			}
171
			if (success) {
169
			if (success) {
172
				if (this.targets == null) {
170
				if (this.targets == null) {
Lines 437-444 Link Here
437
			ScriptReference script = sevent.script();
435
			ScriptReference script = sevent.script();
438
			
436
			
439
			try {
437
			try {
440
				if (scriptPathMatches(script)) 
438
				if (JavaScriptDebugPlugin.getResolutionManager().matches(script, new Path(getScriptPath()))) {
441
					createRequest(target, script);
439
					createRequest(target, script);
440
				}
442
			} catch (CoreException ce) {
441
			} catch (CoreException ce) {
443
				JavaScriptDebugPlugin.log(ce);
442
				JavaScriptDebugPlugin.log(ce);
444
			}
443
			}
Lines 446-471 Link Here
446
		return true;
445
		return true;
447
	}
446
	}
448
447
449
	protected boolean scriptPathMatches(ScriptReference script) throws CoreException {
450
		URI sourceURI = script.sourceURI();
451
		if ("file".equals(sourceURI.getScheme())) {//$NON-NLS-1$			
452
			IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
453
			URI workspaceURI = workspaceRoot.getRawLocationURI();			
454
			sourceURI = workspaceURI.relativize(sourceURI);
455
		}
456
		String path = getScriptPath();
457
		IPath spath = new Path(path);
458
		if(spath.segment(0).equals(Messages.external_javascript_source)) {
459
			spath = spath.removeFirstSegments(1).makeAbsolute();
460
		}
461
		//XXX use the same algorithm we use to save the source to 'encode' the source URI for comparison
462
		IPath uripath = SourceLookup.getSourcePath(sourceURI);
463
		if(uripath != null) {
464
			uripath = uripath.makeAbsolute();
465
		}
466
		return spath.equals(uripath);
467
	}
468
469
	/**
448
	/**
470
	 * Returns if the type names for the breakpoint are equal or not. Two <code>null</code> type names are considered to be equal.
449
	 * Returns if the type names for the breakpoint are equal or not. Two <code>null</code> type names are considered to be equal.
471
	 * 
450
	 * 
(-)src/org/eclipse/wst/jsdt/debug/internal/core/breakpoints/JavaScriptLoadBreakpoint.java (-6 / +20 lines)
Lines 20-25 Link Here
20
import org.eclipse.core.resources.ResourcesPlugin;
20
import org.eclipse.core.resources.ResourcesPlugin;
21
import org.eclipse.core.runtime.CoreException;
21
import org.eclipse.core.runtime.CoreException;
22
import org.eclipse.core.runtime.IProgressMonitor;
22
import org.eclipse.core.runtime.IProgressMonitor;
23
import org.eclipse.core.runtime.Path;
23
import org.eclipse.debug.core.DebugException;
24
import org.eclipse.debug.core.DebugException;
24
import org.eclipse.debug.core.model.IBreakpoint;
25
import org.eclipse.debug.core.model.IBreakpoint;
25
import org.eclipse.wst.jsdt.debug.core.breakpoints.IJavaScriptBreakpointParticipant;
26
import org.eclipse.wst.jsdt.debug.core.breakpoints.IJavaScriptBreakpointParticipant;
Lines 102-108 Link Here
102
			ScriptReference script = sevent.script();
103
			ScriptReference script = sevent.script();
103
			JavaScriptThread thread = target.findThread((sevent).thread());
104
			JavaScriptThread thread = target.findThread((sevent).thread());
104
			if (thread != null) {
105
			if (thread != null) {
105
				if(isGlobalLoadSuspend(target.getVM())) {
106
				if(isGlobalLoadSuspend()) {
107
					if(!supportsGlobalSuspend(target.getVM())) {
108
						return true;
109
					}
106
					JavaScriptPreferencesManager.setGlobalSuspendOn(script.sourceURI().toString());
110
					JavaScriptPreferencesManager.setGlobalSuspendOn(script.sourceURI().toString());
107
					thread.addBreakpoint(this);
111
					thread.addBreakpoint(this);
108
					return false;
112
					return false;
Lines 126-132 Link Here
126
	 */
130
	 */
127
	private boolean isMatchedScriptLoadSuspend(ScriptReference script, JavaScriptThread thread, boolean suspendVote) {
131
	private boolean isMatchedScriptLoadSuspend(ScriptReference script, JavaScriptThread thread, boolean suspendVote) {
128
		try {
132
		try {
129
			if (scriptPathMatches(script)) {
133
			if (JavaScriptDebugPlugin.getResolutionManager().matches(script, new Path(getScriptPath()))) {
130
				int vote = thread.suspendForScriptLoad(this, script, suspendVote);
134
				int vote = thread.suspendForScriptLoad(this, script, suspendVote);
131
				return (vote & IJavaScriptBreakpointParticipant.SUSPEND) > 0 || vote == IJavaScriptBreakpointParticipant.DONT_CARE;
135
				return (vote & IJavaScriptBreakpointParticipant.SUSPEND) > 0 || vote == IJavaScriptBreakpointParticipant.DONT_CARE;
132
			}
136
			}
Lines 138-148 Link Here
138
	}
142
	}
139
	
143
	
140
	/**
144
	/**
141
	 * Returns if this breakpoint supports global suspend
145
	 * Use reflection hack to opt-out of global suspend
142
	 * 
146
	 * 
143
	 * @return <code>true</code> if we should suspend on all script loads <code>false</code> otherwise
147
	 * @param vm
148
	 * @return <code>true</code> if the backing {@link VirtualMachine} supports global suspend
144
	 */
149
	 */
145
	private boolean isGlobalLoadSuspend(VirtualMachine vm) {
150
	boolean supportsGlobalSuspend(VirtualMachine vm) {
146
		boolean supports = true;
151
		boolean supports = true;
147
		try {
152
		try {
148
			//TODO consider supportsSuspendOnScriptLoads for future VirtualMachine extensions
153
			//TODO consider supportsSuspendOnScriptLoads for future VirtualMachine extensions
Lines 153-160 Link Here
153
			//assume the method is not there / problematic
158
			//assume the method is not there / problematic
154
			supports = true;
159
			supports = true;
155
		}
160
		}
161
		return supports;
162
	}
163
	
164
	/**
165
	 * Returns if this breakpoint supports global suspend
166
	 * 
167
	 * @return <code>true</code> if we should suspend on all script loads <code>false</code> otherwise
168
	 */
169
	private boolean isGlobalLoadSuspend() {
156
		try {
170
		try {
157
			return supports && ensureMarker().getAttribute(GLOBAL_SUSPEND, false);
171
			return ensureMarker().getAttribute(GLOBAL_SUSPEND, false);
158
		}
172
		}
159
		catch(CoreException ce) {
173
		catch(CoreException ce) {
160
			JavaScriptDebugPlugin.log(ce);
174
			JavaScriptDebugPlugin.log(ce);
(-)src/org/eclipse/wst/jsdt/debug/internal/core/launching/SourceLookup.java (-6 / +9 lines)
Lines 40-46 Link Here
40
public final class SourceLookup {
40
public final class SourceLookup {
41
41
42
	public static final QualifiedName SCRIPT_URL = new QualifiedName(JavaScriptCore.PLUGIN_ID, "scriptURL"); //$NON-NLS-1$
42
	public static final QualifiedName SCRIPT_URL = new QualifiedName(JavaScriptCore.PLUGIN_ID, "scriptURL"); //$NON-NLS-1$
43
	
43
	public static final IPath TOP_LEVEL_PATH = new Path("/"); //$NON-NLS-1$
44
	/**
44
	/**
45
	 * Returns the name of the source object to lookup or <code>null</code>
45
	 * Returns the name of the source object to lookup or <code>null</code>
46
	 * if the object is not a {@link IJavaScriptStackFrame} or an {@link IScript}
46
	 * if the object is not a {@link IJavaScriptStackFrame} or an {@link IScript}
Lines 50-61 Link Here
50
	 * @since 1.1
50
	 * @since 1.1
51
	 */
51
	 */
52
	public static String getSourceName(Object object) {
52
	public static String getSourceName(Object object) {
53
		String name = null;
53
		if (object instanceof IJavaScriptStackFrame) {
54
		if (object instanceof IJavaScriptStackFrame) {
54
			return ((IJavaScriptStackFrame) object).getSourceName();
55
			name = ((IJavaScriptStackFrame) object).getSourceName();
55
		}
56
		}
56
		if(object instanceof IScript) {
57
		if(object instanceof IScript) {
57
			String name = URIUtil.lastSegment(((IScript)object).sourceURI());
58
			name = URIUtil.lastSegment(((IScript)object).sourceURI());
58
			if(!JavaScriptCore.isJavaScriptLikeFileName(name)) {
59
		}
60
		if(name != null) {
61
			if(new Path(name).getFileExtension() == null) {
59
				//append .js, there is no case where we would look up a file with no extension from a script node
62
				//append .js, there is no case where we would look up a file with no extension from a script node
60
				StringBuffer buf = new StringBuffer(name.length()+3);
63
				StringBuffer buf = new StringBuffer(name.length()+3);
61
				buf.append(name).append('.').append(Constants.JS_EXTENSION);
64
				buf.append(name).append('.').append(Constants.JS_EXTENSION);
Lines 165-171 Link Here
165
			return null;
168
			return null;
166
		}
169
		}
167
		if(uripath.trim().equals("/")) { //$NON-NLS-1$
170
		if(uripath.trim().equals("/")) { //$NON-NLS-1$
168
			uripath = "page.js"; //$NON-NLS-1$
171
			uripath = "index.htm"; //$NON-NLS-1$
169
		}
172
		}
170
		String host = sourceuri.getHost();
173
		String host = sourceuri.getHost();
171
		IPath path = null;
174
		IPath path = null;
Lines 244-250 Link Here
244
			newpath = newpath.append((String) segments.get(i));
247
			newpath = newpath.append((String) segments.get(i));
245
		}
248
		}
246
		String ext = newpath.getFileExtension(); 
249
		String ext = newpath.getFileExtension(); 
247
		if(ext == null || !Constants.JS_EXTENSION.equals(ext)) {
250
		if(ext == null && !Constants.JS_EXTENSION.equals(ext)) {
248
			newpath = newpath.addFileExtension(Constants.JS_EXTENSION);
251
			newpath = newpath.addFileExtension(Constants.JS_EXTENSION);
249
		}
252
		}
250
		return newpath; 
253
		return newpath; 
(-)src/org/eclipse/wst/jsdt/debug/internal/core/model/DefaultScriptResolver.java (+98 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.wst.jsdt.debug.internal.core.model;
12
13
import java.net.URI;
14
15
import org.eclipse.core.resources.IFile;
16
import org.eclipse.core.resources.IResource;
17
import org.eclipse.core.resources.IWorkspaceRoot;
18
import org.eclipse.core.resources.ResourcesPlugin;
19
import org.eclipse.core.runtime.IPath;
20
import org.eclipse.core.runtime.Path;
21
import org.eclipse.core.runtime.URIUtil;
22
import org.eclipse.wst.jsdt.debug.core.jsdi.ScriptReference;
23
import org.eclipse.wst.jsdt.debug.core.model.IScriptResolver;
24
import org.eclipse.wst.jsdt.debug.internal.core.Messages;
25
import org.eclipse.wst.jsdt.debug.internal.core.launching.SourceLookup;
26
27
/**
28
 * Default implementation of an {@link IScriptResolver}
29
 * @since 3.4
30
 */
31
public class DefaultScriptResolver implements IScriptResolver {
32
33
	/* (non-Javadoc)
34
	 * @see org.eclipse.wst.jsdt.debug.core.model.IScriptResolver#matches(org.eclipse.wst.jsdt.debug.core.jsdi.ScriptReference, org.eclipse.core.runtime.IPath)
35
	 */
36
	public boolean matches(ScriptReference script, IPath path) {
37
		if(guessScriptMatches(script, path)) {
38
			return true;
39
		}
40
		//no luck, try an exact match
41
		URI sourceURI = script.sourceURI();
42
		if (URIUtil.isFileURI(sourceURI)) {
43
			IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
44
			URI workspaceURI = workspaceRoot.getRawLocationURI();			
45
			sourceURI = workspaceURI.relativize(sourceURI);
46
		}
47
		IPath spath = path;
48
		if(spath.segmentCount() > 0 && spath.segment(0).equals(Messages.external_javascript_source)) {
49
			spath = spath.removeFirstSegments(1).makeAbsolute();
50
		}
51
		IPath uripath = SourceLookup.getSourcePath(sourceURI);
52
		if(uripath != null) {
53
			uripath = uripath.makeAbsolute();
54
		}
55
		return spath.equals(uripath);
56
	}
57
58
	/**
59
	 * Guesses if the paths are considered equal by walking backward from the last segment of the paths and counting the matching segments. 
60
	 * The paths are guessed to be equal iff any two or more segments match in order.
61
	 * 
62
	 * @param script the {@link ScriptReference}
63
	 * @param path the path to compare
64
	 * @return <code>true</code> if the paths 'match', <code>false</code> otherwise
65
	 */
66
	boolean guessScriptMatches(ScriptReference script, IPath path) {
67
		IPath newpath = path.makeAbsolute();
68
		IPath uri = new Path(script.sourceURI().getPath());
69
		if(SourceLookup.TOP_LEVEL_PATH.equals(newpath) && SourceLookup.TOP_LEVEL_PATH.equals(uri)) {
70
			return true;
71
		}
72
		uri = uri.makeAbsolute();
73
		int matched_segments = 0;
74
		int last = uri.segmentCount()-1;
75
		for(int i  = newpath.segmentCount()-1; i > -1; i--) {
76
			if(last < 0) {
77
				break;
78
			}
79
			if(newpath.segment(i).equals(uri.segment(last))) {
80
				matched_segments++;
81
				last--;
82
			}
83
		}
84
		return matched_segments > 1;
85
	}
86
	
87
	/* (non-Javadoc)
88
	 * @see org.eclipse.wst.jsdt.debug.core.model.IScriptResolver#getFile(org.eclipse.wst.jsdt.debug.core.jsdi.ScriptReference)
89
	 */
90
	public IFile getFile(ScriptReference script) {
91
		IPath p = SourceLookup.getSourcePath(script.sourceURI());
92
		IResource res = ResourcesPlugin.getWorkspace().getRoot().findMember(p);
93
		if(res.getType() == IResource.FILE) {
94
			return (IFile) res;
95
		}
96
		return null;
97
	}
98
}
(-)src/org/eclipse/wst/jsdt/debug/internal/core/model/ScriptResolutionManager.java (+90 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.wst.jsdt.debug.internal.core.model;
12
13
import java.util.Arrays;
14
import java.util.List;
15
16
import org.eclipse.core.runtime.IConfigurationElement;
17
import org.eclipse.core.runtime.IExtensionPoint;
18
import org.eclipse.core.runtime.IPath;
19
import org.eclipse.core.runtime.ListenerList;
20
import org.eclipse.core.runtime.Platform;
21
import org.eclipse.wst.jsdt.debug.core.jsdi.ScriptReference;
22
import org.eclipse.wst.jsdt.debug.core.model.IScriptResolver;
23
import org.eclipse.wst.jsdt.debug.internal.core.Constants;
24
import org.eclipse.wst.jsdt.debug.internal.core.JavaScriptDebugPlugin;
25
26
/**
27
 * Handles the collection of {@link ScriptResolverExtension}s and provide useful utilities for path / script handling
28
 * @since 3.4
29
 */
30
public final class ScriptResolutionManager {
31
32
	static IScriptResolver[] NO_RESOLVERS = new IScriptResolver[0];
33
	ListenerList resolvers = null;
34
	
35
	/**
36
	 * This is a convenience method that consults all of the registered {@link IScriptResolver}s.
37
	 * <br><br>
38
	 * This method will return <code>true</code> iff any one (or all) of the {@link IScriptResolver}s returns <code>true</code>
39
	 * @param script the script to check
40
	 * @param path the path to compare against
41
	 * @return <code>true</code> if any one (or all) of the {@link IScriptResolver}s return <code>true</code>, <code>false</code> otherwise
42
	 */
43
	public boolean matches(ScriptReference script, IPath path) {
44
		IScriptResolver[] res = getResolvers();
45
		for (int i = 0; i < res.length; i++) {
46
			if(res[i].matches(script, path)) {
47
				return true;
48
			}
49
		}
50
		return false;
51
	}
52
	
53
	/**
54
	 * Returns the complete listing of {@link IScriptResolver}s or an empty array, never <code>null</code>
55
	 * 
56
	 * @return the complete listing of {@link IScriptResolver}s
57
	 */
58
	public IScriptResolver[] getResolvers() {
59
		loadResolvers();
60
		if(resolvers.size() < 1) {
61
			return NO_RESOLVERS;
62
		}
63
		List res = Arrays.asList(resolvers.getListeners());
64
		return (IScriptResolver[]) res.toArray(new IScriptResolver[res.size()]);
65
	}
66
	
67
	/**
68
	 * load up all the extension points to the delegate listeners
69
	 */
70
	void loadResolvers() {
71
		if(resolvers == null) {
72
			resolvers = new ListenerList();
73
			IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(JavaScriptDebugPlugin.PLUGIN_ID, Constants.SCRIPT_RESOLVERS);
74
			IConfigurationElement[] elements = extensionPoint.getConfigurationElements();
75
			for (int i = 0; i < elements.length; i++) {
76
				resolvers.add(new ScriptResolverExtension(elements[i]));
77
			}
78
		}
79
	}
80
	
81
	/**
82
	 * Clean up
83
	 */
84
	public void dispose() {
85
		if(resolvers != null) {
86
			resolvers.clear();
87
			resolvers = null;
88
		}
89
	}
90
}
(-)src/org/eclipse/wst/jsdt/debug/internal/core/model/ScriptResolverExtension.java (+75 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.wst.jsdt.debug.internal.core.model;
12
13
import org.eclipse.core.resources.IFile;
14
import org.eclipse.core.runtime.CoreException;
15
import org.eclipse.core.runtime.IConfigurationElement;
16
import org.eclipse.core.runtime.IPath;
17
import org.eclipse.wst.jsdt.debug.core.jsdi.ScriptReference;
18
import org.eclipse.wst.jsdt.debug.core.model.IScriptResolver;
19
import org.eclipse.wst.jsdt.debug.internal.core.Constants;
20
21
/**
22
 * Default implementation of the delegate class for all {@link IScriptResolver}s
23
 * 
24
 * @since 3.4
25
 */
26
public class ScriptResolverExtension implements IScriptResolver {
27
28
	private IConfigurationElement element = null;
29
	private IScriptResolver delegate = null;
30
	
31
	/**
32
	 * Constructor
33
	 * @param element the backing {@link IConfigurationElement} to lazily load and delegate to
34
	 */
35
	public ScriptResolverExtension(IConfigurationElement element) {
36
		this.element = element;
37
	}
38
	
39
	/**
40
	 * Returns the delegate {@link IScriptResolver} from the backing {@link IConfigurationElement}
41
	 * 
42
	 * @return the delegate {@link IScriptResolver}
43
	 * @throws CoreException thrown if the delegate class fails to be created
44
	 */
45
	synchronized IScriptResolver getDelegate() throws CoreException {
46
		if(delegate == null) {
47
			delegate = (IScriptResolver) element.createExecutableExtension(Constants.CLASS);
48
		}
49
		return delegate;
50
	}
51
	
52
	/* (non-Javadoc)
53
	 * @see org.eclipse.wst.jsdt.debug.core.model.IScriptPathResolver#matches(org.eclipse.wst.jsdt.debug.core.jsdi.ScriptReference, org.eclipse.core.runtime.IPath)
54
	 */
55
	public boolean matches(ScriptReference script, IPath path) {
56
		try {
57
			return getDelegate().matches(script, path);
58
		}
59
		catch(CoreException ce) {
60
			return false;
61
		}
62
	}
63
64
	/* (non-Javadoc)
65
	 * @see org.eclipse.wst.jsdt.debug.core.model.IScriptPathResolver#getFile(org.eclipse.wst.jsdt.debug.core.jsdi.ScriptReference)
66
	 */
67
	public IFile getFile(ScriptReference script) {
68
		try {
69
			return getDelegate().getFile(script);
70
		}
71
		catch(CoreException ce) {
72
			return null;
73
		}
74
	}
75
}
(-)plugin.xml (+7 lines)
Lines 89-94 Link Here
89
               type="org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider">
89
               type="org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider">
90
         </adapter>
90
         </adapter>
91
      </factory>
91
      </factory>
92
      <factory
93
            adaptableType="org.eclipse.wst.sse.ui.StructuredTextEditor"
94
            class="org.eclipse.wst.jsdt.debug.internal.ui.adapters.JavaScriptAdapterFactory">
95
         <adapter
96
               type="org.eclipse.debug.ui.actions.IToggleBreakpointsTarget">
97
         </adapter>
98
      </factory>
92
   </extension>
99
   </extension>
93
   <extension
100
   <extension
94
         point="org.eclipse.ui.editorActions">
101
         point="org.eclipse.ui.editorActions">

Return to bug 361315