Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 333903 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/wst/jsdt/web/core/internal/JSPCorePluginResources.properties (+3 lines)
Lines 22-24 Link Here
22
JSPDirectiveValidator_2=The prefix {0} is used more than once
22
JSPDirectiveValidator_2=The prefix {0} is used more than once
23
JSPDirectiveValidator_3=A {0} value is required in this directive
23
JSPDirectiveValidator_3=A {0} value is required in this directive
24
JSPBatchValidator_0=Gathering files in {0}
24
JSPBatchValidator_0=Gathering files in {0}
25
26
JSWebResourceEventManager=JavaScript Web Resource Event Manager
27
JsCorePlugin_Initializing_JS_Web_Tools=Initializing JavaScript Web Tools
(-)src/org/eclipse/wst/jsdt/web/core/internal/JSWebResourceEventManager.java (+249 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
 *******************************************************************************/
12
package org.eclipse.wst.jsdt.web.core.internal;
13
14
import java.io.File;
15
import java.util.ArrayList;
16
import java.util.List;
17
18
import org.eclipse.core.resources.IProject;
19
import org.eclipse.core.resources.IResource;
20
import org.eclipse.core.runtime.CoreException;
21
import org.eclipse.core.runtime.IPath;
22
import org.eclipse.core.runtime.Path;
23
import org.eclipse.wst.common.componentcore.ComponentCore;
24
import org.eclipse.wst.common.componentcore.ModuleCoreNature;
25
import org.eclipse.wst.common.componentcore.resources.IVirtualFile;
26
import org.eclipse.wst.jsdt.core.IIncludePathAttribute;
27
import org.eclipse.wst.jsdt.core.IIncludePathEntry;
28
import org.eclipse.wst.jsdt.core.JavaScriptCore;
29
import org.eclipse.wst.jsdt.internal.core.ClasspathEntry;
30
import org.eclipse.wst.jsdt.internal.core.JavaProject;
31
import org.eclipse.wst.jsdt.web.core.internal.project.ModuleSourcePathProvider;
32
import org.eclipse.wst.sse.core.indexing.AbstractIndexManager;
33
34
/**
35
 * <p>This is an implementation of the {@link AbstractIndexManager} for the JavaScript Web core plugin.</p>
36
 * 
37
 * <p>Current Uses:
38
 * <ul>
39
 * <li>listen for .project changes so that JavaScript class paths can be updated
40
 * if the module core nature is added to a project</li>
41
 * </ul></p>
42
 * 
43
 * <p><b>NOTE:</b> If any other file resource change listening needs to take place in the future
44
 * in this plugin it should be done here.</p>
45
 */
46
public class JSWebResourceEventManager extends AbstractIndexManager {
47
	/** the singleton instance of the {@link JSWebResourceEventManager} */
48
	private static JSWebResourceEventManager INSTANCE;
49
	
50
	/** the name of the ".project" file where natures are stored */
51
	private static final String DOT_PROJECT_FILE_NAME = ".project"; //$NON-NLS-1$
52
	
53
	/** the location to store state */
54
	private IPath fWorkingLocation;
55
	
56
	/**
57
	 * <p>Private constructor for the resource event manager</p>
58
	 */
59
	private JSWebResourceEventManager() {
60
		super(JsCoreMessages.JSWebResourceEventManager);
61
	}
62
	
63
	/**
64
	 * @return the singleton instance of the {@link JSWebResourceEventManager}
65
	 */
66
	public static JSWebResourceEventManager getDefault() {
67
		return INSTANCE != null ? INSTANCE : (INSTANCE = new JSWebResourceEventManager());
68
	}
69
70
	/**
71
	 * @see org.eclipse.wst.sse.core.indexing.AbstractIndexManager#isResourceToIndex(int, org.eclipse.core.runtime.IPath)
72
	 */
73
	protected boolean isResourceToIndex(int type, IPath path) {
74
		String name = path.lastSegment();
75
		return 
76
			type == IResource.ROOT ||
77
			type == IResource.PROJECT || 
78
			(type == IResource.FILE && name.equals(DOT_PROJECT_FILE_NAME));
79
	}
80
81
	/**
82
	 * @see org.eclipse.wst.sse.core.indexing.AbstractIndexManager#performAction(byte, byte, org.eclipse.core.resources.IResource, org.eclipse.core.runtime.IPath)
83
	 */
84
	protected void performAction(byte source, byte action, IResource resource,
85
			IPath movePath) {
86
		
87
		switch(action) {
88
			case(AbstractIndexManager.ACTION_ADD): {
89
				if(resource.getName().equals(DOT_PROJECT_FILE_NAME)) {
90
					updateClassPathEntires(resource.getProject());
91
				}
92
				break;
93
			}
94
		}
95
96
	}
97
98
	/**
99
	 * @see org.eclipse.wst.sse.core.indexing.AbstractIndexManager#getWorkingLocation()
100
	 */
101
	protected IPath getWorkingLocation() {
102
		if(this.fWorkingLocation == null) {
103
			//create path to working area
104
    		IPath workingLocation =
105
    			JsCorePlugin.getDefault().getStateLocation().append("JSWebResourceEventManager"); //$NON-NLS-1$
106
107
            // ensure that it exists on disk
108
            File folder = new File(workingLocation.toOSString());
109
    		if (!folder.isDirectory()) {
110
    			try {
111
    				folder.mkdir();
112
    			}
113
    			catch (SecurityException e) {
114
    				Logger.logException(this.getName() +
115
    						": Error while creating state location: " + folder + //$NON-NLS-1$
116
    						" This renders the index manager irrevocably broken for this workspace session", //$NON-NLS-1$
117
    						e);
118
    			}
119
    		}
120
    		
121
    		this.fWorkingLocation = workingLocation;
122
    	}
123
    	
124
        return this.fWorkingLocation;
125
	}
126
	
127
	/**
128
	 * <p>Updates the JavaScript class path entries for the given project if
129
	 * both the Module core and JavaScript natures are installed on that project.</p>
130
	 *
131
	 * @param project {@link IProject} to update the JavaScript class path entires for
132
	 */
133
	private static void updateClassPathEntires(IProject project) {
134
		try {
135
			//if a JS project with Module core check if class path needs to be updated
136
			if (project.hasNature(JavaScriptCore.NATURE_ID) &&
137
					ModuleCoreNature.isFlexibleProject(project)) {
138
				
139
				JavaProject jsProject = (JavaProject) JavaScriptCore.create(project);
140
				
141
				IIncludePathEntry[] oldEntries = jsProject.getRawIncludepath();
142
				List updatedEntries = new ArrayList();
143
				boolean foundDefault = false;
144
				
145
				List preExistingExclusionPatterns = new ArrayList();
146
				List preExistingInclusionPatterns = new ArrayList();
147
				for(int oldEntry = 0; oldEntry < oldEntries.length; ++oldEntry) {
148
					IIncludePathAttribute[] attrs = oldEntries[oldEntry].getExtraAttributes();
149
					
150
					for(int atter = 0; atter < attrs.length; ++atter) {
151
						if(attrs[atter].getName().equals(ModuleSourcePathProvider.PROVIDER_ATTRIBUTE_KEY_NAME) && 
152
								attrs[atter].getValue().equals(ModuleSourcePathProvider.PROVIDER_ATTRIBUTE_KEY_VALUE)) {
153
							foundDefault = true;
154
							
155
							//create exclusion paths that are not relative to the parent entry
156
							IPath[] exclusionPaths = oldEntries[oldEntry].getExclusionPatterns();
157
							for(int i = 0; i < exclusionPaths.length; ++i) {
158
								preExistingExclusionPatterns.add(
159
										oldEntries[oldEntry].getPath().append(exclusionPaths[i]));
160
							}
161
							
162
							//create inclusion paths that are not relative to the parent entry
163
							IPath[]inclusionPaths = oldEntries[oldEntry].getInclusionPatterns();
164
							for(int i = 0; i < inclusionPaths.length; ++i) {
165
								preExistingInclusionPatterns.add(
166
										oldEntries[oldEntry].getPath().append(inclusionPaths[i]));
167
							}
168
						} else {
169
							updatedEntries.add(oldEntries[oldEntry]);
170
						}
171
					}
172
					
173
				}
174
				
175
				//if found that a default path was added, replace with module core determined path
176
				if(foundDefault) {
177
					IResource[] roots = getRoots(project);
178
					for(int root = 0; root < roots.length; ++root) {
179
						IPath rootPath = roots[root].getFullPath();
180
181
						//find matching pre-existing exclusion patterns
182
						List exclusionPatterns = new ArrayList();
183
						for(int i = 0; i < preExistingExclusionPatterns.size(); ++i) {
184
							IPath parentRelativeExclusionPattern = PathUtils.makePatternRelativeToParent(
185
									(IPath)preExistingExclusionPatterns.get(i), rootPath);
186
							
187
							if(parentRelativeExclusionPattern != null) {
188
								exclusionPatterns.add(parentRelativeExclusionPattern);
189
							}
190
						}
191
						
192
						//find matching pre-existing inclusion patterns
193
						List inclusionPatterns = new ArrayList();
194
						for(int i = 0; i < preExistingInclusionPatterns.size(); ++i) {
195
							IPath parentRelativeInclusionPattern = PathUtils.makePatternRelativeToParent(
196
									(IPath)preExistingInclusionPatterns.get(i), rootPath);
197
							
198
							if(parentRelativeInclusionPattern != null) {
199
								inclusionPatterns.add(parentRelativeInclusionPattern);
200
							}
201
						}
202
						
203
						//create new entry entry
204
						IPath[] exclusionPaths = ClasspathEntry.EXCLUDE_NONE;
205
						if(exclusionPatterns.size() > 0) {
206
							exclusionPaths = (IPath[])exclusionPatterns.toArray(
207
									new IPath[exclusionPatterns.size()]);
208
						}
209
						IPath[] inclusionPaths = ClasspathEntry.INCLUDE_ALL;
210
						if(inclusionPatterns.size() > 0) {
211
							inclusionPaths = (IPath[])inclusionPatterns.toArray(
212
									new IPath[inclusionPatterns.size()]);
213
						}
214
						IIncludePathEntry newEntry = JavaScriptCore.newSourceEntry(
215
								rootPath,
216
								inclusionPaths,
217
								exclusionPaths,
218
								null);
219
						updatedEntries.add(newEntry);
220
					}
221
					
222
					//set include path
223
					jsProject.setRawIncludepath(
224
							(IIncludePathEntry[])updatedEntries.toArray(
225
									new IIncludePathEntry[updatedEntries.size()]),
226
							project.getLocation(), null);
227
				}
228
			}
229
		} catch(CoreException e) {
230
			Logger.logException("Error while updating JavaScript classpath.", e); //$NON-NLS-1$
231
		}
232
	}
233
	
234
	/**
235
	 * <p>Uses module core to get the roots of the given project.</p>
236
	 *
237
	 * @param project find the module core roots for this {@link IProject}
238
	 * @return the module core roots for the given {@link IProject
239
	 */
240
	private static IResource[] getRoots(IProject project) {
241
		IVirtualFile root = ComponentCore.createFile(project, Path.ROOT);
242
		IResource[] underlyingResources = root.getUnderlyingResources();
243
		if (underlyingResources == null || underlyingResources.length == 0) {
244
			underlyingResources = new IResource[]{root.getUnderlyingResource()};
245
		}
246
		
247
		return underlyingResources;
248
	}
249
}
(-)src/org/eclipse/wst/jsdt/web/core/internal/JsCoreMessages.java (+4 lines)
Lines 33-38 Link Here
33
	public static String JSPFContentPropertiesManager_Updating;
33
	public static String JSPFContentPropertiesManager_Updating;
34
	public static String JSPIndexManager_0;
34
	public static String JSPIndexManager_0;
35
	public static String JSPIndexManager_2;
35
	public static String JSPIndexManager_2;
36
	
37
	public static String JSWebResourceEventManager;
38
	public static String JsCorePlugin_Initializing_JS_Web_Tools;
39
	
36
	/**
40
	/**
37
	 * @deprecated
41
	 * @deprecated
38
	 */
42
	 */
(-)src/org/eclipse/wst/jsdt/web/core/internal/JsCorePlugin.java (-5 / +142 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2004, 2008 IBM Corporation and others.
2
 * Copyright (c) 2004, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 10-16 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.wst.jsdt.web.core.internal;
11
package org.eclipse.wst.jsdt.web.core.internal;
12
12
13
import org.eclipse.core.resources.IResourceChangeEvent;
14
import org.eclipse.core.resources.IResourceChangeListener;
15
import org.eclipse.core.resources.ISaveContext;
16
import org.eclipse.core.resources.ISaveParticipant;
17
import org.eclipse.core.resources.ISavedState;
18
import org.eclipse.core.resources.IWorkspace;
19
import org.eclipse.core.resources.IWorkspaceRunnable;
20
import org.eclipse.core.resources.ResourcesPlugin;
21
import org.eclipse.core.runtime.CoreException;
22
import org.eclipse.core.runtime.IProgressMonitor;
23
import org.eclipse.core.runtime.IStatus;
13
import org.eclipse.core.runtime.Plugin;
24
import org.eclipse.core.runtime.Plugin;
25
import org.eclipse.core.runtime.Status;
26
import org.eclipse.core.runtime.jobs.Job;
14
import org.eclipse.wst.jsdt.web.core.javascript.search.JsIndexManager;
27
import org.eclipse.wst.jsdt.web.core.javascript.search.JsIndexManager;
15
import org.osgi.framework.BundleContext;
28
import org.osgi.framework.BundleContext;
16
29
Lines 27-38 Link Here
27
	public static final String PLUGIN_ID = "org.eclipse.wst.jsdt.web.core"; //$NON-NLS-1$
40
	public static final String PLUGIN_ID = "org.eclipse.wst.jsdt.web.core"; //$NON-NLS-1$
28
	
41
	
29
	/**
42
	/**
43
	 * <p>Job used to finish tasks needed to start up the plugin but that did not have
44
	 * to block the plugin start up process.</p>
45
	 */
46
	private Job fPluginInitializerJob;
47
	
48
	/**
30
	 * Returns the shared instance.
49
	 * Returns the shared instance.
31
	 * 
32
	 * @deprecated - will be removed. Currently used to get "model preferences",
33
	 *             but there are other, better ways.
34
	 */
50
	 */
35
36
	public static JsCorePlugin getDefault() {
51
	public static JsCorePlugin getDefault() {
37
		return JsCorePlugin.plugin;
52
		return JsCorePlugin.plugin;
38
	}
53
	}
Lines 43-48 Link Here
43
	public JsCorePlugin() {
58
	public JsCorePlugin() {
44
		super();
59
		super();
45
		JsCorePlugin.plugin = this;
60
		JsCorePlugin.plugin = this;
61
		this.fPluginInitializerJob = new PluginInitializerJob();
46
	}
62
	}
47
	
63
	
48
	/*
64
	/*
Lines 58-63 Link Here
58
		// listen for classpath changes
74
		// listen for classpath changes
59
		JsIndexManager.getInstance().initialize();
75
		JsIndexManager.getInstance().initialize();
60
		// listen for resource changes to update content properties keys
76
		// listen for resource changes to update content properties keys
77
		
78
		//schedule delayed initialization
79
		this.fPluginInitializerJob.schedule(2000);
80
61
	}
81
	}
62
	
82
	
63
	/*
83
	/*
Lines 71-76 Link Here
71
		// keys
91
		// keys
72
		// stop any indexing
92
		// stop any indexing
73
		JsIndexManager.getInstance().shutdown();
93
		JsIndexManager.getInstance().shutdown();
94
		
95
		//Stop the resource event manager
96
		JSWebResourceEventManager.getDefault().stop();
97
		
74
		super.stop(context);
98
		super.stop(context);
75
	}
99
	}
100
	
101
	/**
102
	 * <p>A {@link Job} used to perform delayed initialization for the plugin</p>
103
	 */
104
	private static class PluginInitializerJob extends Job {
105
		/**
106
		 * <p>Default constructor to set up this {@link Job} as a
107
		 * long running system {@link Job}</p>
108
		 */
109
		protected PluginInitializerJob() {
110
			super(JsCoreMessages.JsCorePlugin_Initializing_JS_Web_Tools);
111
			
112
			this.setUser(false);
113
			this.setSystem(true);
114
			this.setPriority(Job.LONG);
115
		}
116
		
117
		/**
118
		 * <p>Perform delayed initialization for the plugin</p>
119
		 * 
120
		 * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
121
		 */
122
		protected IStatus run(IProgressMonitor monitor) {
123
			IStatus status = Status.OK_STATUS;
124
			final IWorkspace workspace = ResourcesPlugin.getWorkspace();
125
			try {
126
				/*
127
				 * Restore save state and process any events that happened before
128
				 * plug-in loaded. Don't do it immediately since adding the save
129
				 * participant requires a lock on the workspace to compute the
130
				 * accumulated deltas, and if the tree is not already locked it
131
				 * becomes a blocking call.
132
				 */
133
				workspace.run(new IWorkspaceRunnable() {
134
					public void run(final IProgressMonitor worspaceMonitor) throws CoreException {
135
						ISavedState savedState = null;
136
						
137
						try {
138
							//add the save participant for this bundle
139
							savedState = ResourcesPlugin.getWorkspace().addSaveParticipant(
140
									JsCorePlugin.plugin.getBundle().getSymbolicName(), new SaveParticipant());
141
						} catch (CoreException e) {
142
							Logger.logException("JSP Core Plugin failed at loading previously saved state." + //$NON-NLS-1$
143
									" All componenets dependent on this state will start as if first workspace load.", e); //$NON-NLS-1$
144
						}
145
						
146
						//if there is a saved state start up using that, else start up cold
147
						if(savedState != null) {
148
							try {
149
								Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
150
							} finally {
151
								savedState.processResourceChangeEvents(new IResourceChangeListener() {
152
									/**
153
									 * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
154
									 */
155
									public void resourceChanged(IResourceChangeEvent event) {
156
										JSWebResourceEventManager.getDefault().start(event.getDelta(), worspaceMonitor);
157
									}
158
								});
159
							}
160
						} else {
161
							JSWebResourceEventManager.getDefault().start(null, worspaceMonitor);
162
						}
163
					}
164
				}, monitor);
165
			} catch(CoreException e) {
166
				status = e.getStatus();
167
			}
168
			
169
			return status;
170
		}
171
		
172
	}
173
	
174
	/**
175
	 * Used so that all of the IResourceChangeEvents that occurred before
176
	 * this plugin loaded can be processed.
177
	 */
178
	private static class SaveParticipant implements ISaveParticipant {
179
		/**
180
		 * <p>Default constructor</p>
181
		 */
182
		protected SaveParticipant() {
183
		}
184
		
185
		/**
186
		 * @see org.eclipse.core.resources.ISaveParticipant#doneSaving(org.eclipse.core.resources.ISaveContext)
187
		 */
188
		public void doneSaving(ISaveContext context) {
189
			//ignore
190
		}
191
	
192
		/**
193
		 * @see org.eclipse.core.resources.ISaveParticipant#prepareToSave(org.eclipse.core.resources.ISaveContext)
194
		 */
195
		public void prepareToSave(ISaveContext context) throws CoreException {
196
			//ignore
197
		}
198
	
199
		/**
200
		 * @see org.eclipse.core.resources.ISaveParticipant#rollback(org.eclipse.core.resources.ISaveContext)
201
		 */
202
		public void rollback(ISaveContext context) {
203
			//ignore
204
		}
205
	
206
		/**
207
		 * @see org.eclipse.core.resources.ISaveParticipant#saving(org.eclipse.core.resources.ISaveContext)
208
		 */
209
		public void saving(ISaveContext context) throws CoreException {
210
			context.needDelta();
211
		}
212
	}
76
}
213
}
(-)src/org/eclipse/wst/jsdt/web/core/internal/PathUtils.java (+146 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
 *******************************************************************************/
12
package org.eclipse.wst.jsdt.web.core.internal;
13
14
import java.io.File;
15
16
import org.eclipse.core.runtime.IPath;
17
import org.eclipse.wst.jsdt.core.compiler.CharOperation;
18
19
/**
20
 * <p>Utility class dealing with {@link IPath}s.</p>
21
 */
22
public class PathUtils {
23
	/** represents the * pattern in a path pattern */
24
	private static final String STAR = "*"; //$NON-NLS-1$
25
	
26
	/** represents the ** pattern in a path pattern */
27
	private static final String STAR_STAR = "**"; //$NON-NLS-1$
28
	
29
	/**
30
	 * <p>Counts the number of segments in a given pattern that match segments in a given parent path.
31
	 * This counting takes place from the beginning of both the pattern and parent and stops when
32
	 * they no longer match.  The pattern can contain **, * and ? wild cards.</p>
33
	 *
34
	 * @param pattern count the number of segments of this pattern that match the given <code>parent</code>
35
	 * @param parent count the number of segments in the given <code>pattern</code> that match this path
36
	 * @return the number of segments from the beginning of the given <code>pattern</code> {@link IPath}
37
	 * that match the beginning segments of the given <code>parent</code> {@link IPath}
38
	 */
39
	public static int countPatternSegmentsThatMatchParent(IPath pattern, IPath parent) {
40
		int matchingSegments = 0;
41
		
42
		//ignore a pattern that is just ** or *
43
		if(!(pattern.segmentCount() == 1 &&
44
				(pattern.segment(0).equals(STAR_STAR) || pattern.segment(0).equals(STAR)))) {
45
			
46
			int patternSegmentIndex = 0;
47
			int parentSegmentIndex = 0;
48
			boolean starStarMode = false;
49
			while(patternSegmentIndex < pattern.segmentCount() &&
50
					parentSegmentIndex < parent.segmentCount()) {
51
				
52
				String patternSegment = pattern.segment(patternSegmentIndex);
53
				String parentSegment = parent.segment(parentSegmentIndex);
54
				
55
				/* if matching on wild
56
				 * else if wild match on multiple path segments
57
				 * else if wild match on one path segment or path segments are equal
58
				 * else not equal so stop comparing
59
				 */
60
				if(starStarMode) {
61
					/* if parent segment equals first pattern segment after a ** stop matching on it
62
					 * else still matching on **
63
					 */
64
					if(pathSegmentMatchesPattern(patternSegment, parentSegment)) {
65
						starStarMode = false;
66
						matchingSegments++;
67
						patternSegmentIndex++;
68
						parentSegmentIndex++;
69
					} else {
70
						parentSegmentIndex++;
71
					}
72
				
73
				} else if(patternSegment.equals(STAR_STAR)) { //$NON-NLS-1$
74
					starStarMode = true;
75
					
76
					//find the first pattern segment after the ** that is not another ** or *
77
					matchingSegments++;
78
					parentSegmentIndex++;
79
					
80
					for(int i = patternSegmentIndex+1; i < pattern.segmentCount(); ++i) {
81
						
82
						if(!(pattern.segment(i).equals(STAR_STAR) || //$NON-NLS-1$
83
								pattern.segment(i).equals(STAR))) { //$NON-NLS-1$
84
							
85
							patternSegmentIndex = i;
86
							break;
87
						}
88
					}
89
				} else if(patternSegment.equals("*") || //$NON-NLS-1$
90
						pathSegmentMatchesPattern(patternSegment, parentSegment)){
91
					
92
					matchingSegments++;
93
					patternSegmentIndex++;
94
					parentSegmentIndex++;
95
				} else {
96
					break;
97
				}
98
			}
99
		}
100
		
101
		return matchingSegments;
102
	}
103
	
104
	/**
105
	 * <p>Given a pattern path and a parent path attempts to truncate the given pattern path such
106
	 * that it is relative to the given parent path.</p>
107
	 *
108
	 * @param pattern attempt to truncate this {@link IPath} such that it is relative to the given
109
	 * <code>parent</code> {@link IPath}
110
	 * @param parent attempt to truncate the given <code>pattern</code> {@link IPath} such that it
111
	 * is relative to this {@link IPath}
112
	 * @return either a truncated version of the given <code>pattern</code> {@link IPath} that is
113
	 * relative to the given <code>parent</code> {@link IPath}, or <code>null</code> if the given
114
	 * <code>pattern</code> {@link IPath} could not be truncated to be relative to the given
115
	 * <code>parent</code> {@link IPath}
116
	 */
117
	public static IPath makePatternRelativeToParent(IPath pattern, IPath parent) {
118
		int matchedSegments = countPatternSegmentsThatMatchParent(pattern, parent);
119
		
120
		IPath relativePattern = null;
121
		if(matchedSegments != 0) {
122
			relativePattern = pattern.removeFirstSegments(matchedSegments);
123
			
124
			if(relativePattern.segmentCount() == 0) {
125
				relativePattern = null;
126
			} else {
127
				relativePattern.makeRelative();
128
			}
129
		}
130
		
131
		return relativePattern;
132
	}
133
	
134
	/**
135
	 * <p>A convenience method for checking the matching of one segment from a pattern path with
136
	 * one segment from a path.</p>
137
	 *Bug 334922 - CharOperation#match does not work as expected when isCaseSensitive is passed as false
138
	 * @param patternSegment check if this pattern segment is a match with the given path segment.
139
	 * @param segment check if this path segment matches with the given pattern segment
140
	 * @return <code>true</code> if the segments match, <code>false</code> otherwise
141
	 */
142
	private static boolean pathSegmentMatchesPattern(String patternSegment, String segment) {
143
		return CharOperation.pathMatch(patternSegment.toCharArray(), segment.toCharArray(),
144
				false, File.separatorChar);
145
	}
146
}
(-)src/org/eclipse/wst/jsdt/web/core/internal/project/ModuleSourcePathProvider.java (-3 / +10 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2010 IBM Corporation and others.
2
 * Copyright (c) 2010, 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 21-33 Link Here
21
import org.eclipse.wst.jsdt.core.IIncludePathAttribute;
21
import org.eclipse.wst.jsdt.core.IIncludePathAttribute;
22
import org.eclipse.wst.jsdt.core.IIncludePathEntry;
22
import org.eclipse.wst.jsdt.core.IIncludePathEntry;
23
import org.eclipse.wst.jsdt.core.JavaScriptCore;
23
import org.eclipse.wst.jsdt.core.JavaScriptCore;
24
import org.eclipse.wst.jsdt.internal.core.ClasspathEntry;
24
import org.eclipse.wst.jsdt.internal.core.util.DefaultSourcePathProvider;
25
import org.eclipse.wst.jsdt.internal.core.util.DefaultSourcePathProvider;
25
26
26
public class ModuleSourcePathProvider extends DefaultSourcePathProvider {
27
public class ModuleSourcePathProvider extends DefaultSourcePathProvider {
27
28
29
	public static final String PROVIDER_ATTRIBUTE_KEY_NAME = "provider"; //$NON-NLS-1$
30
	public static final String PROVIDER_ATTRIBUTE_KEY_VALUE = ModuleSourcePathProvider.class.getName(); //$NON-NLS-1$
31
	
28
	static final IPath VIRTUAL_CONTAINER_PATH = new Path("org.eclipse.wst.jsdt.launching.WebProject"); //$NON-NLS-1$
32
	static final IPath VIRTUAL_CONTAINER_PATH = new Path("org.eclipse.wst.jsdt.launching.WebProject"); //$NON-NLS-1$
29
	static final IIncludePathEntry VIRTUAL_SCOPE_ENTRY = JavaScriptCore.newContainerEntry(VIRTUAL_CONTAINER_PATH, new IAccessRule[0], new IIncludePathAttribute[]{IIncludePathAttribute.HIDE}, false);
33
	static final IIncludePathEntry VIRTUAL_SCOPE_ENTRY = JavaScriptCore.newContainerEntry(VIRTUAL_CONTAINER_PATH, new IAccessRule[0], new IIncludePathAttribute[]{IIncludePathAttribute.HIDE}, false);
30
34
	
31
	public ModuleSourcePathProvider() {
35
	public ModuleSourcePathProvider() {
32
	}
36
	}
33
37
Lines 53-58 Link Here
53
				}
57
				}
54
			}
58
			}
