1 /*******************************************************************************
2  * Copyright (c) 2000, 2003 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.internal.core;
12 
13 import java.util.ArrayList;
14 import java.util.Map;
15 
16 import net.sourceforge.phpdt.core.IJavaElement;
17 import net.sourceforge.phpdt.core.IJavaModelStatusConstants;
18 import net.sourceforge.phpdt.core.IPackageFragment;
19 import net.sourceforge.phpdt.core.IPackageFragmentRoot;
20 import net.sourceforge.phpdt.core.JavaCore;
21 import net.sourceforge.phpdt.core.JavaModelException;
22 import net.sourceforge.phpdt.core.WorkingCopyOwner;
23 import net.sourceforge.phpdt.core.compiler.CharOperation;
24 import net.sourceforge.phpdt.internal.core.util.MementoTokenizer;
25 import net.sourceforge.phpdt.internal.core.util.Util;
26 
27 import org.eclipse.core.resources.IContainer;
28 import org.eclipse.core.resources.IFolder;
29 import org.eclipse.core.resources.IResource;
30 import org.eclipse.core.resources.ResourcesPlugin;
31 import org.eclipse.core.runtime.CoreException;
32 import org.eclipse.core.runtime.IPath;
33 import org.eclipse.core.runtime.IProgressMonitor;
34 import org.eclipse.core.runtime.QualifiedName;
35 
36 /**
37  * @see IPackageFragmentRoot
38  */
39 public class PackageFragmentRoot extends Openable implements
40 		IPackageFragmentRoot {
41 
42 	/**
43 	 * The delimiter between the source path and root path in the attachment
44 	 * server property.
45 	 */
46 	protected final static char ATTACHMENT_PROPERTY_DELIMITER = '*';
47 
48 	/*
49 	 * No source attachment property
50 	 */
51 	protected final static String NO_SOURCE_ATTACHMENT = ""; //$NON-NLS-1$
52 
53 	/*
54 	 * No source mapper singleton
55 	 */
56 	// protected final static SourceMapper NO_SOURCE_MAPPER = new
57 	// SourceMapper();
58 	/**
59 	 * The resource associated with this root. (an IResource or a java.io.File
60 	 * (for external jar only))
61 	 */
62 	protected Object resource;
63 
64 	/**
65 	 * Constructs a package fragment root which is the root of the java package
66 	 * directory hierarchy.
67 	 */
PackageFragmentRoot(IResource resource, JavaProject project, String name)68 	protected PackageFragmentRoot(IResource resource, JavaProject project,
69 			String name) {
70 		super(project, name);
71 		this.resource = resource;
72 	}
73 
74 	/**
75 	 * @see Openable
76 	 */
buildStructure(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource)77 	protected boolean buildStructure(OpenableElementInfo info,
78 			IProgressMonitor pm, Map newElements, IResource underlyingResource)
79 			throws JavaModelException {
80 
81 		// check whether this pkg fragment root can be opened
82 		if (!resourceExists()) { // || !isOnClasspath()) {
83 			throw newNotPresentException();
84 		}
85 
86 		((PackageFragmentRootInfo) info)
87 				.setRootKind(determineKind(underlyingResource));
88 		return computeChildren(info, newElements);
89 	}
90 
91 	/**
92 	 * Returns the root's kind - K_SOURCE or K_BINARY, defaults to K_SOURCE if
93 	 * it is not on the classpath.
94 	 *
95 	 * @exception NotPresentException
96 	 *                if the project and root do not exist.
97 	 */
determineKind(IResource underlyingResource)98 	protected int determineKind(IResource underlyingResource)
99 			throws JavaModelException {
100 		// IClasspathEntry[] entries=
101 		// ((JavaProject)getJavaProject()).getExpandedClasspath(true);
102 		// for (int i= 0; i < entries.length; i++) {
103 		// IClasspathEntry entry= entries[i];
104 		// if (entry.getPath().equals(underlyingResource.getFullPath())) {
105 		// return entry.getContentKind();
106 		// }
107 		// }
108 		return IPackageFragmentRoot.K_SOURCE;
109 	}
110 
111 	/**
112 	 * Compute the package fragment children of this package fragment root.
113 	 *
114 	 * @exception JavaModelException
115 	 *                The resource associated with this package fragment root
116 	 *                does not exist
117 	 */
computeChildren(OpenableElementInfo info, Map newElements)118 	protected boolean computeChildren(OpenableElementInfo info, Map newElements)
119 			throws JavaModelException {
120 		// Note the children are not opened (so not added to newElements) for a
121 		// regular package fragment root
122 		// Howver they are opened for a Jar package fragment root (see
123 		// JarPackageFragmentRoot#computeChildren)
124 		try {
125 			// the underlying resource may be a folder or a project (in the case
126 			// that the project folder
127 			// is actually the package fragment root)
128 			IResource underlyingResource = getResource();
129 			if (underlyingResource.getType() == IResource.FOLDER
130 					|| underlyingResource.getType() == IResource.PROJECT) {
131 				ArrayList vChildren = new ArrayList(5);
132 				IContainer rootFolder = (IContainer) underlyingResource;
133 				// char[][] inclusionPatterns = fullInclusionPatternChars();
134 				char[][] exclusionPatterns = fullExclusionPatternChars();
135 				computeFolderChildren(rootFolder, !Util.isExcluded(rootFolder,
136 						exclusionPatterns), "", vChildren, exclusionPatterns); //$NON-NLS-1$
137 
138 				IJavaElement[] children = new IJavaElement[vChildren.size()];
139 				vChildren.toArray(children);
140 				info.setChildren(children);
141 			}
142 		} catch (JavaModelException e) {
143 			// problem resolving children; structure remains unknown
144 			info.setChildren(new IJavaElement[] {});
145 			throw e;
146 		}
147 		return true;
148 	}
149 
150 	/**
151 	 * Starting at this folder, create package fragments and add the fragments
152 	 * that are not exclused to the collection of children.
153 	 *
154 	 * @exception JavaModelException
155 	 *                The resource associated with this package fragment does
156 	 *                not exist
157 	 */
computeFolderChildren(IContainer folder, boolean isIncluded, String prefix, ArrayList vChildren, char[][] exclusionPatterns)158 	protected void computeFolderChildren(IContainer folder, boolean isIncluded,
159 			String prefix, ArrayList vChildren, char[][] exclusionPatterns)
160 			throws JavaModelException {
161 		// , char[][] inclusionPatterns, char[][] exclusionPatterns) throws
162 		// JavaModelException {
163 
164 		if (isIncluded) {
165 			IPackageFragment pkg = getPackageFragment(prefix);
166 			vChildren.add(pkg);
167 		}
168 		try {
169 			JavaProject javaProject = (JavaProject) getJavaProject();
170 			IResource[] members = folder.members();
171 			boolean hasIncluded = isIncluded;
172 			for (int i = 0, max = members.length; i < max; i++) {
173 				IResource member = members[i];
174 				String memberName = member.getName();
175 
176 				switch (member.getType()) {
177 
178 				case IResource.FOLDER:
179 					if (Util.isValidFolderNameForPackage(memberName)) {
180 						boolean isMemberIncluded = !Util.isExcluded(member,
181 								exclusionPatterns);
182 						// keep looking inside as long as included already, or
183 						// may have child included due to inclusion patterns
184 						// if (isMemberIncluded || inclusionPatterns != null) {
185 						// // eliminate binary output only if nested inside
186 						// direct subfolders
187 						// if (javaProject.contains(member)) {
188 						// String newPrefix;
189 						// if (prefix.length() == 0) {
190 						// newPrefix = memberName;
191 						// } else {
192 						// newPrefix = prefix + "." + memberName; //$NON-NLS-1$
193 						// }
194 						// computeFolderChildren((IFolder) member,
195 						// isMemberIncluded, newPrefix, vChildren,
196 						// inclusionPatterns,
197 						// exclusionPatterns);
198 						// }
199 						// }
200 					}
201 					break;
202 				case IResource.FILE:
203 					// inclusion filter may only include files, in which case we
204 					// still want to include the immediate parent package
205 					// (lazily)
206 					if (!hasIncluded
207 							&& Util.isValidCompilationUnitName(memberName)
208 							&& !Util.isExcluded(member, exclusionPatterns)) {
209 						hasIncluded = true;
210 						IPackageFragment pkg = getPackageFragment(prefix);
211 						vChildren.add(pkg);
212 					}
213 					break;
214 				}
215 			}
216 		} catch (IllegalArgumentException e) {
217 			throw new JavaModelException(e,
218 					IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST); // could
219 																		// be
220 																		// thrown
221 																		// by
222 																		// ElementTree
223 																		// when
224 																		// path
225 			// is not found
226 		} catch (CoreException e) {
227 			throw new JavaModelException(e);
228 		}
229 	}
230 
231 	/**
232 	 * @see IPackageFragmentRoot
233 	 */
234 	// public void attachSource(IPath sourcePath, IPath rootPath,
235 	// IProgressMonitor monitor) throws JavaModelException {
236 	// try {
237 	// verifyAttachSource(sourcePath);
238 	// if (monitor != null) {
239 	// monitor.beginTask(ProjectPrefUtil.bind("element.attachingSource"), 2);
240 	// //$NON-NLS-1$
241 	// }
242 	// SourceMapper oldMapper= getSourceMapper();
243 	// IWorkspace workspace = ResourcesPlugin.getWorkspace();
244 	// boolean rootNeedsToBeClosed= false;
245 	//
246 	// if (sourcePath == null) {
247 	// //source being detached
248 	// rootNeedsToBeClosed= true;
249 	// setSourceMapper(null);
250 	// /* Disable deltas (see 1GDTUSD)
251 	// // fire a delta to notify the UI about the source detachement.
252 	// JavaModelManager manager = (JavaModelManager)
253 	// JavaModelManager.getJavaModelManager();
254 	// JavaModel model = (JavaModel) getJavaModel();
255 	// JavaElementDelta attachedSourceDelta = new JavaElementDelta(model);
256 	// attachedSourceDelta .sourceDetached(this); // this would be a
257 	// PackageFragmentRoot
258 	// manager.registerResourceDelta(attachedSourceDelta );
259 	// manager.fire(); // maybe you want to fire the change later. Let us know
260 	// about it.
261 	// */
262 	// } else {
263 	// /*
264 	// // fire a delta to notify the UI about the source attachement.
265 	// JavaModelManager manager = (JavaModelManager)
266 	// JavaModelManager.getJavaModelManager();
267 	// JavaModel model = (JavaModel) getJavaModel();
268 	// JavaElementDelta attachedSourceDelta = new JavaElementDelta(model);
269 	// attachedSourceDelta .sourceAttached(this); // this would be a
270 	// PackageFragmentRoot
271 	// manager.registerResourceDelta(attachedSourceDelta );
272 	// manager.fire(); // maybe you want to fire the change later. Let us know
273 	// about it.
274 	// */
275 	//
276 	// //check if different from the current attachment
277 	// IPath storedSourcePath= getSourceAttachmentPath();
278 	// IPath storedRootPath= getSourceAttachmentRootPath();
279 	// if (monitor != null) {
280 	// monitor.worked(1);
281 	// }
282 	// if (storedSourcePath != null) {
283 	// if (!(storedSourcePath.equals(sourcePath) && (rootPath != null &&
284 	// rootPath.equals(storedRootPath)) || storedRootPath == null))
285 	// {
286 	// rootNeedsToBeClosed= true;
287 	// }
288 	// }
289 	// // check if source path is valid
290 	// Object target = JavaModel.getTarget(workspace.getRoot(), sourcePath,
291 	// false);
292 	// if (target == null) {
293 	// if (monitor != null) {
294 	// monitor.done();
295 	// }
296 	// throw new JavaModelException(new
297 	// JavaModelStatus(IJavaModelStatusConstants.INVALID_PATH, sourcePath));
298 	// }
299 	// SourceMapper mapper = createSourceMapper(sourcePath, rootPath);
300 	// if (rootPath == null && mapper.rootPath != null) {
301 	// // as a side effect of calling the SourceMapper constructor, the root
302 	// path was computed
303 	// rootPath = new Path(mapper.rootPath);
304 	// }
305 	// setSourceMapper(mapper);
306 	// }
307 	// if (sourcePath == null) {
308 	// setSourceAttachmentProperty(null); //remove the property
309 	// } else {
310 	// //set the property to the path of the mapped source
311 	// setSourceAttachmentProperty(
312 	// sourcePath.toString()
313 	// + (rootPath == null ? "" : (ATTACHMENT_PROPERTY_DELIMITER +
314 	// rootPath.toString()))); //$NON-NLS-1$
315 	// }
316 	// if (rootNeedsToBeClosed) {
317 	// if (oldMapper != null) {
318 	// oldMapper.close();
319 	// }
320 	// BufferManager manager= BufferManager.getDefaultBufferManager();
321 	// Enumeration openBuffers= manager.getOpenBuffers();
322 	// while (openBuffers.hasMoreElements()) {
323 	// IBuffer buffer= (IBuffer) openBuffers.nextElement();
324 	// IOpenable possibleMember= buffer.getOwner();
325 	// if (isAncestorOf((IJavaElement) possibleMember)) {
326 	// buffer.close();
327 	// }
328 	// }
329 	// if (monitor != null) {
330 	// monitor.worked(1);
331 	// }
332 	// }
333 	// } catch (JavaModelException e) {
334 	// setSourceAttachmentProperty(null); // loose info - will be recomputed
335 	// throw e;
336 	// } finally {
337 	// if (monitor != null) {
338 	// monitor.done();
339 	// }
340 	// }
341 	// }
342 	// SourceMapper createSourceMapper(IPath sourcePath, IPath rootPath) {
343 	// SourceMapper mapper = new SourceMapper(
344 	// sourcePath,
345 	// rootPath == null ? null : rootPath.toOSString(),
346 	// this.isExternal() ? JavaCore.getOptions() :
347 	// this.getJavaProject().getOptions(true)); // only project options if
348 	// associated with
349 	// resource
350 	// return mapper;
351 	// }
352 	/*
353 	 * @see net.sourceforge.phpdt.core.IPackageFragmentRoot#delete
354 	 */
355 	// public void delete(
356 	// int updateResourceFlags,
357 	// int updateModelFlags,
358 	// IProgressMonitor monitor)
359 	// throws JavaModelException {
360 	//
361 	// DeletePackageFragmentRootOperation op = new
362 	// DeletePackageFragmentRootOperation(this, updateResourceFlags,
363 	// updateModelFlags);
364 	// runOperation(op, monitor);
365 	// }
366 	/**
367 	 * This root is being closed. If this root has an associated source
368 	 * attachment, close it too.
369 	 *
370 	 * @see JavaElement
371 	 */
372 	// protected void closing(Object info) throws JavaModelException { TODO
373 	// remove after 2.1
374 	// ((PackageFragmentRootInfo) info).sourceMapper = null;
375 	// super.closing(info);
376 	// }
377 	/**
378 	 * Compute the package fragment children of this package fragment root.
379 	 *
380 	 * @exception JavaModelException
381 	 *                The resource associated with this package fragment root
382 	 *                does not exist
383 	 */
384 	// protected boolean computeChildren(OpenableElementInfo info) throws
385 	// JavaModelException {
386 	// try {
387 	// // the underlying resource may be a folder or a project (in the case that
388 	// the project folder
389 	// // is actually the package fragment root)
390 	// IResource resource = getResource();
391 	// if (resource.getType() == IResource.FOLDER || resource.getType() ==
392 	// IResource.PROJECT) {
393 	// ArrayList vChildren = new ArrayList(5);
394 	// char[][] exclusionPatterns = fullExclusionPatternChars();
395 	// computeFolderChildren((IContainer) resource, "", vChildren,
396 	// exclusionPatterns); //$NON-NLS-1$
397 	// IJavaElement[] children = new IJavaElement[vChildren.size()];
398 	// vChildren.toArray(children);
399 	// info.setChildren(children);
400 	// }
401 	// } catch (JavaModelException e) {
402 	// //problem resolving children; structure remains unknown
403 	// info.setChildren(new IJavaElement[]{});
404 	// throw e;
405 	// }
406 	// return true;
407 	// }
408 	/**
409 	 * Starting at this folder, create package fragments and add the fragments
410 	 * that are not exclused to the collection of children.
411 	 *
412 	 * @exception JavaModelException
413 	 *                The resource associated with this package fragment does
414 	 *                not exist
415 	 */
416 	// protected void computeFolderChildren(IContainer folder, String prefix,
417 	// ArrayList vChildren, char[][] exclusionPatterns) throws
418 	// JavaModelException {
419 	// IPackageFragment pkg = getPackageFragment(prefix);
420 	// vChildren.add(pkg);
421 	// try {
422 	// JavaProject javaProject = (JavaProject)getJavaProject();
423 	// IResource[] members = folder.members();
424 	// for (int i = 0, max = members.length; i < max; i++) {
425 	// IResource member = members[i];
426 	// String memberName = member.getName();
427 	// if (member.getType() == IResource.FOLDER
428 	// && ProjectPrefUtil.isValidFolderNameForPackage(memberName)
429 	// && !ProjectPrefUtil.isExcluded(member, exclusionPatterns)) {
430 	//
431 	// // eliminate binary output only if nested inside direct subfolders
432 	// if (javaProject.contains(member)) {
433 	// String newPrefix;
434 	// if (prefix.length() == 0) {
435 	// newPrefix = memberName;
436 	// } else {
437 	// newPrefix = prefix + "." + memberName; //$NON-NLS-1$
438 	// }
439 	// computeFolderChildren((IFolder) member, newPrefix, vChildren,
440 	// exclusionPatterns);
441 	// }
442 	// }
443 	// }
444 	// } catch(IllegalArgumentException e){
445 	// throw new JavaModelException(e,
446 	// IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST); // could be thrown by
447 	// ElementTree when path
448 	// is not found
449 	// } catch (CoreException e) {
450 	// throw new JavaModelException(e);
451 	// }
452 	// }
453 	/*
454 	 * Computes and returns the source attachment root path for the given source
455 	 * attachment path. Returns <code> null </code> if none could be found.
456 	 *
457 	 * @param sourceAttachmentPath the given absolute path to the source archive
458 	 * or folder @return the computed source attachment root path or <code> null
459 	 * </cde> if none could be found @throws JavaModelException
460 	 */
461 	// public IPath computeSourceAttachmentRootPath(IPath sourceAttachmentPath)
462 	// throws JavaModelException {
463 	// IPath sourcePath = this.getSourceAttachmentPath();
464 	// if (sourcePath == null) return null;
465 	// SourceMapper mapper =
466 	// new SourceMapper(
467 	// sourcePath,
468 	// null, // detect root path
469 	// this.isExternal() ? JavaCore.getOptions() :
470 	// this.getJavaProject().getOptions(true) // only project options if
471 	// associated with
472 	// resource
473 	// );
474 	// if (mapper.rootPath == null) return null;
475 	// return new Path(mapper.rootPath);
476 	// }
477 	/*
478 	 * @see net.sourceforge.phpdt.core.IPackageFragmentRoot#copy
479 	 */
480 	// public void copy(
481 	// IPath destination,
482 	// int updateResourceFlags,
483 	// int updateModelFlags,
484 	// IClasspathEntry sibling,
485 	// IProgressMonitor monitor)
486 	// throws JavaModelException {
487 	//
488 	// CopyPackageFragmentRootOperation op =
489 	// new CopyPackageFragmentRootOperation(this, destination,
490 	// updateResourceFlags, updateModelFlags, sibling);
491 	// runOperation(op, monitor);
492 	// }
493 	/**
494 	 * Returns a new element info for this element.
495 	 */
createElementInfo()496 	protected Object createElementInfo() {
497 		return new PackageFragmentRootInfo();
498 	}
499 
500 	/**
501 	 * @see IPackageFragmentRoot
502 	 */
503 	// public IPackageFragment createPackageFragment(String name, boolean force,
504 	// IProgressMonitor monitor) throws JavaModelException {
505 	// CreatePackageFragmentOperation op = new
506 	// CreatePackageFragmentOperation(this, name, force);
507 	// runOperation(op, monitor);
508 	// return getPackageFragment(name);
509 	// }
510 	/**
511 	 * Returns the root's kind - K_SOURCE or K_BINARY, defaults to K_SOURCE if
512 	 * it is not on the classpath.
513 	 *
514 	 * @exception NotPresentException
515 	 *                if the project and root do not exist.
516 	 */
517 	// protected int determineKind(IResource underlyingResource) throws
518 	// JavaModelException {
519 	// IClasspathEntry[] entries=
520 	// ((JavaProject)getJavaProject()).getExpandedClasspath(true);
521 	// for (int i= 0; i < entries.length; i++) {
522 	// IClasspathEntry entry= entries[i];
523 	// if (entry.getPath().equals(underlyingResource.getFullPath())) {
524 	// return entry.getContentKind();
525 	// }
526 	// }
527 	// return IPackageFragmentRoot.K_SOURCE;
528 	// }
529 	/**
530 	 * Compares two objects for equality; for <code>PackageFragmentRoot</code>s,
531 	 * equality is having the same <code>JavaModel</code>, same resources,
532 	 * and occurrence count.
533 	 *
534 	 */
equals(Object o)535 	public boolean equals(Object o) {
536 		if (this == o)
537 			return true;
538 		if (!(o instanceof PackageFragmentRoot))
539 			return false;
540 		PackageFragmentRoot other = (PackageFragmentRoot) o;
541 		return getJavaModel().equals(other.getJavaModel())
542 				&& this.resource.equals(other.resource)
543 				&& occurrenceCount == other.occurrenceCount;
544 	}
545 
546 	/**
547 	 * @see IJavaElement
548 	 */
549 	// public boolean exists() {
550 	// return super.exists()
551 	// && isOnClasspath();
552 	// }
553 	// public IClasspathEntry findSourceAttachmentRecommendation() {
554 	// try {
555 	// IPath rootPath = this.getPath();
556 	// IClasspathEntry entry;
557 	// IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
558 	//
559 	// // try on enclosing project first
560 	// JavaProject parentProject = (JavaProject) getJavaProject();
561 	// try {
562 	// entry = parentProject.getClasspathEntryFor(rootPath);
563 	// if (entry != null){
564 	// Object target = JavaModel.getTarget(workspaceRoot,
565 	// entry.getSourceAttachmentPath(), true);
566 	// if (target instanceof IFile){
567 	// IFile file = (IFile) target;
568 	// if (ProjectPrefUtil.isArchiveFileName(file.getName())){
569 	// return entry;
570 	// }
571 	// } else if (target instanceof IFolder) {
572 	// return entry;
573 	// }
574 	// if (target instanceof java.io.File){
575 	// java.io.File file = (java.io.File) target;
576 	// if (file.isFile()) {
577 	// if (ProjectPrefUtil.isArchiveFileName(file.getName())){
578 	// return entry;
579 	// }
580 	// } else {
581 	// // external directory
582 	// return entry;
583 	// }
584 	// }
585 	// }
586 	// } catch(JavaModelException e){
587 	// }
588 	//
589 	// // iterate over all projects
590 	// IJavaModel model = getJavaModel();
591 	// IJavaProject[] jProjects = model.getJavaProjects();
592 	// for (int i = 0, max = jProjects.length; i < max; i++){
593 	// JavaProject jProject = (JavaProject) jProjects[i];
594 	// if (jProject == parentProject) continue; // already done
595 	// try {
596 	// entry = jProject.getClasspathEntryFor(rootPath);
597 	// if (entry != null){
598 	// Object target = JavaModel.getTarget(workspaceRoot,
599 	// entry.getSourceAttachmentPath(), true);
600 	// if (target instanceof IFile){
601 	// IFile file = (IFile) target;
602 	// if (ProjectPrefUtil.isArchiveFileName(file.getName())){
603 	// return entry;
604 	// }
605 	// } else if (target instanceof IFolder) {
606 	// return entry;
607 	// }
608 	// if (target instanceof java.io.File){
609 	// java.io.File file = (java.io.File) target;
610 	// if (file.isFile()) {
611 	// if (ProjectPrefUtil.isArchiveFileName(file.getName())){
612 	// return entry;
613 	// }
614 	// } else {
615 	// // external directory
616 	// return entry;
617 	// }
618 	// }
619 	// }
620 	// } catch(JavaModelException e){
621 	// }
622 	// }
623 	// } catch(JavaModelException e){
624 	// }
625 	//
626 	// return null;
627 	// }
628 	/*
629 	 * Returns the exclusion patterns from the classpath entry associated with
630 	 * this root.
631 	 */
fullExclusionPatternChars()632 	char[][] fullExclusionPatternChars() {
633 		return null;
634 		// try {
635 
636 		// if (this.isOpen() && this.getKind() != IPackageFragmentRoot.K_SOURCE)
637 		// return null;
638 		// ClasspathEntry entry = (ClasspathEntry)getRawClasspathEntry();
639 		// if (entry == null) {
640 		// return null;
641 		// } else {
642 		// return entry.fullExclusionPatternChars();
643 		// }
644 		// } catch (JavaModelException e) {
645 		// return null;
646 		// }
647 	}
648 
649 	/**
650 	 * @see Openable
651 	 */
generateInfos(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource)652 	protected boolean generateInfos(OpenableElementInfo info,
653 			IProgressMonitor pm, Map newElements, IResource underlyingResource)
654 			throws JavaModelException {
655 
656 		// ((PackageFragmentRootInfo)
657 		// info).setRootKind(determineKind(underlyingResource));
658 		// return computeChildren(info);
659 		return false;
660 	}
661 
662 	/**
663 	 * @see JavaElement#getHandleMemento()
664 	 */
getHandleMementoDelimiter()665 	protected char getHandleMementoDelimiter() {
666 		return JavaElement.JEM_PACKAGEFRAGMENTROOT;
667 	}
668 
669 	/**
670 	 * @see IJavaElement
671 	 */
getElementType()672 	public int getElementType() {
673 		return PACKAGE_FRAGMENT_ROOT;
674 	}
675 
676 	/*
677 	 * @see JavaElement
678 	 */
getHandleFromMemento(String token, MementoTokenizer memento, WorkingCopyOwner owner)679 	public IJavaElement getHandleFromMemento(String token,
680 			MementoTokenizer memento, WorkingCopyOwner owner) {
681 		switch (token.charAt(0)) {
682 		case JEM_COUNT:
683 			return getHandleUpdatingCountFromMemento(memento, owner);
684 		case JEM_PACKAGEFRAGMENT:
685 			String pkgName;
686 			if (memento.hasMoreTokens()) {
687 				pkgName = memento.nextToken();
688 				char firstChar = pkgName.charAt(0);
689 				// if (firstChar == JEM_CLASSFILE || firstChar ==
690 				// JEM_COMPILATIONUNIT || firstChar == JEM_COUNT) {
691 				if (firstChar == JEM_COMPILATIONUNIT || firstChar == JEM_COUNT) {
692 					token = pkgName;
693 					pkgName = IPackageFragment.DEFAULT_PACKAGE_NAME;
694 				} else {
695 					token = null;
696 				}
697 			} else {
698 				pkgName = IPackageFragment.DEFAULT_PACKAGE_NAME;
699 				token = null;
700 			}
701 			JavaElement pkg = (JavaElement) getPackageFragment(pkgName);
702 			if (token == null) {
703 				return pkg.getHandleFromMemento(memento, owner);
704 			} else {
705 				return pkg.getHandleFromMemento(token, memento, owner);
706 			}
707 		}
708 		return null;
709 	}
710 
711 	/**
712 	 * @see JavaElement#getHandleMemento()
713 	 */
getHandleMemento()714 	public String getHandleMemento() {
715 		IPath path;
716 		IResource underlyingResource = getResource();
717 		if (underlyingResource != null) {
718 			// internal jar or regular root
719 			if (getResource().getProject()
720 					.equals(getJavaProject().getProject())) {
721 				path = underlyingResource.getProjectRelativePath();
722 			} else {
723 				path = underlyingResource.getFullPath();
724 			}
725 		} else {
726 			// external jar
727 			path = getPath();
728 		}
729 		StringBuffer buff = new StringBuffer(((JavaElement) getParent())
730 				.getHandleMemento());
731 		buff.append(getHandleMementoDelimiter());
732 		escapeMementoName(buff, path.toString());
733 		if (this.occurrenceCount > 1) {
734 			buff.append(JEM_COUNT);
735 			buff.append(this.occurrenceCount);
736 		}
737 		return buff.toString();
738 	}
739 
740 	/**
741 	 * @see IPackageFragmentRoot
742 	 */
getKind()743 	public int getKind() throws JavaModelException {
744 		return ((PackageFragmentRootInfo) getElementInfo()).getRootKind();
745 	}
746 
747 	/**
748 	 * Returns an array of non-java resources contained in the receiver.
749 	 */
750 	// public Object[] getNonJavaResources() throws JavaModelException {
751 	// return ((PackageFragmentRootInfo)
752 	// getElementInfo()).getNonJavaResources(getJavaProject(), getResource(),
753 	// this);
754 	// }
755 	/**
756 	 * @see IPackageFragmentRoot
757 	 */
getPackageFragment(String packageName)758 	public IPackageFragment getPackageFragment(String packageName) {
759 		if (packageName.indexOf(' ') != -1) { // tolerate package names with
760 												// spaces (e.g. 'x . y')
761 			// (http://bugs.eclipse.org/bugs/show_bug.cgi?id=21957)
762 			char[][] compoundName = Util.toCompoundChars(packageName);
763 			StringBuffer buffer = new StringBuffer(packageName.length());
764 			for (int i = 0, length = compoundName.length; i < length; i++) {
765 				buffer.append(CharOperation.trim(compoundName[i]));
766 				if (i != length - 1) {
767 					buffer.append('.');
768 				}
769 			}
770 			packageName = buffer.toString();
771 		}
772 		return new PackageFragment(this, packageName);
773 	}
774 
775 	/**
776 	 * Returns the package name for the given folder (which is a decendent of
777 	 * this root).
778 	 */
getPackageName(IFolder folder)779 	protected String getPackageName(IFolder folder) throws JavaModelException {
780 		IPath myPath = getPath();
781 		IPath pkgPath = folder.getFullPath();
782 		int mySegmentCount = myPath.segmentCount();
783 		int pkgSegmentCount = pkgPath.segmentCount();
784 		StringBuffer name = new StringBuffer(
785 				IPackageFragment.DEFAULT_PACKAGE_NAME);
786 		for (int i = mySegmentCount; i < pkgSegmentCount; i++) {
787 			if (i > mySegmentCount) {
788 				name.append('.');
789 			}
790 			name.append(pkgPath.segment(i));
791 		}
792 		return name.toString();
793 	}
794 
795 	/**
796 	 * @see IJavaElement
797 	 */
getPath()798 	public IPath getPath() {
799 		return getResource().getFullPath();
800 	}
801 
802 	/*
803 	 * @see IPackageFragmentRoot
804 	 */
805 	// public IClasspathEntry getRawClasspathEntry() throws JavaModelException {
806 	//
807 	// IClasspathEntry rawEntry = null;
808 	// IJavaProject project = this.getJavaProject();
809 	// project.getResolvedClasspath(true); // force the reverse rawEntry cache
810 	// to be populated
811 	// JavaModelManager.PerProjectInfo perProjectInfo =
812 	// JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(project.getProject());
813 	// if (perProjectInfo != null && perProjectInfo.resolvedPathToRawEntries !=
814 	// null) {
815 	// rawEntry = (IClasspathEntry)
816 	// perProjectInfo.resolvedPathToRawEntries.get(this.getPath());
817 	// }
818 	// return rawEntry;
819 	// }
820 	/*
821 	 * @see IJavaElement
822 	 */
getResource()823 	public IResource getResource() {
824 		return (IResource) this.resource;
825 	}
826 
827 	/**
828 	 * @see IPackageFragmentRoot
829 	 */
830 	// public IPath getSourceAttachmentPath() throws JavaModelException {
831 	// if (getKind() != K_BINARY) return null;
832 	//
833 	// String serverPathString= getSourceAttachmentProperty();
834 	// if (serverPathString == null) {
835 	// return null;
836 	// }
837 	// int index= serverPathString.lastIndexOf(ATTACHMENT_PROPERTY_DELIMITER);
838 	// if (index < 0) {
839 	// // no root path specified
840 	// return new Path(serverPathString);
841 	// } else {
842 	// String serverSourcePathString= serverPathString.substring(0, index);
843 	// return new Path(serverSourcePathString);
844 	// }
845 	// }
846 	/**
847 	 * Returns the server property for this package fragment root's source
848 	 * attachement.
849 	 */
850 	// protected String getSourceAttachmentProperty() throws JavaModelException
851 	// {
852 	// String propertyString = null;
853 	// QualifiedName qName= getSourceAttachmentPropertyName();
854 	// try {
855 	// propertyString =
856 	// ResourcesPlugin.getWorkspace().getRoot().getPersistentProperty(qName);
857 	//
858 	// // if no existing source attachment information, then lookup a
859 	// recommendation from classpath entries
860 	// if (propertyString == null) {
861 	// IClasspathEntry recommendation = findSourceAttachmentRecommendation();
862 	// if (recommendation != null) {
863 	// IPath rootPath = recommendation.getSourceAttachmentRootPath();
864 	// propertyString =
865 	// recommendation.getSourceAttachmentPath().toString()
866 	// + ((rootPath == null)
867 	// ? "" : //$NON-NLS-1$
868 	// (ATTACHMENT_PROPERTY_DELIMITER + rootPath.toString()));
869 	// setSourceAttachmentProperty(propertyString);
870 	// } else {
871 	// // mark as being already looked up
872 	// setSourceAttachmentProperty(NO_SOURCE_ATTACHMENT);
873 	// }
874 	// } else if (NO_SOURCE_ATTACHMENT.equals(propertyString)) {
875 	// // already looked up and no source attachment found
876 	// return null;
877 	// }
878 	// return propertyString;
879 	// } catch (CoreException ce) {
880 	// throw new JavaModelException(ce);
881 	// }
882 	// }
883 	/**
884 	 * Returns the qualified name for the source attachment property of this
885 	 * root.
886 	 */
getSourceAttachmentPropertyName()887 	protected QualifiedName getSourceAttachmentPropertyName()
888 			throws JavaModelException {
889 		return new QualifiedName(JavaCore.PLUGIN_ID,
890 				"sourceattachment: " + this.getPath().toOSString()); //$NON-NLS-1$
891 	}
892 
setSourceAttachmentProperty(String property)893 	public void setSourceAttachmentProperty(String property) {
894 		try {
895 			ResourcesPlugin.getWorkspace().getRoot().setPersistentProperty(
896 					this.getSourceAttachmentPropertyName(), property);
897 		} catch (CoreException ce) {
898 		}
899 	}
900 
901 	/**
902 	 * For use by <code>AttachSourceOperation</code> only. Sets the source
903 	 * mapper associated with this root.
904 	 */
905 	// public void setSourceMapper(SourceMapper mapper) throws
906 	// JavaModelException {
907 	// ((PackageFragmentRootInfo) getElementInfo()).setSourceMapper(mapper);
908 	// }
909 	/**
910 	 * @see IPackageFragmentRoot
911 	 */
912 	// public IPath getSourceAttachmentRootPath() throws JavaModelException {
913 	// if (getKind() != K_BINARY) return null;
914 	//
915 	// String serverPathString= getSourceAttachmentProperty();
916 	// if (serverPathString == null) {
917 	// return null;
918 	// }
919 	// int index = serverPathString.lastIndexOf(ATTACHMENT_PROPERTY_DELIMITER);
920 	// if (index == -1) return null;
921 	// String serverRootPathString=
922 	// IPackageFragmentRoot.DEFAULT_PACKAGEROOT_PATH;
923 	// if (index != serverPathString.length() - 1) {
924 	// serverRootPathString= serverPathString.substring(index + 1);
925 	// }
926 	// return new Path(serverRootPathString);
927 	// }
928 	/**
929 	 * @see JavaElement
930 	 */
931 	// public SourceMapper getSourceMapper() {
932 	// SourceMapper mapper;
933 	// try {
934 	// PackageFragmentRootInfo rootInfo = (PackageFragmentRootInfo)
935 	// getElementInfo();
936 	// mapper = rootInfo.getSourceMapper();
937 	// if (mapper == null) {
938 	// // first call to this method
939 	// IPath sourcePath= getSourceAttachmentPath();
940 	// if (sourcePath != null) {
941 	// IPath rootPath= getSourceAttachmentRootPath();
942 	// mapper = this.createSourceMapper(sourcePath, rootPath);
943 	// if (rootPath == null && mapper.rootPath != null) {
944 	// // as a side effect of calling the SourceMapper constructor, the root
945 	// path was computed
946 	// rootPath = new Path(mapper.rootPath);
947 	//
948 	// //set the property to the path of the mapped source
949 	// this.setSourceAttachmentProperty(
950 	// sourcePath.toString()
951 	// + ATTACHMENT_PROPERTY_DELIMITER
952 	// + rootPath.toString());
953 	// }
954 	// rootInfo.setSourceMapper(mapper);
955 	// } else {
956 	// // remember that no source is attached
957 	// rootInfo.setSourceMapper(NO_SOURCE_MAPPER);
958 	// mapper = null;
959 	// }
960 	// } else if (mapper == NO_SOURCE_MAPPER) {
961 	// // a previous call to this method found out that no source was attached
962 	// mapper = null;
963 	// }
964 	// } catch (JavaModelException e) {
965 	// // no source can be attached
966 	// mapper = null;
967 	// }
968 	// return mapper;
969 	// }
970 	/**
971 	 * @see IJavaElement
972 	 */
getUnderlyingResource()973 	public IResource getUnderlyingResource() throws JavaModelException {
974 		if (!exists())
975 			throw newNotPresentException();
976 		return getResource();
977 	}
978 
hashCode()979 	public int hashCode() {
980 		return this.resource.hashCode();
981 	}
982 
983 	/**
984 	 * @see IPackageFragmentRoot
985 	 */
isArchive()986 	public boolean isArchive() {
987 		return false;
988 	}
989 
990 	/**
991 	 * @see IPackageFragmentRoot
992 	 */
isExternal()993 	public boolean isExternal() {
994 		return false;
995 	}
996 
997 	/*
998 	 * Returns whether this package fragment root is on the classpath of its
999 	 * project.
1000 	 */
1001 	// protected boolean isOnClasspath() {
1002 	// if (this.getElementType() == IJavaElement.JAVA_PROJECT){
1003 	// return true;
1004 	// }
1005 	//
1006 	// IPath path = this.getPath();
1007 	// try {
1008 	// // check package fragment root on classpath of its project
1009 	// IJavaProject project = this.getJavaProject();
1010 	// IClasspathEntry[] classpath = project.getResolvedClasspath(true);
1011 	// for (int i = 0, length = classpath.length; i < length; i++) {
1012 	// IClasspathEntry entry = classpath[i];
1013 	// if (entry.getPath().equals(path)) {
1014 	// return true;
1015 	// }
1016 	// }
1017 	// } catch(JavaModelException e){
1018 	// // could not read classpath, then assume it is outside
1019 	// }
1020 	// return false;
1021 	// }
1022 	/*
1023 	 * @see net.sourceforge.phpdt.core.IPackageFragmentRoot#move
1024 	 */
1025 	// public void move(
1026 	// IPath destination,
1027 	// int updateResourceFlags,
1028 	// int updateModelFlags,
1029 	// IClasspathEntry sibling,
1030 	// IProgressMonitor monitor)
1031 	// throws JavaModelException {
1032 	//
1033 	// MovePackageFragmentRootOperation op =
1034 	// new MovePackageFragmentRootOperation(this, destination,
1035 	// updateResourceFlags, updateModelFlags, sibling);
1036 	// runOperation(op, monitor);
1037 	// }
1038 	//
1039 	//
1040 	// protected void openWhenClosed(IProgressMonitor pm) throws
1041 	// JavaModelException {
1042 	// if (!this.resourceExists()
1043 	// || !this.isOnClasspath()) {
1044 	// throw newNotPresentException();
1045 	// }
1046 	// super.openWhenClosed(pm);
1047 	// }
1048 	/**
1049 	 * Recomputes the children of this element, based on the current state of
1050 	 * the workbench.
1051 	 */
1052 	// public void refreshChildren() {
1053 	// try {
1054 	// OpenableElementInfo info= (OpenableElementInfo)getElementInfo();
1055 	// computeChildren(info);
1056 	// } catch (JavaModelException e) {
1057 	// // do nothing.
1058 	// }
1059 	// }
1060 	// /*
1061 	// * @see JavaElement#rootedAt(IJavaProject)
1062 	// */
1063 	// public IJavaElement rootedAt(IJavaProject project) {
1064 	// return
1065 	// new PackageFragmentRoot(
1066 	// getResource(),
1067 	// project,
1068 	// name);
1069 	// }
1070 	/**
1071 	 * @private Debugging purposes
1072 	 */
toStringInfo(int tab, StringBuffer buffer, Object info)1073 	protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
1074 		buffer.append(this.tabString(tab));
1075 		if (getElementName().length() == 0) {
1076 			buffer.append("[project root]"); //$NON-NLS-1$
1077 		} else {
1078 			IPath path = getPath();
1079 			if (getJavaProject().getElementName().equals(path.segment(0))) {
1080 				buffer.append(path.removeFirstSegments(1).makeRelative());
1081 			} else {
1082 				buffer.append(path);
1083 			}
1084 		}
1085 		if (info == null) {
1086 			buffer.append(" (not open)"); //$NON-NLS-1$
1087 		}
1088 	}
1089 
1090 	/**
1091 	 * Possible failures:
1092 	 * <ul>
1093 	 * <li>ELEMENT_NOT_PRESENT - the root supplied to the operation does not
1094 	 * exist
1095 	 * <li>INVALID_ELEMENT_TYPES - the root is not of kind K_BINARY
1096 	 * <li>RELATIVE_PATH - the path supplied to this operation must be an
1097 	 * absolute path
1098 	 * </ul>
1099 	 */
1100 	// protected void verifyAttachSource(IPath sourcePath) throws
1101 	// JavaModelException {
1102 	// if (!exists()) {
1103 	// throw newNotPresentException();
1104 	// } else if (this.getKind() != K_BINARY) {
1105 	// throw new JavaModelException(new
1106 	// JavaModelStatus(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, this));
1107 	// } else if (sourcePath != null && !sourcePath.isAbsolute()) {
1108 	// throw new JavaModelException(new
1109 	// JavaModelStatus(IJavaModelStatusConstants.RELATIVE_PATH, sourcePath));
1110 	// }
1111 	// }
1112 }