]>
Commit | Line | Data |
---|---|---|
1b2798f6 EK |
1 | /******************************************************************************* |
2 | * Copyright (c) 2000, 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 | * Matt Chapman, mpchapman@gmail.com - 89977 Make JDT .java agnostic | |
11 | *******************************************************************************/ | |
12 | package org.eclipse.jdt.internal.corext.buildpath; | |
13 | ||
14 | import java.net.URI; | |
15 | import java.util.ArrayList; | |
16 | import java.util.Collections; | |
17 | import java.util.Iterator; | |
18 | import java.util.List; | |
19 | ||
20 | import org.eclipse.core.filesystem.EFS; | |
21 | import org.eclipse.core.filesystem.IFileStore; | |
22 | ||
23 | import org.eclipse.core.runtime.CoreException; | |
24 | import org.eclipse.core.runtime.IAdaptable; | |
25 | import org.eclipse.core.runtime.IPath; | |
26 | import org.eclipse.core.runtime.IProgressMonitor; | |
27 | import org.eclipse.core.runtime.IStatus; | |
28 | import org.eclipse.core.runtime.MultiStatus; | |
29 | import org.eclipse.core.runtime.NullProgressMonitor; | |
30 | import org.eclipse.core.runtime.OperationCanceledException; | |
31 | import org.eclipse.core.runtime.Path; | |
32 | import org.eclipse.core.runtime.SubProgressMonitor; | |
33 | ||
34 | import org.eclipse.core.resources.IContainer; | |
35 | import org.eclipse.core.resources.IFile; | |
36 | import org.eclipse.core.resources.IFolder; | |
37 | import org.eclipse.core.resources.IProject; | |
38 | import org.eclipse.core.resources.IResource; | |
39 | import org.eclipse.core.resources.IWorkspace; | |
40 | import org.eclipse.core.resources.IWorkspaceRoot; | |
41 | import org.eclipse.core.resources.ResourcesPlugin; | |
42 | ||
43 | import org.eclipse.jdt.core.IClasspathEntry; | |
44 | import org.eclipse.jdt.core.IJavaElement; | |
45 | import org.eclipse.jdt.core.IJavaModelStatus; | |
46 | import org.eclipse.jdt.core.IJavaProject; | |
47 | import org.eclipse.jdt.core.IPackageFragment; | |
48 | import org.eclipse.jdt.core.IPackageFragmentRoot; | |
49 | import org.eclipse.jdt.core.JavaConventions; | |
50 | import org.eclipse.jdt.core.JavaCore; | |
51 | import org.eclipse.jdt.core.JavaModelException; | |
52 | ||
53 | import org.eclipse.jdt.internal.corext.util.Messages; | |
54 | ||
55 | import org.eclipse.jdt.ui.PreferenceConstants; | |
56 | ||
57 | import org.eclipse.jdt.internal.ui.dialogs.StatusInfo; | |
58 | import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels; | |
59 | import org.eclipse.jdt.internal.ui.wizards.NewWizardMessages; | |
60 | import org.eclipse.jdt.internal.ui.wizards.buildpaths.ArchiveFileFilter; | |
61 | import org.eclipse.jdt.internal.ui.wizards.buildpaths.BuildPathSupport; | |
62 | import org.eclipse.jdt.internal.ui.wizards.buildpaths.CPListElement; | |
63 | import org.eclipse.jdt.internal.ui.wizards.buildpaths.CPListElementAttribute; | |
64 | import org.eclipse.jdt.internal.ui.wizards.buildpaths.newsourcepage.ClasspathModifierQueries.OutputFolderValidator; | |
65 | ||
66 | public class ClasspathModifier { | |
67 | ||
68 | private ClasspathModifier() {} | |
69 | ||
70 | public static BuildpathDelta setOutputLocation(CPListElement elementToChange, IPath outputPath, boolean allowInvalidCP, CPJavaProject cpProject) throws CoreException { | |
71 | BuildpathDelta result= new BuildpathDelta(NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_EditOutput_tooltip); | |
72 | ||
73 | IJavaProject javaProject= cpProject.getJavaProject(); | |
74 | IProject project= javaProject.getProject(); | |
75 | IWorkspace workspace= project.getWorkspace(); | |
76 | ||
77 | IPath projectPath= project.getFullPath(); | |
78 | ||
79 | if (!allowInvalidCP && cpProject.getDefaultOutputLocation().segmentCount() == 1 && !projectPath.equals(elementToChange.getPath())) { | |
80 | String outputFolderName= PreferenceConstants.getPreferenceStore().getString(PreferenceConstants.SRCBIN_BINNAME); | |
81 | cpProject.setDefaultOutputLocation(cpProject.getDefaultOutputLocation().append(outputFolderName)); | |
82 | List<CPListElement> existingEntries= cpProject.getCPListElements(); | |
83 | CPListElement elem= ClasspathModifier.getListElement(javaProject.getPath(), existingEntries); | |
84 | if (elem != null) { | |
85 | existingEntries.remove(elem); | |
86 | result.removeEntry(elem); | |
87 | } | |
88 | } | |
89 | ||
90 | if (outputPath != null) | |
91 | exclude(outputPath, cpProject.getCPListElements(), new ArrayList<CPListElement>(), cpProject.getJavaProject(), null); | |
92 | ||
93 | IPath oldOutputLocation= (IPath)elementToChange.getAttribute(CPListElement.OUTPUT); | |
94 | if (oldOutputLocation != null && oldOutputLocation.segmentCount() > 1 && !oldOutputLocation.equals(cpProject.getDefaultOutputLocation())) { | |
95 | include(cpProject, oldOutputLocation); | |
96 | result.addDeletedResource(workspace.getRoot().getFolder(oldOutputLocation)); | |
97 | } | |
98 | elementToChange.setAttribute(CPListElement.OUTPUT, outputPath); | |
99 | ||
100 | result.setDefaultOutputLocation(cpProject.getDefaultOutputLocation()); | |
101 | result.setNewEntries(cpProject.getCPListElements().toArray(new CPListElement[cpProject.getCPListElements().size()])); | |
102 | if (outputPath != null && outputPath.segmentCount() > 1) { | |
103 | result.addCreatedResource(workspace.getRoot().getFolder(outputPath)); | |
104 | } | |
105 | ||
106 | return result; | |
107 | } | |
108 | ||
109 | public static IStatus checkSetOutputLocationPrecondition(CPListElement elementToChange, IPath outputPath, boolean allowInvalidCP, CPJavaProject cpProject) throws CoreException { | |
110 | IJavaProject javaProject= cpProject.getJavaProject(); | |
111 | IProject project= javaProject.getProject(); | |
112 | IWorkspace workspace= project.getWorkspace(); | |
113 | ||
114 | IPath projectPath= project.getFullPath(); | |
115 | ||
116 | if (outputPath == null) | |
117 | outputPath= cpProject.getDefaultOutputLocation(); | |
118 | ||
119 | IStatus pathValidation= workspace.validatePath(outputPath.toString(), IResource.PROJECT | IResource.FOLDER); | |
120 | if (!pathValidation.isOK()) | |
121 | return new StatusInfo(IStatus.ERROR, Messages.format(NewWizardMessages.OutputLocationDialog_error_invalidpath, pathValidation.getMessage())); | |
122 | ||
123 | IWorkspaceRoot root= workspace.getRoot(); | |
124 | IResource res= root.findMember(outputPath); | |
125 | if (res != null) { | |
126 | // if exists, must be a folder or project | |
127 | if (res.getType() == IResource.FILE) | |
128 | return new StatusInfo(IStatus.ERROR, NewWizardMessages.OutputLocationDialog_error_existingisfile); | |
129 | } | |
130 | ||
131 | IStatus result= StatusInfo.OK_STATUS; | |
132 | ||
133 | int index= cpProject.indexOf(elementToChange); | |
134 | cpProject= cpProject.createWorkingCopy(); | |
135 | elementToChange= cpProject.get(index); | |
136 | ||
137 | if (!allowInvalidCP && cpProject.getDefaultOutputLocation().segmentCount() == 1 && !projectPath.equals(elementToChange.getPath())) { | |
138 | String outputFolderName= PreferenceConstants.getPreferenceStore().getString(PreferenceConstants.SRCBIN_BINNAME); | |
139 | cpProject.setDefaultOutputLocation(cpProject.getDefaultOutputLocation().append(outputFolderName)); | |
140 | ClasspathModifier.removeFromClasspath(javaProject, cpProject.getCPListElements(), null); | |
141 | result= new StatusInfo(IStatus.INFO, Messages.format(NewWizardMessages.OutputLocationDialog_removeProjectFromBP, BasicElementLabels.getPathLabel(cpProject.getDefaultOutputLocation(), false))); | |
142 | } | |
143 | ||
144 | exclude(outputPath, cpProject.getCPListElements(), new ArrayList<CPListElement>(), cpProject.getJavaProject(), null); | |
145 | ||
146 | IPath oldOutputLocation= (IPath)elementToChange.getAttribute(CPListElement.OUTPUT); | |
147 | if (oldOutputLocation != null && oldOutputLocation.segmentCount() > 1 && !oldOutputLocation.equals(cpProject.getDefaultOutputLocation())) { | |
148 | include(cpProject, oldOutputLocation); | |
149 | } | |
150 | elementToChange.setAttribute(CPListElement.OUTPUT, outputPath); | |
151 | ||
152 | IJavaModelStatus status= JavaConventions.validateClasspath(javaProject, cpProject.getClasspathEntries(), cpProject.getDefaultOutputLocation()); | |
153 | if (!status.isOK()) { | |
154 | if (allowInvalidCP) { | |
155 | return new StatusInfo(IStatus.WARNING, status.getMessage()); | |
156 | } else { | |
157 | return new StatusInfo(IStatus.ERROR, status.getMessage()); | |
158 | } | |
159 | } | |
160 | ||
161 | if (outputPath.segmentCount() - projectPath.segmentCount() < 1) | |
162 | return result; | |
163 | ||
164 | String lastSegment= outputPath.lastSegment(); | |
165 | if (lastSegment == null) | |
166 | return result; | |
167 | ||
168 | if (lastSegment.equals(".settings") && outputPath.segmentCount() - projectPath.segmentCount() == 1) { //$NON-NLS-1$ | |
169 | ||
170 | StatusInfo statusInfo= new StatusInfo(IStatus.WARNING, NewWizardMessages.OutputLocation_SettingsAsLocation); | |
171 | if (result.isOK()) { | |
172 | return statusInfo; | |
173 | } else { | |
174 | MultiStatus ms= new MultiStatus(result.getPlugin(), result.getCode(), new IStatus[] {result, statusInfo}, statusInfo.getMessage(), null); | |
175 | return ms; | |
176 | } | |
177 | } | |
178 | ||
179 | if (lastSegment.length() > 1 && lastSegment.charAt(0) == '.') { | |
180 | StatusInfo statusInfo= new StatusInfo(IStatus.WARNING, Messages.format(NewWizardMessages.OutputLocation_DotAsLocation, BasicElementLabels.getPathLabel(outputPath, false))); | |
181 | if (result.isOK()) { | |
182 | return statusInfo; | |
183 | } else { | |
184 | MultiStatus ms= new MultiStatus(result.getPlugin(), result.getCode(), new IStatus[] {result, statusInfo}, statusInfo.getMessage(), null); | |
185 | return ms; | |
186 | } | |
187 | } | |
188 | ||
189 | return result; | |
190 | } | |
191 | ||
192 | public static IStatus checkAddExternalJarsPrecondition(IPath[] absolutePaths, CPJavaProject cpProject) { | |
193 | IStatus result= StatusInfo.OK_STATUS; | |
194 | ||
195 | IJavaProject javaProject= cpProject.getJavaProject(); | |
196 | ||
197 | List<CPListElement> newEntries= new ArrayList<CPListElement>(); | |
198 | List<CPListElement> duplicateEntries= new ArrayList<CPListElement>(); | |
199 | List<CPListElement> existingEntries= cpProject.getCPListElements(); | |
200 | for (int i= 0; i < absolutePaths.length; i++) { | |
201 | CPListElement newEntry= new CPListElement(javaProject, IClasspathEntry.CPE_LIBRARY, absolutePaths[i], null); | |
202 | if (existingEntries.contains(newEntry)) { | |
203 | duplicateEntries.add(newEntry); | |
204 | } else { | |
205 | newEntries.add(newEntry); | |
206 | } | |
207 | } | |
208 | ||
209 | if (duplicateEntries.size() > 0) { | |
210 | String message; | |
211 | if (duplicateEntries.size() > 1) { | |
212 | StringBuffer buf= new StringBuffer(); | |
213 | for (Iterator<CPListElement> iterator= duplicateEntries.iterator(); iterator.hasNext();) { | |
214 | CPListElement dup= iterator.next(); | |
215 | buf.append('\n').append(BasicElementLabels.getResourceName(dup.getPath().lastSegment())); | |
216 | } | |
217 | message= Messages.format(NewWizardMessages.AddArchiveToBuildpathAction_DuplicateArchivesInfo_message, buf.toString()); | |
218 | } else { | |
219 | message= Messages.format(NewWizardMessages.AddArchiveToBuildpathAction_DuplicateArchiveInfo_message, BasicElementLabels.getResourceName(duplicateEntries.get(0).getPath().lastSegment())); | |
220 | } | |
221 | result= new StatusInfo(IStatus.INFO, message); | |
222 | } | |
223 | ||
224 | if (newEntries.size() == 0) | |
225 | return result; | |
226 | ||
227 | cpProject= cpProject.createWorkingCopy(); | |
228 | existingEntries= cpProject.getCPListElements(); | |
229 | ||
230 | for (Iterator<CPListElement> iterator= newEntries.iterator(); iterator.hasNext();) { | |
231 | CPListElement newEntry= iterator.next(); | |
232 | insertAtEndOfCategory(newEntry, existingEntries); | |
233 | } | |
234 | ||
235 | IJavaModelStatus cpStatus= JavaConventions.validateClasspath(javaProject, cpProject.getClasspathEntries(), cpProject.getDefaultOutputLocation()); | |
236 | if (!cpStatus.isOK()) | |
237 | return cpStatus; | |
238 | ||
239 | return result; | |
240 | } | |
241 | ||
242 | public static BuildpathDelta addExternalJars(IPath[] absolutePaths, CPJavaProject cpProject) { | |
243 | BuildpathDelta result= new BuildpathDelta(NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_AddJarCP_tooltip); | |
244 | ||
245 | IJavaProject javaProject= cpProject.getJavaProject(); | |
246 | ||
247 | List<CPListElement> existingEntries= cpProject.getCPListElements(); | |
248 | for (int i= 0; i < absolutePaths.length; i++) { | |
249 | CPListElement newEntry= new CPListElement(javaProject, IClasspathEntry.CPE_LIBRARY, absolutePaths[i], null); | |
250 | if (!existingEntries.contains(newEntry)) { | |
251 | insertAtEndOfCategory(newEntry, existingEntries); | |
252 | result.addEntry(newEntry); | |
253 | } | |
254 | } | |
255 | ||
256 | result.setNewEntries(existingEntries.toArray(new CPListElement[existingEntries.size()])); | |
257 | result.setDefaultOutputLocation(cpProject.getDefaultOutputLocation()); | |
258 | return result; | |
259 | } | |
260 | ||
261 | public static BuildpathDelta removeFromBuildpath(CPListElement[] toRemove, CPJavaProject cpProject) { | |
262 | ||
263 | IJavaProject javaProject= cpProject.getJavaProject(); | |
264 | IPath projectPath= javaProject.getPath(); | |
265 | IWorkspaceRoot workspaceRoot= javaProject.getProject().getWorkspace().getRoot(); | |
266 | ||
267 | List<CPListElement> existingEntries= cpProject.getCPListElements(); | |
268 | BuildpathDelta result= new BuildpathDelta(NewWizardMessages.NewSourceContainerWorkbookPage_ToolBar_RemoveFromCP_tooltip); | |
269 | ||
270 | for (int i= 0; i < toRemove.length; i++) { | |
271 | CPListElement element= toRemove[i]; | |
272 | existingEntries.remove(element); | |
273 | result.removeEntry(element); | |
274 | IPath path= element.getPath(); | |
275 | removeFilters(path, javaProject, existingEntries); | |
276 | if (!path.equals(projectPath)) { | |
277 | IResource member= workspaceRoot.findMember(path); | |
278 | if (member != null) | |
279 | result.addDeletedResource(member); | |
280 | } else if (cpProject.getDefaultOutputLocation().equals(projectPath) && containsSourceFolders(cpProject)) { | |
281 | String outputFolderName= PreferenceConstants.getPreferenceStore().getString(PreferenceConstants.SRCBIN_BINNAME); | |
282 | cpProject.setDefaultOutputLocation(cpProject.getDefaultOutputLocation().append(outputFolderName)); | |
283 | } | |
284 | } | |
285 | ||
286 | result.setDefaultOutputLocation(cpProject.getDefaultOutputLocation()); | |
287 | result.setNewEntries(existingEntries.toArray(new CPListElement[existingEntries.size()])); | |
288 | ||
289 | return result; | |
290 | } | |
291 | ||
292 | private static boolean containsSourceFolders(CPJavaProject cpProject) { | |
293 | List<CPListElement> elements= cpProject.getCPListElements(); | |
294 | for (Iterator<CPListElement> iterator= elements.iterator(); iterator.hasNext();) { | |
295 | CPListElement element= iterator.next(); | |
296 | if (element.getEntryKind() == IClasspathEntry.CPE_SOURCE) | |
297 | return true; | |
298 | } | |
299 | return false; | |
300 | } | |
301 | ||
302 | private static void include(CPJavaProject cpProject, IPath path) { | |
303 | List<CPListElement> elements= cpProject.getCPListElements(); | |
304 | for (Iterator<CPListElement> iterator= elements.iterator(); iterator.hasNext();) { | |
305 | CPListElement element= iterator.next(); | |
306 | element.removeFromExclusions(path); | |
307 | } | |
308 | } | |
309 | ||
310 | /** | |
311 | * Get the <code>IClasspathEntry</code> from the project and | |
312 | * convert it into a list of <code>CPListElement</code>s. | |
313 | * | |
314 | * @param project the Java project to get it's build path entries from | |
315 | * @return a list of <code>CPListElement</code>s corresponding to the | |
316 | * build path entries of the project | |
317 | * @throws JavaModelException | |
318 | */ | |
319 | public static List<CPListElement> getExistingEntries(IJavaProject project) throws JavaModelException { | |
320 | IClasspathEntry[] classpathEntries= project.getRawClasspath(); | |
321 | ArrayList<CPListElement> newClassPath= new ArrayList<CPListElement>(); | |
322 | for (int i= 0; i < classpathEntries.length; i++) { | |
323 | IClasspathEntry curr= classpathEntries[i]; | |
324 | newClassPath.add(CPListElement.createFromExisting(curr, project)); | |
325 | } | |
326 | return newClassPath; | |
327 | } | |
328 | ||
329 | /** | |
330 | * Try to find the corresponding and modified <code>CPListElement</code> for the root | |
331 | * in the list of elements and return it. | |
332 | * If no one can be found, the roots <code>ClasspathEntry</code> is converted to a | |
333 | * <code>CPListElement</code> and returned. | |
334 | * | |
335 | * @param elements a list of <code>CPListElements</code> | |
336 | * @param root the root to find the <code>ClasspathEntry</code> for represented by | |
337 | * a <code>CPListElement</code> | |
338 | * @return the <code>CPListElement</code> found in the list (matching by using the path) or | |
339 | * the roots own <code>IClasspathEntry</code> converted to a <code>CPListElement</code>. | |
340 | * @throws JavaModelException | |
341 | */ | |
342 | public static CPListElement getClasspathEntry(List<CPListElement> elements, IPackageFragmentRoot root) throws JavaModelException { | |
343 | IClasspathEntry entry= root.getRawClasspathEntry(); | |
344 | for (int i= 0; i < elements.size(); i++) { | |
345 | CPListElement element= elements.get(i); | |
346 | if (element.getPath().equals(root.getPath()) && element.getEntryKind() == entry.getEntryKind()) | |
347 | return elements.get(i); | |
348 | } | |
349 | CPListElement newElement= CPListElement.createFromExisting(entry, root.getJavaProject()); | |
350 | elements.add(newElement); | |
351 | return newElement; | |
352 | } | |
353 | ||
354 | /** | |
355 | * For a given <code>IResource</code>, try to | |
356 | * convert it into a <code>IPackageFragmentRoot</code> | |
357 | * if possible or return <code>null</code> if no | |
358 | * fragment root could be created. | |
359 | * | |
360 | * @param resource the resource to be converted | |
361 | * @return the <code>resource<code> as | |
362 | * <code>IPackageFragment</code>,or <code>null</code> | |
363 | * if failed to convert | |
364 | */ | |
365 | public static IPackageFragment getFragment(IResource resource) { | |
366 | IJavaElement elem= JavaCore.create(resource); | |
367 | if (elem instanceof IPackageFragment) | |
368 | return (IPackageFragment) elem; | |
369 | return null; | |
370 | } | |
371 | ||
372 | /** | |
373 | * Get the source folder of a given <code>IResource</code> element, | |
374 | * starting with the resource's parent. | |
375 | * | |
376 | * @param resource the resource to get the fragment root from | |
377 | * @param project the Java project | |
378 | * @param monitor progress monitor, can be <code>null</code> | |
379 | * @return resolved fragment root, or <code>null</code> the resource is not (in) a source folder | |
380 | * @throws JavaModelException | |
381 | */ | |
382 | public static IPackageFragmentRoot getFragmentRoot(IResource resource, IJavaProject project, IProgressMonitor monitor) throws JavaModelException { | |
383 | if (monitor == null) | |
384 | monitor= new NullProgressMonitor(); | |
385 | IJavaElement javaElem= null; | |
386 | if (resource.getFullPath().equals(project.getPath())) | |
387 | return project.getPackageFragmentRoot(resource); | |
388 | IContainer container= resource.getParent(); | |
389 | do { | |
390 | if (container instanceof IFolder) | |
391 | javaElem= JavaCore.create((IFolder) container); | |
392 | if (container.getFullPath().equals(project.getPath())) { | |
393 | javaElem= project; | |
394 | break; | |
395 | } | |
396 | container= container.getParent(); | |
397 | if (container == null) | |
398 | return null; | |
399 | } while (javaElem == null || !(javaElem instanceof IPackageFragmentRoot)); | |
400 | if (javaElem instanceof IJavaProject) { | |
401 | if (!isSourceFolder((IJavaProject)javaElem)) | |
402 | return null; | |
403 | javaElem= project.getPackageFragmentRoot(project.getResource()); | |
404 | } | |
405 | return (IPackageFragmentRoot) javaElem; | |
406 | } | |
407 | ||
408 | /** | |
409 | * Get the <code>IClasspathEntry</code> for the | |
410 | * given path by looking up all | |
411 | * build path entries on the project | |
412 | * | |
413 | * @param path the path to find a build path entry for | |
414 | * @param project the Java project | |
415 | * @param entryKind | |
416 | * @return the <code>IClasspathEntry</code> corresponding | |
417 | * to the <code>path</code> or <code>null</code> if there | |
418 | * is no such entry | |
419 | * @throws JavaModelException | |
420 | */ | |
421 | public static IClasspathEntry getClasspathEntryFor(IPath path, IJavaProject project, int entryKind) throws JavaModelException { | |
422 | IClasspathEntry[] entries= project.getRawClasspath(); | |
423 | for (int i= 0; i < entries.length; i++) { | |
424 | IClasspathEntry entry= entries[i]; | |
425 | if (entry.getPath().equals(path) && equalEntryKind(entry, entryKind)) | |
426 | return entry; | |
427 | } | |
428 | return null; | |
429 | } | |
430 | ||
431 | /** | |
432 | * Check whether the current selection is the project's | |
433 | * default output folder or not | |
434 | * | |
435 | * @param attrib the attribute to be checked | |
436 | * @return <code>true</code> if is the default output folder, | |
437 | * <code>false</code> otherwise. | |
438 | */ | |
439 | public static boolean isDefaultOutputFolder(CPListElementAttribute attrib) { | |
440 | return attrib.getValue() == null; | |
441 | } | |
442 | ||
443 | /** | |
444 | * Determines whether the current selection (of type | |
445 | * <code>ICompilationUnit</code> or <code>IPackageFragment</code>) | |
446 | * is on the inclusion filter of it's parent source folder. | |
447 | * | |
448 | * @param selection the current Java element | |
449 | * @param project the Java project | |
450 | * @param monitor progress monitor, can be <code>null</code> | |
451 | * @return <code>true</code> if the current selection is included, | |
452 | * <code>false</code> otherwise. | |
453 | * @throws JavaModelException | |
454 | */ | |
455 | public static boolean isIncluded(IJavaElement selection, IJavaProject project, IProgressMonitor monitor) throws JavaModelException { | |
456 | if (monitor == null) | |
457 | monitor= new NullProgressMonitor(); | |
458 | try { | |
459 | monitor.beginTask(NewWizardMessages.ClasspathModifier_Monitor_ContainsPath, 4); | |
460 | IPackageFragmentRoot root= (IPackageFragmentRoot) selection.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT); | |
461 | IClasspathEntry entry= root.getRawClasspathEntry(); | |
462 | if (entry == null) | |
463 | return false; | |
464 | return contains(selection.getPath().removeFirstSegments(root.getPath().segmentCount()), entry.getInclusionPatterns(), new SubProgressMonitor(monitor, 2)); | |
465 | } finally { | |
466 | monitor.done(); | |
467 | } | |
468 | } | |
469 | ||
470 | /** | |
471 | * Find out whether the <code>IResource</code> excluded or not. | |
472 | * | |
473 | * @param resource the resource to be checked | |
474 | * @param project the Java project | |
475 | * @return <code>true</code> if the resource is excluded, <code> | |
476 | * false</code> otherwise | |
477 | * @throws JavaModelException | |
478 | */ | |
479 | public static boolean isExcluded(IResource resource, IJavaProject project) throws JavaModelException { | |
480 | IPackageFragmentRoot root= getFragmentRoot(resource, project, null); | |
481 | if (root == null) | |
482 | return false; | |
483 | String fragmentName= getName(resource.getFullPath(), root.getPath()); | |
484 | fragmentName= completeName(fragmentName); | |
485 | IClasspathEntry entry= root.getRawClasspathEntry(); | |
486 | return entry != null && contains(new Path(fragmentName), entry.getExclusionPatterns(), null); | |
487 | } | |
488 | ||
489 | /** | |
490 | * Find out whether one of the <code>IResource</code>'s parents | |
491 | * is excluded. | |
492 | * | |
493 | * @param resource check the resources parents whether they are | |
494 | * excluded or not | |
495 | * @param project the Java project | |
496 | * @return <code>true</code> if there is an excluded parent, | |
497 | * <code>false</code> otherwise | |
498 | * @throws JavaModelException | |
499 | */ | |
500 | public static boolean parentExcluded(IResource resource, IJavaProject project) throws JavaModelException { | |
501 | if (resource.getFullPath().equals(project.getPath())) | |
502 | return false; | |
503 | IPackageFragmentRoot root= getFragmentRoot(resource, project, null); | |
504 | if (root == null) { | |
505 | return true; | |
506 | } | |
507 | IPath path= resource.getFullPath().removeFirstSegments(root.getPath().segmentCount()); | |
508 | IClasspathEntry entry= root.getRawClasspathEntry(); | |
509 | if (entry == null) | |
510 | return true; // there is no build path entry, this is equal to the fact that the parent is excluded | |
511 | while (path.segmentCount() > 0) { | |
512 | if (contains(path, entry.getExclusionPatterns(), null)) | |
513 | return true; | |
514 | path= path.removeLastSegments(1); | |
515 | } | |
516 | return false; | |
517 | } | |
518 | ||
519 | /** | |
520 | * Check whether the output location of the <code>IPackageFragmentRoot</code> | |
521 | * is <code>null</code>. If this holds, then the root | |
522 | * does use the default output folder. | |
523 | * | |
524 | * @param root the root to examine the output location for | |
525 | * @return <code>true</code> if the root uses the default output folder, <code>false | |
526 | * </code> otherwise. | |
527 | * @throws JavaModelException | |
528 | */ | |
529 | public static boolean hasDefaultOutputFolder(IPackageFragmentRoot root) throws JavaModelException { | |
530 | return root.getRawClasspathEntry().getOutputLocation() == null; | |
531 | } | |
532 | ||
533 | /** | |
534 | * Check whether at least one source folder of the given | |
535 | * Java project has an output folder set. | |
536 | * | |
537 | * @param project the Java project | |
538 | * @param monitor progress monitor, can be <code>null</code> | |
539 | * @return <code>true</code> if at least one outputfolder | |
540 | * is set, <code>false</code> otherwise | |
541 | * @throws JavaModelException | |
542 | */ | |
543 | public static boolean hasOutputFolders(IJavaProject project, IProgressMonitor monitor) throws JavaModelException { | |
544 | if (monitor == null) | |
545 | monitor= new NullProgressMonitor(); | |
546 | try { | |
547 | IPackageFragmentRoot[] roots= project.getPackageFragmentRoots(); | |
548 | monitor.beginTask(NewWizardMessages.ClasspathModifier_Monitor_CheckOutputFolders, roots.length); | |
549 | for (int i= 0; i < roots.length; i++) { | |
550 | if (roots[i].getRawClasspathEntry().getOutputLocation() != null) | |
551 | return true; | |
552 | monitor.worked(1); | |
553 | } | |
554 | } finally { | |
555 | monitor.done(); | |
556 | } | |
557 | return false; | |
558 | } | |
559 | ||
560 | public static String escapeSpecialChars(String value) { | |
561 | StringBuffer buf = new StringBuffer(); | |
562 | for (int i = 0; i < value.length(); i++) { | |
563 | char c = value.charAt(i); | |
564 | ||
565 | switch (c) { | |
566 | case '&': | |
567 | buf.append("&"); //$NON-NLS-1$ | |
568 | break; | |
569 | case '<': | |
570 | buf.append("<"); //$NON-NLS-1$ | |
571 | break; | |
572 | case '>': | |
573 | buf.append(">"); //$NON-NLS-1$ | |
574 | break; | |
575 | case '\'': | |
576 | buf.append("'"); //$NON-NLS-1$ | |
577 | break; | |
578 | case '\"': | |
579 | buf.append("""); //$NON-NLS-1$ | |
580 | break; | |
581 | case 160: | |
582 | buf.append(" "); //$NON-NLS-1$ | |
583 | break; | |
584 | default: | |
585 | buf.append(c); | |
586 | break; | |
587 | } | |
588 | } | |
589 | return buf.toString(); | |
590 | } | |
591 | ||
592 | ||
593 | /** | |
594 | * Check whether the <code>IJavaProject</code> | |
595 | * is a source folder | |
596 | * | |
597 | * @param project the project to test | |
598 | * @return <code>true</code> if <code>project</code> is a source folder | |
599 | * <code>false</code> otherwise. | |
600 | * @throws JavaModelException | |
601 | */ | |
602 | public static boolean isSourceFolder(IJavaProject project) throws JavaModelException { | |
603 | return ClasspathModifier.getClasspathEntryFor(project.getPath(), project, IClasspathEntry.CPE_SOURCE) != null; | |
604 | } | |
605 | ||
606 | /** | |
607 | * Check whether the <code>IPackageFragment</code> | |
608 | * corresponds to the project's default fragment. | |
609 | * | |
610 | * @param fragment the package fragment to be checked | |
611 | * @return <code>true</code> if is the default package fragment, | |
612 | * <code>false</code> otherwise. | |
613 | */ | |
614 | public static boolean isDefaultFragment(IPackageFragment fragment) { | |
615 | return fragment.isDefaultPackage(); | |
616 | } | |
617 | ||
618 | /** | |
619 | * Determines whether the inclusion filter of the element's source folder is empty | |
620 | * or not | |
621 | * @param resource | |
622 | * @param project | |
623 | * @param monitor | |
624 | * @return <code>true</code> if the inclusion filter is empty, | |
625 | * <code>false</code> otherwise. | |
626 | * @throws JavaModelException | |
627 | */ | |
628 | public static boolean includeFiltersEmpty(IResource resource, IJavaProject project, IProgressMonitor monitor) throws JavaModelException { | |
629 | if (monitor == null) | |
630 | monitor= new NullProgressMonitor(); | |
631 | try { | |
632 | monitor.beginTask(NewWizardMessages.ClasspathModifier_Monitor_ExamineInputFilters, 4); | |
633 | IPackageFragmentRoot root= getFragmentRoot(resource, project, new SubProgressMonitor(monitor, 4)); | |
634 | if (root != null) { | |
635 | IClasspathEntry entry= root.getRawClasspathEntry(); | |
636 | return entry.getInclusionPatterns().length == 0; | |
637 | } | |
638 | return true; | |
639 | } finally { | |
640 | monitor.done(); | |
641 | } | |
642 | } | |
643 | ||
644 | /** | |
645 | * Check whether the input parameter of type <code> | |
646 | * IPackageFragmentRoot</code> has either it's inclusion or | |
647 | * exclusion filter or both set (that means they are | |
648 | * not empty). | |
649 | * | |
650 | * @param root the fragment root to be inspected | |
651 | * @return <code>true</code> inclusion or exclusion filter set, | |
652 | * <code>false</code> otherwise. | |
653 | * @throws JavaModelException | |
654 | */ | |
655 | public static boolean filtersSet(IPackageFragmentRoot root) throws JavaModelException { | |
656 | if (root == null) | |
657 | return false; | |
658 | IClasspathEntry entry= root.getRawClasspathEntry(); | |
659 | IPath[] inclusions= entry.getInclusionPatterns(); | |
660 | IPath[] exclusions= entry.getExclusionPatterns(); | |
661 | if (inclusions != null && inclusions.length > 0) | |
662 | return true; | |
663 | if (exclusions != null && exclusions.length > 0) | |
664 | return true; | |
665 | return false; | |
666 | } | |
667 | ||
668 | /** | |
669 | * Add a resource to the build path. | |
670 | * | |
671 | * @param resource the resource to be added to the build path | |
672 | * @param existingEntries | |
673 | * @param newEntries | |
674 | * @param project the Java project | |
675 | * @param monitor progress monitor, can be <code>null</code> | |
676 | * @return returns the new element of type <code>IPackageFragmentRoot</code> that has been added to the build path | |
677 | * @throws CoreException | |
678 | * @throws OperationCanceledException | |
679 | */ | |
680 | public static CPListElement addToClasspath(IResource resource, List<CPListElement> existingEntries, List<CPListElement> newEntries, IJavaProject project, IProgressMonitor monitor) throws OperationCanceledException, CoreException { | |
681 | if (monitor == null) | |
682 | monitor= new NullProgressMonitor(); | |
683 | try { | |
684 | monitor.beginTask(NewWizardMessages.ClasspathModifier_Monitor_AddToBuildpath, 2); | |
685 | exclude(resource.getFullPath(), existingEntries, newEntries, project, new SubProgressMonitor(monitor, 1)); | |
686 | CPListElement entry= new CPListElement(project, IClasspathEntry.CPE_SOURCE, resource.getFullPath(), resource); | |
687 | return entry; | |
688 | } finally { | |
689 | monitor.done(); | |
690 | } | |
691 | } | |
692 | ||
693 | /** | |
694 | * Check whether the provided file is an archive (.jar or .zip). | |
695 | * | |
696 | * @param file the file to be checked | |
697 | * @param project the Java project | |
698 | * @return <code>true</code> if the file is an archive, <code>false</code> | |
699 | * otherwise | |
700 | * @throws JavaModelException | |
701 | */ | |
702 | public static boolean isArchive(IFile file, IJavaProject project) throws JavaModelException { | |
703 | if (!ArchiveFileFilter.isArchivePath(file.getFullPath(), true)) | |
704 | return false; | |
705 | if (project != null && project.exists() && (project.findPackageFragmentRoot(file.getFullPath()) == null)) | |
706 | return true; | |
707 | return false; | |
708 | } | |
709 | ||
710 | /** | |
711 | * Add a Java element to the build path. | |
712 | * | |
713 | * @param javaElement element to be added to the build path | |
714 | * @param existingEntries | |
715 | * @param newEntries | |
716 | * @param project the Java project | |
717 | * @param monitor progress monitor, can be <code>null</code> | |
718 | * @return returns the new element of type <code>IPackageFragmentRoot</code> that has been added to the build path | |
719 | * @throws CoreException | |
720 | * @throws OperationCanceledException | |
721 | */ | |
722 | public static CPListElement addToClasspath(IJavaElement javaElement, List<CPListElement> existingEntries, List<CPListElement> newEntries, IJavaProject project, IProgressMonitor monitor) throws OperationCanceledException, CoreException { | |
723 | if (monitor == null) | |
724 | monitor= new NullProgressMonitor(); | |
725 | try { | |
726 | monitor.beginTask(NewWizardMessages.ClasspathModifier_Monitor_AddToBuildpath, 10); | |
727 | CPListElement entry= new CPListElement(project, IClasspathEntry.CPE_SOURCE, javaElement.getPath(), javaElement.getResource()); | |
728 | return entry; | |
729 | } finally { | |
730 | monitor.done(); | |
731 | } | |
732 | } | |
733 | ||
734 | /** | |
735 | * Remove the Java project from the build path | |
736 | * | |
737 | * @param project the project to be removed | |
738 | * @param existingEntries a list of existing <code>CPListElement</code>. This list | |
739 | * will be traversed and the entry for the project will be removed. | |
740 | * @param monitor progress monitor, can be <code>null</code> | |
741 | * @return returns the Java project | |
742 | */ | |
743 | public static IJavaProject removeFromClasspath(IJavaProject project, List<CPListElement> existingEntries, IProgressMonitor monitor) { | |
744 | CPListElement elem= getListElement(project.getPath(), existingEntries); | |
745 | if (elem != null) { | |
746 | existingEntries.remove(elem); | |
747 | } | |
748 | return project; | |
749 | } | |
750 | ||
751 | /** | |
752 | * Remove <code>path</code> from inclusion/exlusion filters in all <code>existingEntries</code> | |
753 | * | |
754 | * @param path the path to remove | |
755 | * @param project the Java project | |
756 | * @param existingEntries a list of <code>CPListElement</code> representing the build path | |
757 | * entries of the project. | |
758 | * @return returns a <code>List</code> of <code>CPListElement</code> of modified elements, not null. | |
759 | */ | |
760 | public static List<CPListElement> removeFilters(IPath path, IJavaProject project, List<CPListElement> existingEntries) { | |
761 | if (path == null) | |
762 | return Collections.emptyList(); | |
763 | ||
764 | IPath projPath= project.getPath(); | |
765 | if (projPath.isPrefixOf(path)) { | |
766 | path= path.removeFirstSegments(projPath.segmentCount()).addTrailingSeparator(); | |
767 | } | |
768 | ||
769 | List<CPListElement> result= new ArrayList<CPListElement>(); | |
770 | for (Iterator<CPListElement> iter= existingEntries.iterator(); iter.hasNext();) { | |
771 | CPListElement element= iter.next(); | |
772 | boolean hasChange= false; | |
773 | IPath[] exlusions= (IPath[])element.getAttribute(CPListElement.EXCLUSION); | |
774 | if (exlusions != null) { | |
775 | List<IPath> exlusionList= new ArrayList<IPath>(exlusions.length); | |
776 | for (int i= 0; i < exlusions.length; i++) { | |
777 | if (!exlusions[i].equals(path)) { | |
778 | exlusionList.add(exlusions[i]); | |
779 | } else { | |
780 | hasChange= true; | |
781 | } | |
782 | } | |
783 | element.setAttribute(CPListElement.EXCLUSION, exlusionList.toArray(new IPath[exlusionList.size()])); | |
784 | } | |
785 | ||
786 | IPath[] inclusion= (IPath[])element.getAttribute(CPListElement.INCLUSION); | |
787 | if (inclusion != null) { | |
788 | List<IPath> inclusionList= new ArrayList<IPath>(inclusion.length); | |
789 | for (int i= 0; i < inclusion.length; i++) { | |
790 | if (!inclusion[i].equals(path)) { | |
791 | inclusionList.add(inclusion[i]); | |
792 | } else { | |
793 | hasChange= true; | |
794 | } | |
795 | } | |
796 | element.setAttribute(CPListElement.INCLUSION, inclusionList.toArray(new IPath[inclusionList.size()])); | |
797 | } | |
798 | if (hasChange) { | |
799 | result.add(element); | |
800 | } | |
801 | } | |
802 | return result; | |
803 | } | |
804 | ||
805 | /** | |
806 | * Exclude an element with a given name and absolute path | |
807 | * from the build path. | |
808 | * | |
809 | * @param name the name of the element to be excluded | |
810 | * @param fullPath the absolute path of the element | |
811 | * @param entry the build path entry to be modified | |
812 | * @param project the Java project | |
813 | * @param monitor progress monitor, can be <code>null</code> | |
814 | * @return a <code>IResource</code> corresponding to the excluded element | |
815 | * @throws JavaModelException | |
816 | */ | |
817 | private static IResource exclude(String name, IPath fullPath, CPListElement entry, IJavaProject project, IProgressMonitor monitor) throws JavaModelException { | |
818 | if (monitor == null) | |
819 | monitor= new NullProgressMonitor(); | |
820 | IResource result; | |
821 | try { | |
822 | monitor.beginTask(NewWizardMessages.ClasspathModifier_Monitor_Excluding, 6); | |
823 | IPath[] excludedPath= (IPath[]) entry.getAttribute(CPListElement.EXCLUSION); | |
824 | IPath[] newExcludedPath= new IPath[excludedPath.length + 1]; | |
825 | name= completeName(name); | |
826 | IPath path= new Path(name); | |
827 | if (!contains(path, excludedPath, new SubProgressMonitor(monitor, 2))) { | |
828 | System.arraycopy(excludedPath, 0, newExcludedPath, 0, excludedPath.length); | |
829 | newExcludedPath[excludedPath.length]= path; | |
830 | entry.setAttribute(CPListElement.EXCLUSION, newExcludedPath); | |
831 | entry.setAttribute(CPListElement.INCLUSION, remove(path, (IPath[]) entry.getAttribute(CPListElement.INCLUSION), new SubProgressMonitor(monitor, 4))); | |
832 | } | |
833 | result= fullPath == null ? null : getResource(fullPath, project); | |
834 | } finally { | |
835 | monitor.done(); | |
836 | } | |
837 | return result; | |
838 | } | |
839 | ||
840 | /** | |
841 | * Exclude an object at a given path. | |
842 | * This means that the exclusion filter for the | |
843 | * corresponding <code>IPackageFragmentRoot</code> needs to be modified. | |
844 | * | |
845 | * First, the fragment root needs to be found. To do so, the new entries | |
846 | * are and the existing entries are traversed for a match and the entry | |
847 | * with the path is removed from one of those lists. | |
848 | * | |
849 | * Note: the <code>IJavaElement</code>'s fragment (if there is one) | |
850 | * is not allowed to be excluded! However, inclusion (or simply no | |
851 | * filter) on the parent fragment is allowed. | |
852 | * | |
853 | * @param path absolute path of an object to be excluded | |
854 | * @param existingEntries a list of existing build path entries | |
855 | * @param newEntries a list of new build path entries | |
856 | * @param project the Java project | |
857 | * @param monitor progress monitor, can be <code>null</code> | |
858 | * @throws JavaModelException | |
859 | */ | |
860 | public static void exclude(IPath path, List<CPListElement> existingEntries, List<CPListElement> newEntries, IJavaProject project, IProgressMonitor monitor) throws JavaModelException { | |
861 | if (monitor == null) | |
862 | monitor= new NullProgressMonitor(); | |
863 | try { | |
864 | monitor.beginTask(NewWizardMessages.ClasspathModifier_Monitor_Excluding, 1); | |
865 | CPListElement elem= null; | |
866 | CPListElement existingElem= null; | |
867 | int i= 0; | |
868 | do { | |
869 | i++; | |
870 | IPath rootPath= path.removeLastSegments(i); | |
871 | ||
872 | if (rootPath.segmentCount() == 0) | |
873 | return; | |
874 | ||
875 | elem= getListElement(rootPath, newEntries); | |
876 | existingElem= getListElement(rootPath, existingEntries); | |
877 | } while (existingElem == null && elem == null); | |
878 | if (elem == null) { | |
879 | elem= existingElem; | |
880 | } | |
881 | exclude(path.removeFirstSegments(path.segmentCount() - i).toString(), null, elem, project, new SubProgressMonitor(monitor, 1)); | |
882 | } finally { | |
883 | monitor.done(); | |
884 | } | |
885 | } | |
886 | ||
887 | /** | |
888 | * Exclude a <code>IJavaElement</code>. This means that the exclusion filter for the | |
889 | * corresponding <code>IPackageFragmentRoot</code>s need to be modified. | |
890 | * | |
891 | * Note: the <code>IJavaElement</code>'s fragment (if there is one) | |
892 | * is not allowed to be excluded! However, inclusion (or simply no | |
893 | * filter) on the parent fragment is allowed. | |
894 | * | |
895 | * @param javaElement the Java element to be excluded | |
896 | * @param entry the <code>CPListElement</code> representing the | |
897 | * <code>IClasspathEntry</code> of the Java element's root. | |
898 | * @param project the Java project | |
899 | * @param monitor progress monitor, can be <code>null</code> | |
900 | * | |
901 | * @return the resulting <code>IResource<code> | |
902 | * @throws JavaModelException | |
903 | */ | |
904 | public static IResource exclude(IJavaElement javaElement, CPListElement entry, IJavaProject project, IProgressMonitor monitor) throws JavaModelException { | |
905 | if (monitor == null) | |
906 | monitor= new NullProgressMonitor(); | |
907 | try { | |
908 | String name= getName(javaElement.getPath(), entry.getPath()); | |
909 | return exclude(name, javaElement.getPath(), entry, project, new SubProgressMonitor(monitor, 1)); | |
910 | } finally { | |
911 | monitor.done(); | |
912 | } | |
913 | } | |
914 | ||
915 | /** | |
916 | * Inverse operation to <code>exclude</code>. | |
917 | * The resource removed from it's fragment roots exlusion filter. | |
918 | * | |
919 | * Note: the <code>IJavaElement</code>'s fragment (if there is one) | |
920 | * is not allowed to be excluded! However, inclusion (or simply no | |
921 | * filter) on the parent fragment is allowed. | |
922 | * | |
923 | * @param resource the resource to be unexcluded | |
924 | * @param entry the <code>CPListElement</code> representing the | |
925 | * <code>IClasspathEntry</code> of the resource's root. | |
926 | * @param project the Java project | |
927 | * @param monitor progress monitor, can be <code>null</code> | |
928 | * @throws JavaModelException | |
929 | * | |
930 | */ | |
931 | public static void unExclude(IResource resource, CPListElement entry, IJavaProject project, IProgressMonitor monitor) throws JavaModelException { | |
932 | if (monitor == null) | |
933 | monitor= new NullProgressMonitor(); | |
934 | try { | |
935 | monitor.beginTask(NewWizardMessages.ClasspathModifier_Monitor_RemoveExclusion, 10); | |
936 | String name= getName(resource.getFullPath(), entry.getPath()); | |
937 | IPath[] excludedPath= (IPath[]) entry.getAttribute(CPListElement.EXCLUSION); | |
938 | IPath[] newExcludedPath= remove(new Path(completeName(name)), excludedPath, new SubProgressMonitor(monitor, 3)); | |
939 | entry.setAttribute(CPListElement.EXCLUSION, newExcludedPath); | |
940 | } finally { | |
941 | monitor.done(); | |
942 | } | |
943 | } | |
944 | ||
945 | /** | |
946 | * Resets inclusion and exclusion filters for the given | |
947 | * <code>IJavaElement</code> | |
948 | * | |
949 | * @param element element to reset it's filters | |
950 | * @param entry the <code>CPListElement</code> to reset its filters for | |
951 | * @param project the Java project | |
952 | * @param monitor progress monitor, can be <code>null</code> | |
953 | * @throws JavaModelException | |
954 | */ | |
955 | public static void resetFilters(IJavaElement element, CPListElement entry, IJavaProject project, IProgressMonitor monitor) throws JavaModelException { | |
956 | if (monitor == null) | |
957 | monitor= new NullProgressMonitor(); | |
958 | try { | |
959 | monitor.beginTask(NewWizardMessages.ClasspathModifier_Monitor_ResetFilters, 3); | |
960 | ||
961 | List<Path> exclusionList= getFoldersOnCP(element.getPath(), project, new SubProgressMonitor(monitor, 2)); | |
962 | IPath outputLocation= (IPath) entry.getAttribute(CPListElement.OUTPUT); | |
963 | if (outputLocation != null) { | |
964 | IPath[] exclusionPatterns= (IPath[]) entry.getAttribute(CPListElement.EXCLUSION); | |
965 | if (contains(new Path(completeName(outputLocation.lastSegment())), exclusionPatterns, null)) { | |
966 | exclusionList.add(new Path(completeName(outputLocation.lastSegment()))); | |
967 | } | |
968 | } | |
969 | IPath[] exclusions= exclusionList.toArray(new IPath[exclusionList.size()]); | |
970 | ||
971 | entry.setAttribute(CPListElement.INCLUSION, new IPath[0]); | |
972 | entry.setAttribute(CPListElement.EXCLUSION, exclusions); | |
973 | } finally { | |
974 | monitor.done(); | |
975 | } | |
976 | } | |
977 | ||
978 | /** | |
979 | * Reset the output folder for the given entry to the default output folder | |
980 | * | |
981 | * @param entry the <code>CPListElement</code> to be edited | |
982 | * @param project the Java project | |
983 | * @return an attribute representing the modified output folder | |
984 | * @throws JavaModelException | |
985 | */ | |
986 | public static CPListElementAttribute resetOutputFolder(CPListElement entry, IJavaProject project) throws JavaModelException { | |
987 | entry.setAttribute(CPListElement.OUTPUT, null); | |
988 | CPListElementAttribute outputFolder= new CPListElementAttribute(entry, CPListElement.OUTPUT, entry.getAttribute(CPListElement.OUTPUT), true); | |
989 | return outputFolder; | |
990 | } | |
991 | ||
992 | /** | |
993 | * Try to find the corresponding and modified <code>CPListElement</code> for the provided | |
994 | * <code>CPListElement</code> in the list of elements and return it. | |
995 | * If no one can be found, the provided <code>CPListElement</code> is returned. | |
996 | * | |
997 | * @param elements a list of <code>CPListElements</code> | |
998 | * @param cpElement the <code>CPListElement</code> to find the corresponding entry in | |
999 | * the list | |
1000 | * @return the <code>CPListElement</code> found in the list (matching by using the path) or | |
1001 | * the second <code>CPListElement</code> parameter itself if there is no match. | |
1002 | */ | |
1003 | public static CPListElement getClasspathEntry(List<CPListElement> elements, CPListElement cpElement) { | |
1004 | for (int i= 0; i < elements.size(); i++) { | |
1005 | if (elements.get(i).getPath().equals(cpElement.getPath())) | |
1006 | return elements.get(i); | |
1007 | } | |
1008 | elements.add(cpElement); | |
1009 | return cpElement; | |
1010 | } | |
1011 | ||
1012 | /** | |
1013 | * For a given path, find the corresponding element in the list. | |
1014 | * | |
1015 | * @param path the path to found an entry for | |
1016 | * @param elements a list of <code>CPListElement</code>s | |
1017 | * @return the matched <code>CPListElement</code> or <code>null</code> if | |
1018 | * no match could be found | |
1019 | */ | |
1020 | public static CPListElement getListElement(IPath path, List<CPListElement> elements) { | |
1021 | for (int i= 0; i < elements.size(); i++) { | |
1022 | CPListElement element= elements.get(i); | |
1023 | if (element.getEntryKind() == IClasspathEntry.CPE_SOURCE && element.getPath().equals(path)) { | |
1024 | return element; | |
1025 | } | |
1026 | } | |
1027 | return null; | |
1028 | } | |
1029 | ||
1030 | public static void commitClassPath(List<CPListElement> newEntries, IJavaProject project, IProgressMonitor monitor) throws JavaModelException { | |
1031 | if (monitor == null) | |
1032 | monitor= new NullProgressMonitor(); | |
1033 | ||
1034 | monitor.beginTask("", 2); //$NON-NLS-1$ | |
1035 | ||
1036 | try { | |
1037 | IClasspathEntry[] entries= convert(newEntries); | |
1038 | IPath outputLocation= project.getOutputLocation(); | |
1039 | ||
1040 | IJavaModelStatus status= JavaConventions.validateClasspath(project, entries, outputLocation); | |
1041 | if (!status.isOK()) | |
1042 | throw new JavaModelException(status); | |
1043 | ||
1044 | BuildPathSupport.setEEComplianceOptions(project, newEntries); | |
1045 | project.setRawClasspath(entries, outputLocation, new SubProgressMonitor(monitor, 2)); | |
1046 | } finally { | |
1047 | monitor.done(); | |
1048 | } | |
1049 | } | |
1050 | ||
1051 | public static void commitClassPath(CPJavaProject cpProject, IProgressMonitor monitor) throws JavaModelException { | |
1052 | if (monitor == null) | |
1053 | monitor= new NullProgressMonitor(); | |
1054 | ||
1055 | monitor.beginTask("", 2); //$NON-NLS-1$ | |
1056 | ||
1057 | try { | |
1058 | List<CPListElement> cpListElements= cpProject.getCPListElements(); | |
1059 | IClasspathEntry[] entries= convert(cpListElements); | |
1060 | IPath outputLocation= cpProject.getDefaultOutputLocation(); | |
1061 | ||
1062 | IJavaProject javaProject= cpProject.getJavaProject(); | |
1063 | IJavaModelStatus status= JavaConventions.validateClasspath(javaProject, entries, outputLocation); | |
1064 | if (!status.isOK()) | |
1065 | throw new JavaModelException(status); | |
1066 | ||
1067 | BuildPathSupport.setEEComplianceOptions(javaProject, cpListElements); | |
1068 | javaProject.setRawClasspath(entries, outputLocation, new SubProgressMonitor(monitor, 2)); | |
1069 | } finally { | |
1070 | monitor.done(); | |
1071 | } | |
1072 | } | |
1073 | ||
1074 | /** | |
1075 | * For a given list of entries, find out what representation they | |
1076 | * will have in the project and return a list with corresponding | |
1077 | * elements. | |
1078 | * | |
1079 | * @param entries a list of entries to find an appropriate representation | |
1080 | * for. The list can contain elements of two types: | |
1081 | * <li><code>IResource</code></li> | |
1082 | * <li><code>IJavaElement</code></li> | |
1083 | * @param project the Java project | |
1084 | * @return a list of elements corresponding to the passed entries. | |
1085 | */ | |
1086 | public static List<?> getCorrespondingElements(List<?> entries, IJavaProject project) { | |
1087 | List<IAdaptable> result= new ArrayList<IAdaptable>(); | |
1088 | for (int i= 0; i < entries.size(); i++) { | |
1089 | Object element= entries.get(i); | |
1090 | IPath path; | |
1091 | if (element instanceof IResource) | |
1092 | path= ((IResource) element).getFullPath(); | |
1093 | else | |
1094 | path= ((IJavaElement) element).getPath(); | |
1095 | IResource resource= getResource(path, project); | |
1096 | if (resource != null) { | |
1097 | IJavaElement elem= JavaCore.create(resource); | |
1098 | if (elem != null && project.isOnClasspath(elem)) | |
1099 | result.add(elem); | |
1100 | else | |
1101 | result.add(resource); | |
1102 | } | |
1103 | ||
1104 | } | |
1105 | return result; | |
1106 | } | |
1107 | ||
1108 | /** | |
1109 | * Returns for the given absolute path the corresponding | |
1110 | * resource, this is either element of type <code>IFile</code> | |
1111 | * or <code>IFolder</code>. | |
1112 | * | |
1113 | * @param path an absolute path to a resource | |
1114 | * @param project the Java project | |
1115 | * @return the resource matching to the path. Can be | |
1116 | * either an <code>IFile</code> or an <code>IFolder</code>. | |
1117 | */ | |
1118 | private static IResource getResource(IPath path, IJavaProject project) { | |
1119 | return project.getProject().getWorkspace().getRoot().findMember(path); | |
1120 | } | |
1121 | ||
1122 | /** | |
1123 | * Find out whether the provided path equals to one | |
1124 | * in the array. | |
1125 | * | |
1126 | * @param path path to find an equivalent for | |
1127 | * @param paths set of paths to compare with | |
1128 | * @param monitor progress monitor, can be <code>null</code> | |
1129 | * @return <code>true</code> if there is an occurrence, <code> | |
1130 | * false</code> otherwise | |
1131 | */ | |
1132 | private static boolean contains(IPath path, IPath[] paths, IProgressMonitor monitor) { | |
1133 | if (monitor == null) | |
1134 | monitor= new NullProgressMonitor(); | |
1135 | if (path == null) | |
1136 | return false; | |
1137 | try { | |
1138 | monitor.beginTask(NewWizardMessages.ClasspathModifier_Monitor_ComparePaths, paths.length); | |
1139 | if (path.getFileExtension() == null) | |
1140 | path= new Path(completeName(path.toString())); | |
1141 | for (int i= 0; i < paths.length; i++) { | |
1142 | if (paths[i].equals(path)) | |
1143 | return true; | |
1144 | monitor.worked(1); | |
1145 | } | |
1146 | } finally { | |
1147 | monitor.done(); | |
1148 | } | |
1149 | return false; | |
1150 | } | |
1151 | ||
1152 | /** | |
1153 | * Add a '/' at the end of the name if | |
1154 | * it does not end with '.java', or other Java-like extension. | |
1155 | * | |
1156 | * @param name append '/' at the end if | |
1157 | * necessary | |
1158 | * @return modified string | |
1159 | */ | |
1160 | private static String completeName(String name) { | |
1161 | if (!JavaCore.isJavaLikeFileName(name)) { | |
1162 | name= name + "/"; //$NON-NLS-1$ | |
1163 | name= name.replace('.', '/'); | |
1164 | return name; | |
1165 | } | |
1166 | return name; | |
1167 | } | |
1168 | ||
1169 | /** | |
1170 | * Removes <code>path</code> out of the set of given <code> | |
1171 | * paths</code>. If the path is not contained, then the | |
1172 | * initially provided array of paths is returned. | |
1173 | * | |
1174 | * Only the first occurrence will be removed. | |
1175 | * | |
1176 | * @param path path to be removed | |
1177 | * @param paths array of path to apply the removal on | |
1178 | * @param monitor progress monitor, can be <code>null</code> | |
1179 | * @return array which does not contain <code>path</code> | |
1180 | */ | |
1181 | private static IPath[] remove(IPath path, IPath[] paths, IProgressMonitor monitor) { | |
1182 | if (monitor == null) | |
1183 | monitor= new NullProgressMonitor(); | |
1184 | try { | |
1185 | monitor.beginTask(NewWizardMessages.ClasspathModifier_Monitor_RemovePath, paths.length + 5); | |
1186 | if (!contains(path, paths, new SubProgressMonitor(monitor, 5))) | |
1187 | return paths; | |
1188 | ||
1189 | ArrayList<IPath> newPaths= new ArrayList<IPath>(); | |
1190 | for (int i= 0; i < paths.length; i++) { | |
1191 | monitor.worked(1); | |
1192 | if (!paths[i].equals(path)) | |
1193 | newPaths.add(paths[i]); | |
1194 | } | |
1195 | ||
1196 | return newPaths.toArray(new IPath[newPaths.size()]); | |
1197 | } finally { | |
1198 | monitor.done(); | |
1199 | } | |
1200 | ||
1201 | } | |
1202 | ||
1203 | /** | |
1204 | * Find all folders that are on the build path and | |
1205 | * <code>path</code> is a prefix of those folders | |
1206 | * path entry, that is, all folders which are a | |
1207 | * subfolder of <code>path</code>. | |
1208 | * | |
1209 | * For example, if <code>path</code>=/MyProject/src | |
1210 | * then all folders having a path like /MyProject/src/*, | |
1211 | * where * can be any valid string are returned if | |
1212 | * they are also on the project's build path. | |
1213 | * | |
1214 | * @param path absolute path | |
1215 | * @param project the Java project | |
1216 | * @param monitor progress monitor, can be <code>null</code> | |
1217 | * @return an array of paths which belong to subfolders | |
1218 | * of <code>path</code> and which are on the build path | |
1219 | * @throws JavaModelException | |
1220 | */ | |
1221 | private static List<Path> getFoldersOnCP(IPath path, IJavaProject project, IProgressMonitor monitor) throws JavaModelException { | |
1222 | if (monitor == null) | |
1223 | monitor= new NullProgressMonitor(); | |
1224 | List<Path> srcFolders= new ArrayList<Path>(); | |
1225 | IClasspathEntry[] cpEntries= project.getRawClasspath(); | |
1226 | for (int i= 0; i < cpEntries.length; i++) { | |
1227 | IPath cpPath= cpEntries[i].getPath(); | |
1228 | if (path.isPrefixOf(cpPath) && path.segmentCount() + 1 == cpPath.segmentCount()) | |
1229 | srcFolders.add(new Path(completeName(cpPath.lastSegment()))); | |
1230 | } | |
1231 | return srcFolders; | |
1232 | } | |
1233 | ||
1234 | /** | |
1235 | * Returns a string corresponding to the <code>path</code> | |
1236 | * with the <code>rootPath<code>'s number of segments | |
1237 | * removed | |
1238 | * | |
1239 | * @param path path to remove segments | |
1240 | * @param rootPath provides the number of segments to | |
1241 | * be removed | |
1242 | * @return a string corresponding to the mentioned | |
1243 | * action | |
1244 | */ | |
1245 | private static String getName(IPath path, IPath rootPath) { | |
1246 | return path.removeFirstSegments(rootPath.segmentCount()).toString(); | |
1247 | } | |
1248 | ||
1249 | /** | |
1250 | * Sets and validates the new entries. Note that the elements of | |
1251 | * the list containing the new entries will be added to the list of | |
1252 | * existing entries (therefore, there is no return list for this method). | |
1253 | * | |
1254 | * @param existingEntries a list of existing classpath entries | |
1255 | * @param newEntries a list of entries to be added to the existing ones | |
1256 | * @param project the Java project | |
1257 | * @param monitor a progress monitor, can be <code>null</code> | |
1258 | * @throws CoreException in case that validation on one of the new entries fails | |
1259 | */ | |
1260 | public static void setNewEntry(List<CPListElement> existingEntries, List<CPListElement> newEntries, IJavaProject project, IProgressMonitor monitor) throws CoreException { | |
1261 | try { | |
1262 | monitor.beginTask(NewWizardMessages.ClasspathModifier_Monitor_SetNewEntry, existingEntries.size()); | |
1263 | for (int i= 0; i < newEntries.size(); i++) { | |
1264 | CPListElement entry= newEntries.get(i); | |
1265 | validateAndAddEntry(entry, existingEntries, project); | |
1266 | monitor.worked(1); | |
1267 | } | |
1268 | } finally { | |
1269 | monitor.done(); | |
1270 | } | |
1271 | } | |
1272 | ||
1273 | /** | |
1274 | * Convert a list of <code>CPListElement</code>s to | |
1275 | * an array of <code>IClasspathEntry</code>. | |
1276 | * | |
1277 | * @param list the list to be converted | |
1278 | * @return an array containing build path entries | |
1279 | * corresponding to the list | |
1280 | */ | |
1281 | private static IClasspathEntry[] convert(List<CPListElement> list) { | |
1282 | IClasspathEntry[] entries= new IClasspathEntry[list.size()]; | |
1283 | for (int i= 0; i < list.size(); i++) { | |
1284 | CPListElement element= list.get(i); | |
1285 | entries[i]= element.getClasspathEntry(); | |
1286 | } | |
1287 | return entries; | |
1288 | } | |
1289 | ||
1290 | /** | |
1291 | * Validate the new entry in the context of the existing entries. Furthermore, | |
1292 | * check if exclusion filters need to be applied and do so if necessary. | |
1293 | * | |
1294 | * If validation was successful, add the new entry to the list of existing entries. | |
1295 | * | |
1296 | * @param entry the entry to be validated and added to the list of existing entries. | |
1297 | * @param existingEntries a list of existing entries representing the build path | |
1298 | * @param project the Java project | |
1299 | * @throws CoreException in case that validation fails | |
1300 | */ | |
1301 | private static void validateAndAddEntry(CPListElement entry, List<CPListElement> existingEntries, IJavaProject project) throws CoreException { | |
1302 | IPath path= entry.getPath(); | |
1303 | IPath projPath= project.getProject().getFullPath(); | |
1304 | IWorkspaceRoot workspaceRoot= ResourcesPlugin.getWorkspace().getRoot(); | |
1305 | IStatus validate= workspaceRoot.getWorkspace().validatePath(path.toString(), IResource.FOLDER); | |
1306 | StatusInfo rootStatus= new StatusInfo(); | |
1307 | rootStatus.setOK(); | |
1308 | boolean isExternal= isExternalArchiveOrLibrary(entry); | |
1309 | if (!isExternal && validate.matches(IStatus.ERROR) && !project.getPath().equals(path)) { | |
1310 | rootStatus.setError(Messages.format(NewWizardMessages.NewSourceFolderWizardPage_error_InvalidRootName, validate.getMessage())); | |
1311 | throw new CoreException(rootStatus); | |
1312 | } else { | |
1313 | if (!isExternal && !project.getPath().equals(path)) { | |
1314 | IResource res= workspaceRoot.findMember(path); | |
1315 | if (res != null) { | |
1316 | if (res.getType() != IResource.FOLDER && res.getType() != IResource.FILE) { | |
1317 | rootStatus.setError(NewWizardMessages.NewSourceFolderWizardPage_error_NotAFolder); | |
1318 | throw new CoreException(rootStatus); | |
1319 | } | |
1320 | } else { | |
1321 | URI projLocation= project.getProject().getLocationURI(); | |
1322 | if (projLocation != null) { | |
1323 | IFileStore store= EFS.getStore(projLocation).getFileStore(path); | |
1324 | if (store.fetchInfo().exists()) { | |
1325 | rootStatus.setError(NewWizardMessages.NewSourceFolderWizardPage_error_AlreadyExistingDifferentCase); | |
1326 | throw new CoreException(rootStatus); | |
1327 | } | |
1328 | } | |
1329 | } | |
1330 | } | |
1331 | ||
1332 | for (int i= 0; i < existingEntries.size(); i++) { | |
1333 | CPListElement curr= existingEntries.get(i); | |
1334 | if (curr.getEntryKind() == IClasspathEntry.CPE_SOURCE) { | |
1335 | if (path.equals(curr.getPath()) && !project.getPath().equals(path)) { | |
1336 | rootStatus.setError(NewWizardMessages.NewSourceFolderWizardPage_error_AlreadyExisting); | |
1337 | throw new CoreException(rootStatus); | |
1338 | } | |
1339 | } | |
1340 | } | |
1341 | ||
1342 | if (!isExternal && !entry.getPath().equals(project.getPath())) | |
1343 | exclude(entry.getPath(), existingEntries, new ArrayList<CPListElement>(), project, null); | |
1344 | ||
1345 | IPath outputLocation= project.getOutputLocation(); | |
1346 | insertAtEndOfCategory(entry, existingEntries); | |
1347 | ||
1348 | IClasspathEntry[] entries= convert(existingEntries); | |
1349 | ||
1350 | IJavaModelStatus status= JavaConventions.validateClasspath(project, entries, outputLocation); | |
1351 | if (!status.isOK()) { | |
1352 | if (outputLocation.equals(projPath)) { | |
1353 | IStatus status2= JavaConventions.validateClasspath(project, entries, outputLocation); | |
1354 | if (status2.isOK()) { | |
1355 | if (project.isOnClasspath(project)) { | |
1356 | rootStatus.setInfo(Messages.format(NewWizardMessages.NewSourceFolderWizardPage_warning_ReplaceSFandOL, BasicElementLabels.getPathLabel(outputLocation, false))); | |
1357 | } else { | |
1358 | rootStatus.setInfo(Messages.format(NewWizardMessages.NewSourceFolderWizardPage_warning_ReplaceOL, BasicElementLabels.getPathLabel(outputLocation, false))); | |
1359 | } | |
1360 | return; | |
1361 | } | |
1362 | } | |
1363 | rootStatus.setError(status.getMessage()); | |
1364 | throw new CoreException(rootStatus); | |
1365 | } | |
1366 | ||
1367 | if (isSourceFolder(project) || project.getPath().equals(path)) { | |
1368 | rootStatus.setWarning(NewWizardMessages.NewSourceFolderWizardPage_warning_ReplaceSF); | |
1369 | return; | |
1370 | } | |
1371 | ||
1372 | rootStatus.setOK(); | |
1373 | return; | |
1374 | } | |
1375 | } | |
1376 | ||
1377 | private static void insertAtEndOfCategory(CPListElement entry, List<CPListElement> existingEntries) { | |
1378 | int length= existingEntries.size(); | |
1379 | CPListElement[] elements= existingEntries.toArray(new CPListElement[length]); | |
1380 | int i= 0; | |
1381 | while (i < length && elements[i].getClasspathEntry().getEntryKind() != entry.getClasspathEntry().getEntryKind()) { | |
1382 | i++; | |
1383 | } | |
1384 | if (i < length) { | |
1385 | i++; | |
1386 | while (i < length && elements[i].getClasspathEntry().getEntryKind() == entry.getClasspathEntry().getEntryKind()) { | |
1387 | i++; | |
1388 | } | |
1389 | existingEntries.add(i, entry); | |
1390 | return; | |
1391 | } | |
1392 | ||
1393 | switch (entry.getClasspathEntry().getEntryKind()) { | |
1394 | case IClasspathEntry.CPE_SOURCE: | |
1395 | existingEntries.add(0, entry); | |
1396 | break; | |
1397 | case IClasspathEntry.CPE_CONTAINER: | |
1398 | case IClasspathEntry.CPE_LIBRARY: | |
1399 | case IClasspathEntry.CPE_PROJECT: | |
1400 | case IClasspathEntry.CPE_VARIABLE: | |
1401 | default: | |
1402 | existingEntries.add(entry); | |
1403 | break; | |
1404 | } | |
1405 | } | |
1406 | ||
1407 | private static boolean isExternalArchiveOrLibrary(CPListElement entry) { | |
1408 | if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY || entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) { | |
1409 | if (entry.getResource() instanceof IFolder) { | |
1410 | return false; | |
1411 | } | |
1412 | return true; | |
1413 | } | |
1414 | return false; | |
1415 | } | |
1416 | ||
1417 | public static boolean isInExternalOrArchive(IJavaElement element) { | |
1418 | IPackageFragmentRoot root= (IPackageFragmentRoot) element.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT); | |
1419 | return root != null && (root.isArchive() || root.isExternal()); | |
1420 | } | |
1421 | ||
1422 | /** | |
1423 | * Test if the provided kind is of type | |
1424 | * <code>IClasspathEntry.CPE_SOURCE</code> | |
1425 | * | |
1426 | * @param entry the classpath entry to be compared with the provided type | |
1427 | * @param kind the kind to be checked | |
1428 | * @return <code>true</code> if kind equals | |
1429 | * <code>IClasspathEntry.CPE_SOURCE</code>, | |
1430 | * <code>false</code> otherwise | |
1431 | */ | |
1432 | private static boolean equalEntryKind(IClasspathEntry entry, int kind) { | |
1433 | return entry.getEntryKind() == kind; | |
1434 | } | |
1435 | ||
1436 | public static OutputFolderValidator getValidator(final List<?> newElements, final IJavaProject project) throws JavaModelException { | |
1437 | return new OutputFolderValidator(newElements, project) { | |
1438 | ||
1439 | @Override | |
1440 | public boolean validate(IPath outputLocation) { | |
1441 | for (int i= 0; i < newElements.size(); i++) { | |
1442 | if (isInvalid(newElements.get(i), outputLocation)) | |
1443 | return false; | |
1444 | } | |
1445 | ||
1446 | for (int i= 0; i < fEntries.length; i++) { | |
1447 | if (isInvalid(fEntries[i], outputLocation)) | |
1448 | return false; | |
1449 | } | |
1450 | return true; | |
1451 | } | |
1452 | ||
1453 | /** | |
1454 | * Check if the output location for the given object is valid | |
1455 | * | |
1456 | * @param object the object to retrieve its path from and compare it | |
1457 | * to the output location | |
1458 | * @param outputLocation the output location | |
1459 | * @return <code>true</code> if the output location is invalid, that is, | |
1460 | * if it is a subfolder of the provided object. | |
1461 | */ | |
1462 | private boolean isInvalid(Object object, IPath outputLocation) { | |
1463 | IPath path= null; | |
1464 | if (object instanceof IFolder) | |
1465 | path= getFolderPath(object); | |
1466 | else | |
1467 | if (object instanceof IJavaElement) | |
1468 | path= getJavaElementPath(object); | |
1469 | else | |
1470 | if (object instanceof IClasspathEntry) | |
1471 | path= getCPEntryPath(object); | |
1472 | return isSubFolderOf(path, outputLocation); | |
1473 | } | |
1474 | ||
1475 | /** | |
1476 | * Get an <code>IFolder</code>'s path | |
1477 | * | |
1478 | * @param element an element which is of type <code>IFolder</code> | |
1479 | * @return the path of the folder | |
1480 | */ | |
1481 | private IPath getFolderPath(Object element) { | |
1482 | return ((IFolder) element).getFullPath(); | |
1483 | } | |
1484 | ||
1485 | /** | |
1486 | * Get an <code>IJavaElement</code>'s path | |
1487 | * | |
1488 | * @param element an element which is of type <code>IJavaElement</code> | |
1489 | * @return the path of the Java element | |
1490 | */ | |
1491 | private IPath getJavaElementPath(Object element) { | |
1492 | return ((IJavaElement) element).getPath(); | |
1493 | } | |
1494 | ||
1495 | /** | |
1496 | * Get an <code>IClasspathEntry</code>'s path | |
1497 | * | |
1498 | * @param entry an element which is of type <code>IClasspathEntry</code> | |
1499 | * @return the path of the classpath entry | |
1500 | */ | |
1501 | private IPath getCPEntryPath(Object entry) { | |
1502 | return ((IClasspathEntry) entry).getPath(); | |
1503 | } | |
1504 | ||
1505 | /** | |
1506 | * | |
1507 | * @param path1 the first path | |
1508 | * @param path2 the second path | |
1509 | * @return <code>true</code> if path1 is a subfolder of | |
1510 | * path2, <code>false</code> otherwise | |
1511 | */ | |
1512 | private boolean isSubFolderOf(IPath path1, IPath path2) { | |
1513 | if (path1 == null || path2 == null) { | |
1514 | if (path1 == null && path2 == null) | |
1515 | return true; | |
1516 | return false; | |
1517 | } | |
1518 | return path2.matchingFirstSegments(path1) == path2.segmentCount(); | |
1519 | } | |
1520 | ||
1521 | }; | |
1522 | } | |
1523 | ||
1524 | } |