55
		}
59
		}
56
		return super.getDefaultSourcePaths(p);
60
		
61
		return new IIncludePathEntry[]{JavaScriptCore.newSourceEntry(p.getFullPath(),
62
				ClasspathEntry.INCLUDE_ALL,ClasspathEntry.EXCLUDE_NONE,null,
63
				new IIncludePathAttribute[]{JavaScriptCore.newIncludepathAttribute(PROVIDER_ATTRIBUTE_KEY_NAME, PROVIDER_ATTRIBUTE_KEY_VALUE)})};
57
	}
64
	}
58
}
65
}
(-)src/org/eclipse/wst/jsdt/web/core/tests/AllWebCoreTests.java (+12 lines)
Lines 1-3 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2009, 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
 *******************************************************************************/
1
package org.eclipse.wst.jsdt.web.core.tests;
12
package org.eclipse.wst.jsdt.web.core.tests;
2
13
3
import junit.framework.Test;
14
import junit.framework.Test;
Lines 17-22 Link Here
17
28
18
		//$JUnit-END$
29
		//$JUnit-END$
19
		suite.addTestSuite(TestHtmlTranslation.class);
30
		suite.addTestSuite(TestHtmlTranslation.class);
31
		suite.addTestSuite(PathUtilsTests.class);
20
		return suite;
