1 /*******************************************************************************
2  * Copyright (c) 2000, 2016 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *     IBM Corporation - specified that a source archive or a source folder can be attached to a binary
14  *                               package fragment root.
15  *     IBM Corporation - added root manipulation APIs: copy, delete, move
16  *     IBM Corporation - added DESTINATION_PROJECT_CLASSPATH
17  *     IBM Corporation - added OTHER_REFERRING_PROJECTS_CLASSPATH
18  *     IBM Corporation - added NO_RESOURCE_MODIFICATION
19  *     IBM Corporation - added REPLACE
20  *     IBM Corporation - added ORIGINATING_PROJECT_CLASSPATH
21  *******************************************************************************/
22 package org.eclipse.jdt.core;
23 
24 import org.eclipse.core.runtime.IPath;
25 import org.eclipse.core.runtime.IProgressMonitor;
26 
27 /**
28  * A package fragment root contains a set of package fragments.
29  * It corresponds to an underlying resource which is either a folder,
30  * JAR, or zip.  In the case of a folder, all descendant folders represent
31  * package fragments.  For a given child folder representing a package fragment,
32  * the corresponding package name is composed of the folder names between the folder
33  * for this root and the child folder representing the package, separated by '.'.
34  * In the case of a JAR or zip, the contents of the archive dictates
35  * the set of package fragments in an analogous manner.
36  * Package fragment roots need to be opened before they can be navigated or manipulated.
37  * The children are of type <code>IPackageFragment</code>, and are in no particular order.
38  *
39  * @noimplement This interface is not intended to be implemented by clients.
40  */
41 public interface IPackageFragmentRoot
42 	extends IParent, IJavaElement, IOpenable {
43 	/**
44 	 * Kind constant for a source path root. Indicates this root
45 	 * only contains source files.
46 	 */
47 	int K_SOURCE = 1;
48 	/**
49 	 * Kind constant for a binary path root. Indicates this
50 	 * root only contains binary files.
51 	 */
52 	int K_BINARY = 2;
53 	/**
54 	 * Empty root path
55 	 */
56 	String DEFAULT_PACKAGEROOT_PATH = ""; //$NON-NLS-1$
57 	/**
58 	 * Update model flag constant (bit mask value 1) indicating that the operation
59 	 * is to not copy/move/delete the package fragment root resource.
60 	 * @since 2.1
61 	 */
62 	int NO_RESOURCE_MODIFICATION = 1;
63 	/**
64 	 * Update model flag constant (bit mask value 2) indicating that the operation
65 	 * is to update the classpath of the originating project.
66 	 * @since 2.1
67 	 */
68 	int ORIGINATING_PROJECT_CLASSPATH = 2;
69 	/**
70 	 * Update model flag constant (bit mask value 4) indicating that the operation
71 	 * is to update the classpath of all referring projects except the originating project.
72 	 * @since 2.1
73 	 */
74 	int OTHER_REFERRING_PROJECTS_CLASSPATH = 4;
75 	/**
76 	 * Update model flag constant (bit mask value 8) indicating that the operation
77 	 * is to update the classpath of the destination project.
78 	 * @since 2.1
79 	 */
80 	int DESTINATION_PROJECT_CLASSPATH = 8;
81 	/**
82 	 * Update model flag constant (bit mask value 16) indicating that the operation
83 	 * is to replace the resource and the destination project's classpath entry.
84 	 * @since 2.1
85 	 */
86 	int REPLACE = 16;
87 	/**
88 	 * Attaches the source archive identified by the given absolute path to this
89 	 * binary package fragment root. <code>rootPath</code> specifies the location
90 	 * of the root within the archive or folder (empty specifies the default root
91 	 * and <code>null</code> specifies the root path should be detected).
92 	 * Once a source archive or folder is attached to the package fragment root,
93 	 * the <code>getSource</code> and <code>getSourceRange</code>
94 	 * methods become operational for binary types/members.
95 	 * To detach a source archive or folder from a package fragment root, specify
96 	 * <code>null</code> as the source path.
97 	 *
98 	 * @param sourcePath the given absolute path to the source archive or folder
99 	 * @param rootPath specifies the location of the root within the archive
100 	 *              (empty specifies the default root and <code>null</code> specifies
101 	 *               automatic detection of the root path)
102 	 * @param monitor the given progress monitor
103 	 * @exception JavaModelException if this operation fails. Reasons include:
104 	 * <ul>
105 	 * <li> This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
106 	 * <li> A <code>CoreException</code> occurred while updating a server property
107 	 * <li> This package fragment root is not of kind binary (INVALID_ELEMENT_TYPES)
108 	 * <li> The path provided is not absolute (RELATIVE_PATH)
109 	 * </ul>
110 	 */
attachSource(IPath sourcePath, IPath rootPath, IProgressMonitor monitor)111 	void attachSource(IPath sourcePath, IPath rootPath, IProgressMonitor monitor)
112 		throws JavaModelException;
113 
114 	/**
115 	 * Copies the resource of this package fragment root to the destination path
116 	 * as specified by <code>IResource.copy(IPath, int, IProgressMonitor)</code>
117 	 * but excluding nested source folders.
118 	 * <p>
119 	 * If <code>NO_RESOURCE_MODIFICATION</code> is specified in
120 	 * <code>updateModelFlags</code> or if this package fragment root is external,
121 	 * this operation doesn't copy the resource. <code>updateResourceFlags</code>
122 	 * is then ignored.
123 	 * </p><p>
124 	 * If <code>DESTINATION_PROJECT_CLASSPATH</code> is specified in
125 	 * <code>updateModelFlags</code>, updates the classpath of the
126 	 * destination's project (if it is a Java project). If a non-<code>null</code>
127 	 * sibling is specified, a copy of this root's classpath entry is inserted before the
128 	 * sibling on the destination project's raw classpath. If <code>null</code> is
129 	 * specified, the classpath entry is added at the end of the raw classpath.
130 	 * </p><p>
131 	 * If <code>REPLACE</code> is specified in <code>updateModelFlags</code>,
132 	 * overwrites the resource at the destination path if any.
133 	 * If the same classpath entry already exists on the destination project's raw
134 	 * classpath, then the sibling is ignored and the new classpath entry replaces the
135 	 * existing one.
136 	 * </p><p>
137 	 * If no flags is specified in <code>updateModelFlags</code> (using
138 	 * <code>IResource.NONE</code>), the default behavior applies: the
139 	 * resource is copied (if this package fragment root is not external) and the
140 	 * classpath is not updated.
141 	 * </p>
142 	 *
143 	 * @param destination the destination path
144 	 * @param updateResourceFlags bit-wise or of update resource flag constants
145 	 *   (<code>IResource.FORCE</code> and <code>IResource.SHALLOW</code>)
146 	 * @param updateModelFlags bit-wise or of update resource flag constants
147 	 *   (<code>DESTINATION_PROJECT_CLASSPATH</code> and
148 	 *   <code>NO_RESOURCE_MODIFICATION</code>)
149 	 * @param sibling the classpath entry before which a copy of the classpath
150 	 * entry should be inserted or <code>null</code> if the classpath entry should
151 	 * be inserted at the end
152 	 * @param monitor a progress monitor
153 	 *
154 	 * @exception JavaModelException if this root could not be copied. Reasons
155 	 * include:
156 	 * <ul>
157 	 * <li> This root does not exist (ELEMENT_DOES_NOT_EXIST)</li>
158 	 * <li> A <code>CoreException</code> occurred while copying the
159 	 * resource or updating a classpath</li>
160 	 * <li>
161 	 * The destination is not inside an existing project and <code>updateModelFlags</code>
162 	 * has been specified as <code>DESTINATION_PROJECT_CLASSPATH</code>
163 	 * (INVALID_DESTINATION)</li>
164 	 * <li> The sibling is not a classpath entry on the destination project's
165 	 * raw classpath (INVALID_SIBLING)</li>
166 	 * <li> The same classpath entry already exists on the destination project's
167 	 * classpath (NAME_COLLISION) and <code>updateModelFlags</code>
168 	 * has not been specified as <code>REPLACE</code></li>
169 	 * </ul>
170 	 * @see org.eclipse.core.resources.IResource#copy(IPath, boolean, IProgressMonitor)
171 	 * @since 2.1
172 	 */
copy(IPath destination, int updateResourceFlags, int updateModelFlags, IClasspathEntry sibling, IProgressMonitor monitor)173 	void copy(IPath destination, int updateResourceFlags, int updateModelFlags, IClasspathEntry sibling, IProgressMonitor monitor) throws JavaModelException;
174 	/**
175 	 * Creates and returns a package fragment in this root with the
176 	 * given dot-separated package name.  An empty string specifies the default package.
177 	 * This has the side effect of creating all package
178 	 * fragments that are a prefix of the new package fragment which
179 	 * do not exist yet. If the package fragment already exists, this
180 	 * has no effect.
181 	 *
182 	 * For a description of the <code>force</code> flag, see <code>IFolder.create</code>.
183 	 *
184 	 * @param name the given dot-separated package name
185 	 * @param force a flag controlling how to deal with resources that
186 	 *    are not in sync with the local file system
187 	 * @param monitor the given progress monitor
188 	 * @exception JavaModelException if the element could not be created. Reasons include:
189 	 * <ul>
190 	 * <li> This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
191 	 * <li> A <code>CoreException</code> occurred while creating an underlying resource
192 	 * <li> This package fragment root is read only (READ_ONLY)
193 	 * <li> The name is not a valid package name (INVALID_NAME)
194 	 * </ul>
195 	 * @return a package fragment in this root with the given dot-separated package name
196 	 * @see org.eclipse.core.resources.IFolder#create(boolean, boolean, IProgressMonitor)
197 	 */
createPackageFragment( String name, boolean force, IProgressMonitor monitor)198 	IPackageFragment createPackageFragment(
199 		String name,
200 		boolean force,
201 		IProgressMonitor monitor)
202 		throws JavaModelException;
203 	/**
204 	 * Deletes the resource of this package fragment root as specified by
205 	 * <code>IResource.delete(int, IProgressMonitor)</code> but excluding nested
206 	 * source folders.
207 	 * <p>
208 	 * If <code>NO_RESOURCE_MODIFICATION</code> is specified in
209 	 * <code>updateModelFlags</code> or if this package fragment root is external,
210 	 * this operation doesn't delete the resource. <code>updateResourceFlags</code>
211 	 * is then ignored.
212 	 * </p><p>
213 	 * If <code>ORIGINATING_PROJECT_CLASSPATH</code> is specified in
214 	 * <code>updateModelFlags</code>, update the raw classpath of this package
215 	 * fragment root's project by removing the corresponding classpath entry.
216 	 * </p><p>
217 	 * If <code>OTHER_REFERRING_PROJECTS_CLASSPATH</code> is specified in
218 	 * <code>updateModelFlags</code>, update the raw classpaths of all other Java
219 	 * projects referring to this root's resource by removing the corresponding classpath
220 	 * entries.
221 	 * </p><p>
222 	 * If no flags is specified in <code>updateModelFlags</code> (using
223 	 * <code>IResource.NONE</code>), the default behavior applies: the
224 	 * resource is deleted (if this package fragment root is not external) and no
225 	 * classpaths are updated.
226 	 * </p>
227 	 *
228 	 * @param updateResourceFlags bit-wise or of update resource flag constants
229 	 *   (<code>IResource.FORCE</code> and <code>IResource.KEEP_HISTORY</code>)
230 	 * @param updateModelFlags bit-wise or of update resource flag constants
231 	 *   (<code>ORIGINATING_PROJECT_CLASSPATH</code>,
232 	 *   <code>OTHER_REFERRING_PROJECTS_CLASSPATH</code> and
233 	 *   <code>NO_RESOURCE_MODIFICATION</code>)
234 	 * @param monitor a progress monitor
235 	 *
236 	 * @exception JavaModelException if this root could not be deleted. Reasons
237 	 * include:
238 	 * <ul>
239 	 * <li> This root does not exist (ELEMENT_DOES_NOT_EXIST)</li>
240 	 * <li> A <code>CoreException</code> occurred while deleting the resource
241 	 * or updating a classpath
242 	 * </li>
243 	 * </ul>
244 	 * @see org.eclipse.core.resources.IResource#delete(boolean, IProgressMonitor)
245 	 * @since 2.1
246 	 */
delete(int updateResourceFlags, int updateModelFlags, IProgressMonitor monitor)247 	void delete(int updateResourceFlags, int updateModelFlags, IProgressMonitor monitor) throws JavaModelException;
248 	/**
249 	 * Returns this package fragment root's kind encoded as an integer.
250 	 * A package fragment root can contain source files (i.e. files with one
251 	 * of the {@link JavaCore#getJavaLikeExtensions() Java-like extensions},
252 	 * or <code>.class</code> files, but not both.
253 	 * If the underlying folder or archive contains other kinds of files, they are ignored.
254 	 * In particular, <code>.class</code> files are ignored under a source package fragment root,
255 	 * and source files are ignored under a binary package fragment root.
256 	 *
257 	 * @exception JavaModelException if this element does not exist or if an
258 	 *		exception occurs while accessing its corresponding resource.
259 	 * @return this package fragment root's kind encoded as an integer
260 	 * @see IPackageFragmentRoot#K_SOURCE
261 	 * @see IPackageFragmentRoot#K_BINARY
262 	 */
getKind()263 	int getKind() throws JavaModelException;
264 
265 	/**
266 	 * Returns an array of non-Java resources contained in this package fragment root.
267 	 * <p>
268 	 * Non-Java resources includes other files and folders located in the same
269 	 * directories as the compilation units or class files under this package
270 	 * fragment root. Resources excluded from this package fragment root
271 	 * by virtue of inclusion/exclusion patterns on the corresponding source classpath
272 	 * entry are considered non-Java resources and will appear in the result
273 	 * (possibly in a folder). Thus when a nested source folder is excluded, it will appear
274 	 * in the non-Java resources of the outer folder.
275 	 * </p><p>
276 	 * Since 3.3, if this package fragment root is an archive, the non-Java resources
277 	 * are a tree of {@link IJarEntryResource}s. One can navigate this tree using
278 	 * the {@link IJarEntryResource#getChildren()} and
279 	 * {@link IJarEntryResource#getParent()} methods.
280 	 * </p>
281 	 *
282 	 * @return an array of non-Java resources (<code>IFile</code>s,
283 	 *              <code>IFolder</code>s, or <code>IStorage</code>s if the
284 	 *              package fragment root is in archive) contained in this package
285 	 *              fragment root
286 	 * @exception JavaModelException if this element does not exist or if an
287 	 *		exception occurs while accessing its corresponding resource.
288 	 * @see IClasspathEntry#getInclusionPatterns()
289 	 * @see IClasspathEntry#getExclusionPatterns()
290 	 */
getNonJavaResources()291 	Object[] getNonJavaResources() throws JavaModelException;
292 
293 	/**
294 	 * Returns the package fragment with the given package name.
295 	 * An empty string indicates the default package.
296 	 * This is a handle-only operation.  The package fragment
297 	 * may or may not exist.
298 	 *
299 	 * @param packageName the given package name
300 	 * @return the package fragment with the given package name
301 	 */
getPackageFragment(String packageName)302 	IPackageFragment getPackageFragment(String packageName);
303 
304 
305 	/**
306 	 * Returns the first raw classpath entry that corresponds to this package
307 	 * fragment root.
308 	 * A raw classpath entry corresponds to a package fragment root if once resolved
309 	 * this entry's path is equal to the root's path.
310 	 *
311 	 * @exception JavaModelException if this element does not exist or if an
312 	 *		exception occurs while accessing its corresponding resource.
313 	 * @return the first raw classpath entry that corresponds to this package fragment root
314 	 * @since 2.0
315 	 */
getRawClasspathEntry()316 	IClasspathEntry getRawClasspathEntry() throws JavaModelException;
317 
318 	/**
319 	 * Returns the first resolved classpath entry that corresponds to this package fragment root.
320 	 * A resolved classpath entry is said to correspond to a root if the path of the resolved
321 	 * entry is equal to the root's path.
322 	 *
323 	 * @return the first resolved classpath entry that corresponds to this package fragment root
324 	 * @throws JavaModelException if this element does not exist or if an
325 	 *		exception occurs while accessing its corresponding resource.
326 	 * @since 3.6
327 	 */
getResolvedClasspathEntry()328 	IClasspathEntry getResolvedClasspathEntry() throws JavaModelException;
329 
330 	/**
331 	 * Returns the absolute path to the source archive attached to
332 	 * this package fragment root's binary archive.
333 	 *
334 	 * @return the absolute path to the corresponding source archive,
335 	 *   or <code>null</code> if this package fragment root's binary archive
336 	 *   has no corresponding source archive, or if this package fragment root
337 	 *   is not a binary archive
338 	 * @exception JavaModelException if this operation fails
339 	 */
getSourceAttachmentPath()340 	IPath getSourceAttachmentPath() throws JavaModelException;
341 
342 	/**
343 	 * Returns the path within this package fragment root's source archive.
344 	 * An empty path indicates that packages are located at the root of the
345 	 * source archive.
346 	 *
347 	 * @return the path within the corresponding source archive,
348 	 *   or <code>null</code> if this package fragment root's binary archive
349 	 *   has no corresponding source archive, or if this package fragment root
350 	 *   is not a binary archive
351 	 * @exception JavaModelException if this operation fails
352 	 */
getSourceAttachmentRootPath()353 	IPath getSourceAttachmentRootPath() throws JavaModelException;
354 
355 	/**
356 	 * Returns whether this package fragment root's underlying
357 	 * resource is a binary archive (a JAR or zip file).
358 	 * <p>
359 	 * This is a handle-only method.
360 	 * </p>
361 	 *
362 	 * @return true if this package fragment root's underlying resource is a binary archive, false otherwise
363 	 */
isArchive()364 	public boolean isArchive();
365 
366 	/**
367 	 * Returns whether this package fragment root is external
368 	 * to the workbench (that is, a local file), and has no
369 	 * underlying resource.
370 	 * <p>
371 	 * This is a handle-only method.
372 	 * </p>
373 	 *
374 	 * @return true if this package fragment root is external
375 	 * to the workbench (that is, a local file), and has no
376 	 * underlying resource, false otherwise
377 	 */
isExternal()378 	boolean isExternal();
379 
380 	/**
381 	 * Moves the resource of this package fragment root to the destination path
382 	 * as specified by <code>IResource.move(IPath,int,IProgressMonitor)</code>
383 	 * but excluding nested source folders.
384 	 * <p>
385 	 * If <code>NO_RESOURCE_MODIFICATION</code> is specified in
386 	 * <code>updateModelFlags</code> or if this package fragment root is external,
387 	 * this operation doesn't move the resource. <code>updateResourceFlags</code>
388 	 * is then ignored.
389 	 * </p><p>
390 	 * If <code>DESTINATION_PROJECT_CLASSPATH</code> is specified in
391 	 * <code>updateModelFlags</code>, updates the classpath of the
392 	 * destination's project (if it is a Java project). If a non-<code>null</code>
393 	 * sibling is specified, a copy of this root's classpath entry is inserted before the
394 	 * sibling on the destination project's raw classpath. If <code>null</code> is
395 	 * specified, the classpath entry is added at the end of the raw classpath.
396 	 * </p><p>
397 	 * If <code>ORIGINATING_PROJECT_CLASSPATH</code> is specified in
398 	 * <code>updateModelFlags</code>, update the raw classpath of this package
399 	 * fragment root's project by removing the corresponding classpath entry.
400 	 * </p><p>
401 	 * If <code>OTHER_REFERRING_PROJECTS_CLASSPATH</code> is specified in
402 	 * <code>updateModelFlags</code>, update the raw classpaths of all other Java
403 	 * projects referring to this root's resource by removing the corresponding classpath
404 	 * entries.
405 	 * </p><p>
406 	 * If <code>REPLACE</code> is specified in <code>updateModelFlags</code>,
407 	 * overwrites the resource at the destination path if any.
408 	 * If the same classpath entry already exists on the destination project's raw
409 	 * classpath, then the sibling is ignored and the new classpath entry replaces the
410 	 * existing one.
411 	 * </p><p>
412 	 * If no flags is specified in <code>updateModelFlags</code> (using
413 	 * <code>IResource.NONE</code>), the default behavior applies: the
414 	 * resource is moved (if this package fragment root is not external) and no
415 	 * classpaths are updated.
416 	 * </p>
417 	 *
418 	 * @param destination the destination path
419 	 * @param updateResourceFlags bit-wise or of update flag constants
420 	 * (<code>IResource.FORCE</code>, <code>IResource.KEEP_HISTORY</code>
421 	 * and <code>IResource.SHALLOW</code>)
422 	 * @param updateModelFlags bit-wise or of update resource flag constants
423 	 *   (<code>DESTINATION_PROJECT_CLASSPATH</code>,
424 	 *   <code>ORIGINATING_PROJECT_CLASSPATH</code>,
425 	 *   <code>OTHER_REFERRING_PROJECTS_CLASSPATH</code> and
426 	 *   <code>NO_RESOURCE_MODIFICATION</code>)
427 	 * @param sibling the classpath entry before which a copy of the classpath
428 	 * entry should be inserted or <code>null</code> if the classpath entry should
429 	 * be inserted at the end
430 	 * @param monitor a progress monitor
431 	 *
432 	 * @exception JavaModelException if this root could not be moved. Reasons
433 	 * include:
434 	 * <ul>
435 	 * <li> This root does not exist (ELEMENT_DOES_NOT_EXIST)</li>
436 	 * <li> A <code>CoreException</code> occurred while copying the
437 	 * resource or updating a classpath</li>
438 	 * <li>
439 	 * The destination is not inside an existing project and <code>updateModelFlags</code>
440 	 * has been specified as <code>DESTINATION_PROJECT_CLASSPATH</code>
441 	 * (INVALID_DESTINATION)</li>
442 	 * <li> The sibling is not a classpath entry on the destination project's
443 	 * raw classpath (INVALID_SIBLING)</li>
444 	 * <li> The same classpath entry already exists on the destination project's
445 	 * classpath (NAME_COLLISION) and <code>updateModelFlags</code>
446 	 * has not been specified as <code>REPLACE</code></li>
447 	 * </ul>
448 	 * @see org.eclipse.core.resources.IResource#move(IPath, boolean, IProgressMonitor)
449 	 * @since 2.1
450 	 */
move(IPath destination, int updateResourceFlags, int updateModelFlags, IClasspathEntry sibling, IProgressMonitor monitor)451 	void move(IPath destination, int updateResourceFlags, int updateModelFlags, IClasspathEntry sibling, IProgressMonitor monitor) throws JavaModelException;
452 
453 	/**
454 	 * Returns the <code>IModuleDescription</code> that this package fragment root contains.
455 	 * Returns <code>null</code> if the root doesn't contain any named module or if the project compiler compliance is 1.8 or lower.
456 	 * If present the module descriptor is found as a child of the package fragment representing the default package.
457 	 *
458 	 * Note that only one of the source package fragment roots in a Java Project can legally
459 	 * contain a module descriptor.
460 	 *
461 	 * @return the <code>IModuleDescription</code> this root contains.
462 	 * @since 3.14
463 	 */
getModuleDescription()464 	public IModuleDescription getModuleDescription();
465 }
466