### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: model/org/eclipse/jdt/core/IPackageFragment.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IPackageFragment.java,v retrieving revision 1.33 diff -u -r1.33 IPackageFragment.java --- model/org/eclipse/jdt/core/IPackageFragment.java 6 Nov 2006 14:13:47 -0000 1.33 +++ model/org/eclipse/jdt/core/IPackageFragment.java 2 Mar 2007 17:28:31 -0000 @@ -165,6 +165,11 @@ * inclusion/exclusion patterns on the corresponding source classpath entry * are considered non-Java resources and will appear in the result * (possibly in a folder). + *

+ * Since 3.3, if this package fragment is inside an archive, the non-Java resources + * are a tree of {@link IJarEntryResource}s. One can navigate this tree using + * the {@link IJarEntryResource#getChildren()} and + * {@link IJarEntryResource#getParent()} methods. *

* * @exception JavaModelException if this element does not exist or if an Index: model/org/eclipse/jdt/core/IPackageFragmentRoot.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IPackageFragmentRoot.java,v retrieving revision 1.47 diff -u -r1.47 IPackageFragmentRoot.java --- model/org/eclipse/jdt/core/IPackageFragmentRoot.java 29 Mar 2006 03:08:47 -0000 1.47 +++ model/org/eclipse/jdt/core/IPackageFragmentRoot.java 2 Mar 2007 17:28:31 -0000 @@ -270,7 +270,13 @@ * entry are considered non-Java resources and will appear in the result * (possibly in a folder). Thus when a nested source folder is excluded, it will appear * in the non-Java resources of the outer folder. + *

+ * Since 3.3, if this package fragment root is an archive, the non-Java resources + * are a tree of {@link IJarEntryResource}s. One can navigate this tree using + * the {@link IJarEntryResource#getChildren()} and + * {@link IJarEntryResource#getParent()} methods. *

+ * * @return an array of non-Java resources (IFiles, * IFolders, or IStorages if the * package fragment root is in archive) contained in this package Index: model/org/eclipse/jdt/internal/core/JarEntryFile.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarEntryFile.java,v retrieving revision 1.22 diff -u -r1.22 JarEntryFile.java --- model/org/eclipse/jdt/internal/core/JarEntryFile.java 26 Jun 2006 16:43:39 -0000 1.22 +++ model/org/eclipse/jdt/internal/core/JarEntryFile.java 2 Mar 2007 17:28:31 -0000 @@ -19,15 +19,18 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.PlatformObject; +import org.eclipse.jdt.core.IJarEntryResource; import org.eclipse.jdt.core.IJavaModelStatusConstants; import org.eclipse.jdt.core.JavaModelException; /** - * A jar entry that represents a non-java resource found in a JAR. + * A jar entry that represents a non-java file found in a JAR. * * @see IStorage */ -public class JarEntryFile extends PlatformObject implements IStorage { +public class JarEntryFile extends PlatformObject implements IJarEntryResource { + private static final IJarEntryResource[] NO_CHILDREN = new IJarEntryResource[0]; + private Object parent; private String entryName; private String zipName; private IPath path; @@ -53,6 +56,9 @@ throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION); } } +public IJarEntryResource[] getChildren() { + return NO_CHILDREN; +} /** * @see IStorage#getFullPath */ @@ -65,12 +71,21 @@ public String getName() { return this.path.lastSegment(); } +public Object getParent() { + return this.parent; +} +public boolean isFile() { + return true; +} /** * @see IStorage#isReadOnly() */ public boolean isReadOnly() { return true; } +public void setParent(Object parent) { + this.parent = parent; +} /** * @see IStorage#isReadOnly() */ Index: model/org/eclipse/jdt/internal/core/JarPackageFragment.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragment.java,v retrieving revision 1.33 diff -u -r1.33 JarPackageFragment.java --- model/org/eclipse/jdt/internal/core/JarPackageFragment.java 26 Jun 2006 16:43:39 -0000 1.33 +++ model/org/eclipse/jdt/internal/core/JarPackageFragment.java 2 Mar 2007 17:28:31 -0000 @@ -13,6 +13,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; +import java.util.Map; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IPath; @@ -20,6 +21,7 @@ import org.eclipse.core.runtime.Path; import org.eclipse.jdt.core.IClassFile; import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJarEntryResource; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaModelStatusConstants; import org.eclipse.jdt.core.JavaModelException; @@ -61,7 +63,7 @@ /** * Compute all the non-java resources according to the entry name found in the jar file. */ -/* package */ void computeNonJavaResources(String[] resNames, JarPackageFragmentInfo info, String zipName) { +/* package */ void computeNonJavaResources(String[] resNames, JarPackageFragment pkg, JarPackageFragmentInfo info, String zipName) { if (resNames == null) { info.setNonJavaResources(null); return; @@ -70,19 +72,65 @@ if (max == 0) { info.setNonJavaResources(JavaElementInfo.NO_NON_JAVA_RESOURCES); } else { - Object[] res = new Object[max]; - int index = 0; + HashMap jarEntries = new HashMap(); // map from IPath to IJarEntryResource + HashMap childrenMap = new HashMap(); // map from IPath to ArrayList + ArrayList topJarEntries = new ArrayList(); for (int i = 0; i < max; i++) { String resName = resNames[i]; // consider that a .java file is not a non-java resource (see bug 12246 Packages view shows .class and .java files when JAR has source) if (!Util.isJavaLikeFileName(resName)) { - IPath parentRelativePath = new Path(resName).removeFirstSegments(this.names.length); - res[index++] = new JarEntryFile(resName, zipName, parentRelativePath); + IPath childPath = new Path(resName).removeFirstSegments(this.names.length); + JarEntryFile file = new JarEntryFile(resName, zipName, childPath); + jarEntries.put(childPath, file); + if (childPath.segmentCount() == 1) { + file.setParent(pkg); + topJarEntries.add(file); + } else { + IPath parentPath = childPath.removeLastSegments(1); + while (parentPath.segmentCount() > 0) { + ArrayList parentChildren = (ArrayList) childrenMap.get(parentPath); + if (parentChildren == null) { + Object dir = new JarEntryDirectory(parentPath); + jarEntries.put(parentPath, dir); + childrenMap.put(parentPath, parentChildren = new ArrayList()); + parentChildren.add(childPath); + if (parentPath.segmentCount() == 1) { + topJarEntries.add(dir); + break; + } + childPath = parentPath; + parentPath = childPath.removeLastSegments(1); + } else { + parentChildren.add(childPath); + break; // all parents are already registered + } + } + } } - } - if (index != max) { - System.arraycopy(res, 0, res = new Object[index], 0, index); } + Iterator entries = childrenMap.entrySet().iterator(); + while (entries.hasNext()) { + Map.Entry entry = (Map.Entry) entries.next(); + IPath entryPath = (IPath) entry.getKey(); + ArrayList entryValue = (ArrayList) entry.getValue(); + JarEntryDirectory jarEntryDirectory = (JarEntryDirectory) jarEntries.get(entryPath); + int size = entryValue.size(); + IJarEntryResource[] children = new IJarEntryResource[size]; + for (int i = 0; i < size; i++) { + Object child = jarEntries.get(entryValue.get(i)); + if (child instanceof JarEntryFile) { + ((JarEntryFile) child).setParent(jarEntryDirectory); + } else { + ((JarEntryDirectory) child).setParent(jarEntryDirectory); + } + children[i] = (IJarEntryResource) child; + } + jarEntryDirectory.setChildren(children); + if (entryPath.segmentCount() == 1) { + jarEntryDirectory.setParent(pkg); + } + } + Object[] res = topJarEntries.toArray(new Object[topJarEntries.size()]); info.setNonJavaResources(res); } } Index: model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java,v retrieving revision 1.63 diff -u -r1.63 JarPackageFragmentRoot.java --- model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java 6 Nov 2006 14:13:45 -0000 1.63 +++ model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java 2 Mar 2007 17:28:31 -0000 @@ -98,11 +98,11 @@ JarPackageFragmentInfo fragInfo= new JarPackageFragmentInfo(); int resLength= entries[NON_JAVA].size(); if (resLength == 0) { - packFrag.computeNonJavaResources(CharOperation.NO_STRINGS, fragInfo, jar.getName()); + packFrag.computeNonJavaResources(CharOperation.NO_STRINGS, packFrag, fragInfo, jar.getName()); } else { String[] resNames= new String[resLength]; entries[NON_JAVA].toArray(resNames); - packFrag.computeNonJavaResources(resNames, fragInfo, jar.getName()); + packFrag.computeNonJavaResources(resNames, packFrag, fragInfo, jar.getName()); } packFrag.computeChildren(fragInfo, entries[JAVA]); newElements.put(packFrag, fragInfo); Index: model/org/eclipse/jdt/core/IJarEntryResource.java =================================================================== RCS file: model/org/eclipse/jdt/core/IJarEntryResource.java diff -N model/org/eclipse/jdt/core/IJarEntryResource.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ model/org/eclipse/jdt/core/IJarEntryResource.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.core; + +import org.eclipse.core.resources.IStorage; + +/** + * A jar entry corresponding to a non-Java resource in an archive {@link IPackageFragment}. + * + * @since 3.3 + */ +public interface IJarEntryResource extends IStorage { + + /** + * Returns the list of children of this jar entry resource. + * Returns an empty array if this jar entry is a file, or if this jar entry is a directory and it has no children. + * + * @return the children of this jar entry resource + */ + IJarEntryResource[] getChildren(); + + /** + * Returns the parent of this jar entry resource. This is either an {@link IJarEntryResource} or an {@link IPackageFragment}. + * + * @return the parent of this jar entry resource + */ + Object getParent(); + + /** + * Returns true if this jar entry represents a file. + * Returns false if it is a directory. + * + * @return whether this jar entry is a file + */ + boolean isFile(); + +} Index: model/org/eclipse/jdt/internal/core/JarEntryDirectory.java =================================================================== RCS file: model/org/eclipse/jdt/internal/core/JarEntryDirectory.java diff -N model/org/eclipse/jdt/internal/core/JarEntryDirectory.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ model/org/eclipse/jdt/internal/core/JarEntryDirectory.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.core; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.PlatformObject; +import org.eclipse.jdt.core.IJarEntryResource; + +public class JarEntryDirectory extends PlatformObject implements IJarEntryResource { + private Object parent; + private IPath path; + private IJarEntryResource[] children; + + public JarEntryDirectory(IPath parentRelativePath) { + this.path = parentRelativePath; + } + + public IJarEntryResource[] getChildren() { + return this.children; + } + + public InputStream getContents() throws CoreException { + return new ByteArrayInputStream(new byte[0]); + } + + public IPath getFullPath() { + return this.path; + } + + public String getName() { + return this.path.lastSegment(); + } + + public Object getParent() { + return this.parent; + } + + public boolean isFile() { + return false; + } + + public boolean isReadOnly() { + return true; + } + + public void setChildren(IJarEntryResource[] children) { + this.children = children; + } + + public void setParent(Object parent) { + this.parent = parent; + } + + public String toString() { + return "JarEntryDirectory["+this.path+"]"; //$NON-NLS-1$ //$NON-NLS-2$ + } +} #P org.eclipse.jdt.core.tests.model Index: src/org/eclipse/jdt/core/tests/model/JavaProjectTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaProjectTests.java,v retrieving revision 1.77 diff -u -r1.77 JavaProjectTests.java --- src/org/eclipse/jdt/core/tests/model/JavaProjectTests.java 23 Feb 2007 15:26:01 -0000 1.77 +++ src/org/eclipse/jdt/core/tests/model/JavaProjectTests.java 2 Mar 2007 17:28:33 -0000 @@ -760,7 +760,7 @@ Object[] resources = pkg.getNonJavaResources(); assertResourcesEqual( "Unexpected resources", - "x.y/Test.txt", + "x.y", resources); } @@ -862,7 +862,7 @@ resources = root.getNonJavaResources(); assertResourceNamesEqual( "unexpected non java resoures (test case 4)", - "MANIFEST.MF", + "META-INF", resources); } /**