32
		return suite;
21
	}
33
	}
22
34
(-)src/org/eclipse/wst/jsdt/web/core/tests/PathUtilsTests.java (+310 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
 *******************************************************************************/
12
package org.eclipse.wst.jsdt.web.core.tests;
13
14
import org.eclipse.core.runtime.IPath;
15
import org.eclipse.core.runtime.Path;
16
import org.eclipse.wst.jsdt.web.core.internal.PathUtils;
17
18
import junit.framework.Assert;
19
import junit.framework.TestCase;
20
21
/**
22
 * <p>Unit tests for the {@link PathUtils} class.</p>
23
 *
24
 */
25
public class PathUtilsTests extends TestCase {
26
27
	/**
28
	 * <p>Default constructor</p>
29
	 */
30
	public PathUtilsTests() {
31
		super("Path Utils Tests");
32
	}
33
	
34
	public void testOneSegmentParentWithOneSegmentPattern_SegmentCountTest_0() {
35
		runCountPatternSegmentsThatMatchParentTest("foo", "foo", 1);
36
	}
37
	
38
	public void testOneSegmentParentWithOneSegmentPattern_SegmentCountTest_1() {
39
		runCountPatternSegmentsThatMatchParentTest("/foo", "foo", 1);
40
	}
41
	
42
	public void testOneSegmentParentWithOneSegmentPattern_SegmentCountTest_2() {
43
		runCountPatternSegmentsThatMatchParentTest("/foo", "foo", 1);
44
	}
45
	
46
	public void testOneSegmentParentWithOneSegmentPattern_SegmentCountTest_3() {
47
		runCountPatternSegmentsThatMatchParentTest("foo", "/foo", 1);
48
	}
49
	
50
	public void testOneSegmentParentWithOneSegmentPattern_SegmentCountTest_4() {
51
		runCountPatternSegmentsThatMatchParentTest("/foo", "/foo", 1);
52
	}
53
	
54
	public void testOneSegmentParentWithTwoSegmentPattern_SegmentCountTest_0() {
55
		runCountPatternSegmentsThatMatchParentTest("foo/bar", "foo", 1);
56
	}
57
	
58
	public void testOneSegmentParentWithTwoSegmentPattern_SegmentCountTest_1() {
59
		runCountPatternSegmentsThatMatchParentTest("/foo/bar", "foo", 1);
60
	}
61
	
62
	public void testOneSegmentParentWithTwoSegmentPattern_SegmentCountTest_2() {
63
		runCountPatternSegmentsThatMatchParentTest("/foo/bar", "foo", 1);
64
	}
65
	
66
	public void testOneSegmentParentWithTwoSegmentPattern_SegmentCountTest_3() {
67
		runCountPatternSegmentsThatMatchParentTest("foo/bar", "/foo", 1);
68
	}
69
	
70
	public void testOneSegmentParentWithTwoSegmentPattern_SegmentCountTest_4() {
71
		runCountPatternSegmentsThatMatchParentTest("/foo/bar", "/foo", 1);
72
	}
73
	
74
	public void testOneSegmentParentWithTwoSegmentPattern_SegmentCountTest_5() {
75
		runCountPatternSegmentsThatMatchParentTest("foo/bar/", "foo", 1);
76
	}
77
	
78
	public void testOneSegmentParentWithTwoSegmentPattern_SegmentCountTest_6() {
79
		runCountPatternSegmentsThatMatchParentTest("/foo/bar/", "foo", 1);
80
	}
81
	
82
	public void testOneSegmentParentWithTwoSegmentPattern_SegmentCountTest_7() {
83
		runCountPatternSegmentsThatMatchParentTest("/foo/bar/", "foo", 1);
84
	}
85
	
86
	public void testOneSegmentParentWithTwoSegmentPattern_SegmentCountTest_8() {
87
		runCountPatternSegmentsThatMatchParentTest("foo/bar/", "/foo", 1);
88
	}
89
	
90
	public void testOneSegmentParentWithTwoSegmentPattern_SegmentCountTest_9() {
91
		runCountPatternSegmentsThatMatchParentTest("/foo/bar/", "/foo", 1);
92
	}
93
	
94
	public void testOneSegmentParentWithTwoSegmentPattern_SegmentCountTest_10() {
95
		runCountPatternSegmentsThatMatchParentTest("/foo/bar/", "/boo", 0);
96
	}
97
	
98
	public void testTwoSegmentParentWithThreeSegmentPattern_SegmentCountTest_0() {
99
		runCountPatternSegmentsThatMatchParentTest("/foo/bar/blarg", "/foo/bar", 2);
100
	}
101
	
102
	public void testStar_SegmentCountTest_0() {
103
		runCountPatternSegmentsThatMatchParentTest("/foo/*/blarg", "foo/bar", 2);
104
	}
105
	
106
	public void testStar_SegmentCountTest_1() {
107
		runCountPatternSegmentsThatMatchParentTest("/foo/*", "foo", 1);
108
	}
109
	
110
	public void testStar_SegmentCountTest_2() {
111
		runCountPatternSegmentsThatMatchParentTest("/foo/*", "foo/blarg", 2);
112
	}
113
	
114
	public void testStar_SegmentCountTest_3() {
115
		runCountPatternSegmentsThatMatchParentTest("/foo/*", "foo", 1);
116
	}
117
	
118
	public void testStarStar_SegmentCountTest_0() {
119
		runCountPatternSegmentsThatMatchParentTest("/foo/**", "foo", 1);
120
	}
121
	
122
	public void testStarStar_SegmentCountTest_1() {
123
		runCountPatternSegmentsThatMatchParentTest("/foo/**", "foo/bar", 2);
124
	}
125
	
126
	public void testStarStar_SegmentCountTest_2() {
127
		runCountPatternSegmentsThatMatchParentTest("/foo/**", "foo/bar/blarg", 3);
128
	}
129
	
130
	public void testStarStar_SegmentCountTest_3() {
131
		runCountPatternSegmentsThatMatchParentTest("/foo/**/blarg", "foo/bar/blarg", 3);
132
	}
133
	
134
	public void testStarStar_SegmentCountTest_4() {
135
		runCountPatternSegmentsThatMatchParentTest("/foo/**/blarg", "foo/bar/boo/blarg", 3);
136
	}
137
	
138
	public void testStarStar_SegmentCountTest_5() {
139
		runCountPatternSegmentsThatMatchParentTest("/foo/**/blarg/nerg", "foo/bar/boo/blarg", 3);
140
	}
141
	
142
	public void testQuestionMark_SegmentCountTest_0() {
143
		runCountPatternSegmentsThatMatchParentTest("foo?bar", "/fooZbar", 1);
144
	}
145
	
146
	public void testQuestionMark_SegmentCountTest_1() {
147
		runCountPatternSegmentsThatMatchParentTest("foo?bar", "/foobar", 0);
148
	}
149
	
150
	public void testOneSegmentParentWithOneSegmentPattern_TransformPatternTest_0() {
151
		runMakePatternRelativeToParentTest("foo", "foo", null);
152
	}
153
	
154
	public void testOneSegmentParentWithOneSegmentPattern_TransformPatternTest_1() {
155
		runMakePatternRelativeToParentTest("/foo", "foo", null);
156
	}
157
	
158
	public void testOneSegmentParentWithOneSegmentPattern_TransformPatternTest_2() {
159
		runMakePatternRelativeToParentTest("/foo", "foo", null);
160
	}
161
	
162
	public void testOneSegmentParentWithOneSegmentPattern_TransformPatternTest_3() {
163
		runMakePatternRelativeToParentTest("foo", "foo", null);
164
	}
165
	
166
	public void testOneSegmentParentWithOneSegmentPattern_TransformPatternTest_4() {
167
		runMakePatternRelativeToParentTest("/foo", "foo", null);
168
	}
169
	
170
	public void testOneSegmentParentWithTwoSegmentPattern_TransformPatternTest_0() {
171
		runMakePatternRelativeToParentTest("foo/bar", "foo", "bar/");
172
	}
173
	
174
	public void testOneSegmentParentWithTwoSegmentPattern_TransformPatternTest_1() {
175
		runMakePatternRelativeToParentTest("/foo/bar", "foo", "bar/");
176
	}
177
	
178
	public void testOneSegmentParentWithTwoSegmentPattern_TransformPatternTest_2() {
179
		runMakePatternRelativeToParentTest("/foo/bar", "foo", "bar/");
180
	}
181
	
182
	public void testOneSegmentParentWithTwoSegmentPattern_TransformPatternTest_3() {
183
		runMakePatternRelativeToParentTest("foo/bar", "/foo", "bar/");
184
	}
185
	
186
	public void testOneSegmentParentWithTwoSegmentPattern_TransformPatternTest_4() {
187
		runMakePatternRelativeToParentTest("/foo/bar", "/foo", "bar/");
188
	}
189
	
190
	public void testOneSegmentParentWithTwoSegmentPattern_TransformPatternTest_5() {
191
		runMakePatternRelativeToParentTest("foo/bar/", "foo", "bar/");
192
	}
193
	
194
	public void testOneSegmentParentWithTwoSegmentPattern_TransformPatternTest_6() {
195
		runMakePatternRelativeToParentTest("/foo/bar/", "foo", "bar/");
196
	}
197
	
198
	public void testOneSegmentParentWithTwoSegmentPattern_TransformPatternTest_7() {
199
		runMakePatternRelativeToParentTest("/foo/bar/", "foo", "bar/");
200
	}
201
	
202
	public void testOneSegmentParentWithTwoSegmentPattern_TransformPatternTest_8() {
203
		runMakePatternRelativeToParentTest("foo/bar/", "/foo", "bar/");
204
	}
205
	
206
	public void testOneSegmentParentWithTwoSegmentPattern_TransformPatternTest_9() {
207
		runMakePatternRelativeToParentTest("/foo/bar/", "/foo", "bar/");
208
	}
209
	
210
	public void testOneSegmentParentWithTwoSegmentPattern_TransformPatternTest_10() {
211
		runMakePatternRelativeToParentTest("/foo/bar/", "/boo", null);
212
	}
213
	
214
	public void testTwoSegmentParentWithThreeSegmentPattern_TransformPatternTest_0() {
215
		runMakePatternRelativeToParentTest("/foo/bar/blarg", "/foo/bar", "blarg/");
216
	}
217
	
218
	public void testStar_TransformPatternTest_0() {
219
		runMakePatternRelativeToParentTest("/foo/*/blarg", "foo/bar", "blarg/");
220
	}
221
	
222
	public void testStar_TransformPatternTest_1() {
223
		runMakePatternRelativeToParentTest("/foo/*", "foo", "*/");
224
	}
225
	
226
	public void testStar_TransformPatternTest_2() {
227
		runMakePatternRelativeToParentTest("/foo/*", "foo/blarg/", null);
228
	}
229
	
230
	public void testStar_TransformPatternTest_3() {
231
		runMakePatternRelativeToParentTest("/foo/*", "foo", "*/");
232
	}
233
	
234
	public void testStarStar_TransformPatternTest_0() {
235
		runMakePatternRelativeToParentTest("/foo/**", "foo", "**/");
236
	}
237
	
238
	public void testStarStar_TransformPatternTest_1() {
239
		runMakePatternRelativeToParentTest("/foo/**", "foo/bar/", null);
240
	}
241
	
242
	public void testStarStar_TransformPatternTest_2() {
243
		runMakePatternRelativeToParentTest("/foo/**", "foo/bar/blarg/", null);
244
	}
245
	
246
	public void testStarStar_TransformPatternTest_3() {
247
		runMakePatternRelativeToParentTest("/foo/**/blarg", "foo/bar/blarg/", null);
248
	}
249
	
250
	public void testStarStar_TransformPatternTest_4() {
251
		runMakePatternRelativeToParentTest("/foo/**/blarg", "foo/bar/boo/blarg/", null);
252
	}
253
	
254
	public void testStarStar_TransformPatternTest_5() {
255
		runMakePatternRelativeToParentTest("/foo/**/blarg/nerg", "foo/bar/boo/blarg", "nerg/");
256
	}
257
	
258
	public void testQuestionMark_TransformPatternTest_0() {
259
		runMakePatternRelativeToParentTest("foo?bar", "/fooZbar", null);
260
	}
261
	
262
	public void testQuestionMark_TransformPatternTest_1() {
263
		runMakePatternRelativeToParentTest("foo?bar", "/foobar", null);
264
	}
265
	
266
	public void testQuestionMark_TransformPatternTest_2() {
267
		runMakePatternRelativeToParentTest("foo?bar/awesome", "/fooZbar", "awesome/");
268
	}
269
	
270
	public void testQuestionMark_TransformPatternTest_3() {
271
		runMakePatternRelativeToParentTest("foo?bar/awesome", "/foobar", null);
272
	}
273
	
274
	/**
275
	 * <p>Runs a test on {@link PathUtils#countPatternSegmentsThatMatchParent(IPath, IPath)}</p>
276
	 *
277
	 * @param pattern the pattern path to test
278
	 * @param parentPath the parent path to test
279
	 * @param expectedMatchedSegments the expected number of segments in the pattern that match the parent
280
	 */
281
	private static void runCountPatternSegmentsThatMatchParentTest(String pattern, String parentPath,
282
			int expectedMatchedSegments) {
283
		int matchedSegments = PathUtils.countPatternSegmentsThatMatchParent(
284
				new Path(pattern), new Path(parentPath));
285
		
286
		Assert.assertEquals("Number of matched path segments does not equal expected.", //$NON-NLS-1$
287
				expectedMatchedSegments, matchedSegments);
288
	}
289
	
290
	/**
291
	 * 
292
	 * <p>Runs a test on {@link PathUtils#makePatternRelativeToParent(IPath, IPath)}</p>
293
	 *
294
	 * @param pattern the pattern path to test
295
	 * @param parent the parent path to test
296
	 * @param expected the expected pattern path made relative to the parent path
297
	 */
298
	private static void runMakePatternRelativeToParentTest(String pattern, String parent, String expected) {
299
		IPath transformedPattern = PathUtils.makePatternRelativeToParent(
300
				new Path(pattern), new Path(parent));
301
		
302
		IPath expectedPath = null;
303
		if(expected != null) {
304
			expectedPath = new Path(expected);
305
		}
306
		
307
		Assert.assertEquals("Transformed pattern does not match expected.",
308
				expectedPath, transformedPattern);
309
	}
310
}

Return to bug 333903