Copyright (c) 2000, 2017 IBM Corporation and others. This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which accompanies this distribution, and is available at https://www.eclipse.org/legal/epl-2.0/ SPDX-License-Identifier: EPL-2.0 Contributors: IBM Corporation - initial API and implementation
/******************************************************************************* * Copyright (c) 2000, 2017 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/
package org.eclipse.jdt.internal.core; import java.net.URL; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Path; import org.eclipse.jdt.core.IClassFile; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IModularClassFile; import org.eclipse.jdt.core.IOrdinaryClassFile; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.IParent; import org.eclipse.jdt.core.ISourceManipulation; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.WorkingCopyOwner; import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; import org.eclipse.jdt.internal.compiler.util.SuffixConstants; import org.eclipse.jdt.internal.core.JavaModelManager.PerProjectInfo; import org.eclipse.jdt.internal.core.util.MementoTokenizer; import org.eclipse.jdt.internal.core.util.Messages; import org.eclipse.jdt.internal.core.util.Util;
See Also:
  • IPackageFragment
/** * @see IPackageFragment */
@SuppressWarnings({"rawtypes", "unchecked"}) public class PackageFragment extends Openable implements IPackageFragment, SuffixConstants {
Constant empty list of class files
/** * Constant empty list of class files */
protected static final IClassFile[] NO_CLASSFILES = new IClassFile[] {}; protected static final IOrdinaryClassFile[] NO_ORDINARY_CLASSFILES = new IOrdinaryClassFile[] {};
Constant empty list of compilation units
/** * Constant empty list of compilation units */
protected static final ICompilationUnit[] NO_COMPILATION_UNITS = new ICompilationUnit[] {}; public String[] names; private boolean isValidPackageName; protected PackageFragment(PackageFragmentRoot root, String[] names) { super(root); this.names = names; this.isValidPackageName = internalIsValidPackageName(); }
See Also:
  • Openable
/** * @see Openable */
@Override protected boolean buildStructure(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException { // add compilation units/class files from resources HashSet vChildren = new HashSet(); int kind = getKind(); try { PackageFragmentRoot root = getPackageFragmentRoot(); char[][] inclusionPatterns = root.fullInclusionPatternChars(); char[][] exclusionPatterns = root.fullExclusionPatternChars(); IResource[] members = ((IContainer) underlyingResource).members(); int length = members.length; if (length > 0) { IJavaProject project = getJavaProject(); String sourceLevel = project.getOption(JavaCore.COMPILER_SOURCE, true); String complianceLevel = project.getOption(JavaCore.COMPILER_COMPLIANCE, true); for (int i = 0; i < length; i++) { IResource child = members[i]; if (child.getType() != IResource.FOLDER && !Util.isExcluded(child, inclusionPatterns, exclusionPatterns)) { IJavaElement childElement; if (kind == IPackageFragmentRoot.K_SOURCE && Util.isValidCompilationUnitName(child.getName(), sourceLevel, complianceLevel)) { childElement = new CompilationUnit(this, child.getName(), DefaultWorkingCopyOwner.PRIMARY); vChildren.add(childElement); } else if (kind == IPackageFragmentRoot.K_BINARY && Util.isValidClassFileName(child.getName(), sourceLevel, complianceLevel)) { childElement = getClassFile(child.getName()); vChildren.add(childElement); } } } } } catch (CoreException e) { throw new JavaModelException(e); } if (kind == IPackageFragmentRoot.K_SOURCE) { // add primary compilation units ICompilationUnit[] primaryCompilationUnits = getCompilationUnits(DefaultWorkingCopyOwner.PRIMARY); for (int i = 0, length = primaryCompilationUnits.length; i < length; i++) { ICompilationUnit primary = primaryCompilationUnits[i]; vChildren.add(primary); } } if (!vChildren.isEmpty()) { IJavaElement[] children = new IJavaElement[vChildren.size()]; vChildren.toArray(children); info.setChildren(children); } else { info.setChildren(JavaElement.NO_ELEMENTS); } return true; }
Returns true if this fragment contains at least one java resource. Returns false otherwise.
/** * Returns true if this fragment contains at least one java resource. * Returns false otherwise. */
@Override public boolean containsJavaResources() throws JavaModelException { return ((PackageFragmentInfo) getElementInfo()).containsJavaResources(); }
See Also:
  • ISourceManipulation
/** * @see ISourceManipulation */
@Override public void copy(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor) throws JavaModelException { if (container == null) { throw new IllegalArgumentException(Messages.operation_nullContainer); } IJavaElement[] elements= new IJavaElement[] {this}; IJavaElement[] containers= new IJavaElement[] {container}; IJavaElement[] siblings= null; if (sibling != null) { siblings= new IJavaElement[] {sibling}; } String[] renamings= null; if (rename != null) { renamings= new String[] {rename}; } getJavaModel().copy(elements, containers, siblings, renamings, force, monitor); }
See Also:
  • IPackageFragment
/** * @see IPackageFragment */
@Override public ICompilationUnit createCompilationUnit(String cuName, String contents, boolean force, IProgressMonitor monitor) throws JavaModelException { CreateCompilationUnitOperation op= new CreateCompilationUnitOperation(this, cuName, contents, force); op.runOperation(monitor); return new CompilationUnit(this, cuName, DefaultWorkingCopyOwner.PRIMARY); }
See Also:
  • JavaElement
/** * @see JavaElement */
@Override protected Object createElementInfo() { return new PackageFragmentInfo(); }
See Also:
  • ISourceManipulation
/** * @see ISourceManipulation */
@Override public void delete(boolean force, IProgressMonitor monitor) throws JavaModelException { IJavaElement[] elements = new IJavaElement[] {this}; getJavaModel().delete(elements, force, monitor); } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof PackageFragment)) return false; PackageFragment other = (PackageFragment) o; return Util.equalArraysOrNull(this.names, other.names) && this.parent.equals(other.parent); } @Override public boolean exists() { // super.exist() only checks for the parent and the resource existence // so also ensure that: // - the package is not excluded (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=138577) // - its name is valide (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=108456) return super.exists() && !Util.isExcluded(this) && isValidPackageName(); }
Throws:
See Also:
  • getOrdinaryClassFile.getOrdinaryClassFile(String)
/** * @see IPackageFragment#getOrdinaryClassFile(String) * @exception IllegalArgumentException if the name does not end with ".class" or if the name is "module-info.class". */
@Override public IOrdinaryClassFile getOrdinaryClassFile(String classFileName) { if (!org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(classFileName)) { throw new IllegalArgumentException(Messages.bind(Messages.element_invalidClassFileName, classFileName)); } if (TypeConstants.MODULE_INFO_CLASS_NAME_STRING.equals(classFileName)) { throw new IllegalArgumentException(Messages.element_moduleInfoNotSupported); } // don't hold on the .class file extension to save memory // also make sure to not use substring as the resulting String may hold on the underlying char[] which might be much bigger than necessary int length = classFileName.length() - 6; char[] nameWithoutExtension = new char[length]; classFileName.getChars(0, length, nameWithoutExtension, 0); return new ClassFile(this, new String(nameWithoutExtension)); }
Throws:
See Also:
  • getClassFile.getClassFile(String)
/** * @see IPackageFragment#getClassFile(String) * @exception IllegalArgumentException if the name does not end with ".class". */
@Override public IClassFile getClassFile(String classFileName) { if (TypeConstants.MODULE_INFO_CLASS_NAME_STRING.equals(classFileName)) return getModularClassFile(); return getOrdinaryClassFile(classFileName); } @Override public IModularClassFile getModularClassFile() { // don't hold on the .class file extension to save memory // also make sure to not use substring as the resulting String may hold on the underlying char[] which might be much bigger than necessary return new ModularClassFile(this); }
Returns a collection of ordinary class files in this - a folder package fragment which has a root that has its kind set to IPackageFragmentRoot.K_Source does not recognize class files.
See Also:
  • getOrdinaryClassFiles.getOrdinaryClassFiles()
/** * Returns a collection of ordinary class files in this - a folder package fragment which has a root * that has its kind set to <code>IPackageFragmentRoot.K_Source</code> does not * recognize class files. * * @see IPackageFragment#getOrdinaryClassFiles() */
@Override public IOrdinaryClassFile[] getOrdinaryClassFiles() throws JavaModelException { if (getKind() == IPackageFragmentRoot.K_SOURCE) { return NO_ORDINARY_CLASSFILES; } ArrayList list = getChildrenOfType(CLASS_FILE); for (Iterator iterator = list.iterator(); iterator.hasNext();) { if (iterator.next() instanceof ModularClassFile) iterator.remove(); } IOrdinaryClassFile[] array= new IOrdinaryClassFile[list.size()]; list.toArray(array); return array; }
Returns a collection of all class files in this - a folder package fragment which has a root that has its kind set to IPackageFragmentRoot.K_Source does not recognize class files.
See Also:
  • getAllClassFiles.getAllClassFiles()
/** * Returns a collection of all class files in this - a folder package fragment which has a root * that has its kind set to <code>IPackageFragmentRoot.K_Source</code> does not * recognize class files. * * @see IPackageFragment#getAllClassFiles() */
@Override public IClassFile[] getAllClassFiles() throws JavaModelException { if (getKind() == IPackageFragmentRoot.K_SOURCE) { return NO_CLASSFILES; } ArrayList list = getChildrenOfType(CLASS_FILE); IClassFile[] array= new IClassFile[list.size()]; list.toArray(array); return array; } @Deprecated @Override public IClassFile[] getClassFiles() throws JavaModelException { return getOrdinaryClassFiles(); }
Throws:
See Also:
  • getCompilationUnit.getCompilationUnit(String)
/** * @see IPackageFragment#getCompilationUnit(String) * @exception IllegalArgumentException if the name does not end with ".java" */
@Override public ICompilationUnit getCompilationUnit(String cuName) { if (!org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(cuName)) { throw new IllegalArgumentException(Messages.convention_unit_notJavaName); } return new CompilationUnit(this, cuName, DefaultWorkingCopyOwner.PRIMARY); }
See Also:
  • getCompilationUnits.getCompilationUnits()
/** * @see IPackageFragment#getCompilationUnits() */
@Override public ICompilationUnit[] getCompilationUnits() throws JavaModelException { if (getKind() == IPackageFragmentRoot.K_BINARY) { return NO_COMPILATION_UNITS; } ArrayList list = getChildrenOfType(COMPILATION_UNIT); ICompilationUnit[] array= new ICompilationUnit[list.size()]; list.toArray(array); return array; }
See Also:
  • getCompilationUnits.getCompilationUnits(WorkingCopyOwner)
/** * @see IPackageFragment#getCompilationUnits(WorkingCopyOwner) */
@Override public ICompilationUnit[] getCompilationUnits(WorkingCopyOwner owner) { ICompilationUnit[] workingCopies = JavaModelManager.getJavaModelManager().getWorkingCopies(owner, false/*don't add primary*/); if (workingCopies == null) return JavaModelManager.NO_WORKING_COPY; int length = workingCopies.length; ICompilationUnit[] result = new ICompilationUnit[length]; int index = 0; for (int i = 0; i < length; i++) { ICompilationUnit wc = workingCopies[i]; if (equals(wc.getParent()) && !Util.isExcluded(wc)) { // 59933 - excluded wc shouldn't be answered back result[index++] = wc; } } if (index != length) { System.arraycopy(result, 0, result = new ICompilationUnit[index], 0, index); } return result; } @Override public String getElementName() { if (this.names.length == 0) return DEFAULT_PACKAGE_NAME; return Util.concatWith(this.names, '.'); }
See Also:
  • IJavaElement
/** * @see IJavaElement */
@Override public int getElementType() { return PACKAGE_FRAGMENT; } /* * @see JavaElement */ @Override public IJavaElement getHandleFromMemento(String token, MementoTokenizer memento, WorkingCopyOwner owner) { switch (token.charAt(0)) { case JEM_CLASSFILE: if (!memento.hasMoreTokens()) return this; String classFileName = memento.nextToken(); JavaElement classFile = (JavaElement) getClassFile(classFileName); return classFile.getHandleFromMemento(memento, owner); case JEM_MODULAR_CLASSFILE: classFile = (JavaElement) getModularClassFile(); return classFile.getHandleFromMemento(memento, owner); case JEM_COMPILATIONUNIT: if (!memento.hasMoreTokens()) return this; String cuName = memento.nextToken(); JavaElement cu = new CompilationUnit(this, cuName, owner); return cu.getHandleFromMemento(memento, owner); } return null; }
See Also:
  • getHandleMementoDelimiter.getHandleMementoDelimiter()
/** * @see JavaElement#getHandleMementoDelimiter() */
@Override protected char getHandleMementoDelimiter() { return JavaElement.JEM_PACKAGEFRAGMENT; }
See Also:
  • getKind.getKind()
/** * @see IPackageFragment#getKind() */
@Override public int getKind() throws JavaModelException { return ((IPackageFragmentRoot)getParent()).getKind(); }
Returns an array of non-java resources contained in the receiver.
/** * Returns an array of non-java resources contained in the receiver. */
@Override public Object[] getNonJavaResources() throws JavaModelException { if (isDefaultPackage()) { // We don't want to show non java resources of the default package (see PR #1G58NB8) return JavaElementInfo.NO_NON_JAVA_RESOURCES; } else { return ((PackageFragmentInfo) getElementInfo()).getNonJavaResources(resource(), getPackageFragmentRoot()); } }
See Also:
  • getPath.getPath()
/** * @see IJavaElement#getPath() */
@Override public IPath getPath() { PackageFragmentRoot root = getPackageFragmentRoot(); if (root.isArchive()) { return root.getPath(); } else { IPath path = root.getPath(); for (int i = 0, length = this.names.length; i < length; i++) { String name = this.names[i]; path = path.append(name); } return path; } }
See Also:
  • resource.resource()
/** * @see JavaElement#resource() */
@Override public IResource resource(PackageFragmentRoot root) { int length = this.names.length; if (length == 0) { return root.resource(root); } else { IPath path = new Path(this.names[0]); for (int i = 1; i < length; i++) path = path.append(this.names[i]); return ((IContainer)root.resource(root)).getFolder(path); } }
See Also:
  • getUnderlyingResource.getUnderlyingResource()
/** * @see IJavaElement#getUnderlyingResource() */
@Override public IResource getUnderlyingResource() throws JavaModelException { IResource rootResource = this.parent.getUnderlyingResource(); if (rootResource == null) { //jar package fragment root that has no associated resource return null; } // the underlying resource may be a folder or a project (in the case that the project folder // is atually the package fragment root) if (rootResource.getType() == IResource.FOLDER || rootResource.getType() == IResource.PROJECT) { IContainer folder = (IContainer) rootResource; String[] segs = this.names; for (int i = 0; i < segs.length; ++i) { IResource child = folder.findMember(segs[i]); if (child == null || child.getType() != IResource.FOLDER) { throw newNotPresentException(); } folder = (IFolder) child; } return folder; } else { return rootResource; } } @Override public int hashCode() { int hash = this.parent.hashCode(); for (int i = 0, length = this.names.length; i < length; i++) hash = Util.combineHashCodes(this.names[i].hashCode(), hash); return hash; }
See Also:
  • IParent
/** * @see IParent */
@Override public boolean hasChildren() throws JavaModelException { return getChildren().length > 0; }
See Also:
  • hasSubpackages.hasSubpackages()
/** * @see IPackageFragment#hasSubpackages() */
@Override public boolean hasSubpackages() throws JavaModelException { IJavaElement[] packages= ((IPackageFragmentRoot)getParent()).getChildren(); int namesLength = this.names.length; nextPackage: for (int i= 0, length = packages.length; i < length; i++) { String[] otherNames = ((PackageFragment) packages[i]).names; if (otherNames.length <= namesLength) continue nextPackage; for (int j = 0; j < namesLength; j++) if (!this.names[j].equals(otherNames[j])) continue nextPackage; return true; } return false; } protected boolean internalIsValidPackageName() { // if package fragment refers to folder in another IProject, then // resource().getProject() is different than getJavaProject().getProject() // use the other java project's options to verify the name IJavaProject javaProject = JavaCore.create(resource().getProject()); String sourceLevel = javaProject.getOption(JavaCore.COMPILER_SOURCE, true); String complianceLevel = javaProject.getOption(JavaCore.COMPILER_COMPLIANCE, true); for (int i = 0, length = this.names.length; i < length; i++) { if (!Util.isValidFolderNameForPackage(this.names[i], sourceLevel, complianceLevel)) return false; } return true; }
See Also:
  • isDefaultPackage.isDefaultPackage()
/** * @see IPackageFragment#isDefaultPackage() */
@Override public boolean isDefaultPackage() { return this.names.length == 0; } protected final boolean isValidPackageName() { return this.isValidPackageName; }
See Also:
  • move.move(IJavaElement, IJavaElement, String, boolean, IProgressMonitor)
/** * @see ISourceManipulation#move(IJavaElement, IJavaElement, String, boolean, IProgressMonitor) */
@Override public void move(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor) throws JavaModelException { if (container == null) { throw new IllegalArgumentException(Messages.operation_nullContainer); } IJavaElement[] elements= new IJavaElement[] {this}; IJavaElement[] containers= new IJavaElement[] {container}; IJavaElement[] siblings= null; if (sibling != null) { siblings= new IJavaElement[] {sibling}; } String[] renamings= null; if (rename != null) { renamings= new String[] {rename}; } getJavaModel().move(elements, containers, siblings, renamings, force, monitor); }
See Also:
  • rename.rename(String, boolean, IProgressMonitor)
/** * @see ISourceManipulation#rename(String, boolean, IProgressMonitor) */
@Override public void rename(String newName, boolean force, IProgressMonitor monitor) throws JavaModelException { if (newName == null) { throw new IllegalArgumentException(Messages.element_nullName); } IJavaElement[] elements= new IJavaElement[] {this}; IJavaElement[] dests= new IJavaElement[] {getParent()}; String[] renamings= new String[] {newName}; getJavaModel().rename(elements, dests, renamings, force, monitor); }
Debugging purposes
/** * Debugging purposes */
@Override protected void toStringChildren(int tab, StringBuffer buffer, Object info) { if (tab == 0) { super.toStringChildren(tab, buffer, info); } }
Debugging purposes
/** * Debugging purposes */
@Override protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) { buffer.append(tabString(tab)); if (this.names.length == 0) { buffer.append("<default>"); //$NON-NLS-1$ } else { toStringName(buffer); } if (info == null) { buffer.append(" (not open)"); //$NON-NLS-1$ } else { if (tab > 0) { buffer.append(" (...)"); //$NON-NLS-1$ } } } @Override public String getAttachedJavadoc(IProgressMonitor monitor) throws JavaModelException { PerProjectInfo projectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(getJavaProject().getProject()); String cachedJavadoc = null; synchronized (projectInfo.javadocCache) { cachedJavadoc = (String) projectInfo.javadocCache.get(this); } if (cachedJavadoc != null) { return cachedJavadoc; } URL baseLocation= getJavadocBaseLocation(); if (baseLocation == null) { return null; } StringBuffer pathBuffer = new StringBuffer(baseLocation.toExternalForm()); if (!(pathBuffer.charAt(pathBuffer.length() - 1) == '/')) { pathBuffer.append('/'); } String packPath= getElementName().replace('.', '/'); pathBuffer.append(packPath).append('/').append(JavadocConstants.PACKAGE_FILE_NAME); if (monitor != null && monitor.isCanceled()) throw new OperationCanceledException(); String contents = getURLContents(baseLocation, String.valueOf(pathBuffer)); if (monitor != null && monitor.isCanceled()) throw new OperationCanceledException(); if (contents == null) return null; contents = (new JavadocContents(contents)).getPackageDoc(); if (contents == null) contents = ""; //$NON-NLS-1$ synchronized (projectInfo.javadocCache) { projectInfo.javadocCache.put(this, contents); } return contents; } @Override protected IStatus validateExistence(IResource underlyingResource) { // check that the name of the package is valid (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=108456) if (!isValidPackageName()) return newDoesNotExistStatus(); // check whether this pkg can be opened if (underlyingResource != null && !resourceExists(underlyingResource)) return newDoesNotExistStatus(); // check that it is not excluded (https://bugs.eclipse.org/bugs/show_bug.cgi?id=138577) int kind; try { kind = getKind(); } catch (JavaModelException e) { return e.getStatus(); } if (kind == IPackageFragmentRoot.K_SOURCE && Util.isExcluded(this)) return newDoesNotExistStatus(); return JavaModelStatus.VERIFIED_OK; } }