Bug 534624: [9] Support module-info.java in multi-release JAR files

Moving back to ZipFile instead of java.nio file system.

Change-Id: Ib9f8dcbc5f9c9b1bf6c42d12adda6f67165a9adf
Signed-off-by: jay <jarthana@in.ibm.com>
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NameLookupTests2.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NameLookupTests2.java
index 9ace2d8..bdcf342 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NameLookupTests2.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NameLookupTests2.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2016 IBM Corporation and others.
+ * Copyright (c) 2000, 2018 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
@@ -410,7 +410,7 @@
 		assertFalse("The invalid archive cache should no longer report the jar as invalid",
 				!JavaModelManager.getJavaModelManager().getArchiveValidity(transitioningIPath).isValid());
 		type = getNameLookup(proj).findType("test1.IResource", false, NameLookup.ACCEPT_CLASSES);
-		assertTrue("Name lookup should be able to find types in the valid jar", type == null);
+		assertFalse("Name lookup should be able to find types in the valid jar", type == null);
 	} finally {
 		Files.deleteIfExists(transitioningJarPath);
 		deleteProject("P");
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java
index 66360c2..a38d4a4 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java
@@ -10,20 +10,10 @@
  *******************************************************************************/
 package org.eclipse.jdt.internal.core;
 
-import java.io.File;
 import java.io.IOException;
-import java.net.URI;
 import java.net.URL;
-import java.nio.file.FileSystemNotFoundException;
-import java.nio.file.FileSystems;
-import java.nio.file.FileVisitResult;
-import java.nio.file.FileVisitor;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.ProviderNotFoundException;
-import java.nio.file.attribute.BasicFileAttributes;
 import java.util.ArrayList;
+import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -79,8 +69,6 @@
 	boolean knownToBeModuleLess;
 
 	private boolean multiVersion;
-	
-	private int sync_count = 0;
 
 	/**
 	 * Constructs a package fragment root which is the root of the Java package directory hierarchy
@@ -110,7 +98,6 @@
 		final HashtableOfArrayToObject rawPackageInfo = new HashtableOfArrayToObject();
 		final Map<String, String> overridden = new HashMap<>();
 		IJavaElement[] children = NO_ELEMENTS;
-		java.nio.file.FileSystem fs = null;
 		try {
 			// always create the default package
 			rawPackageInfo.put(CharOperation.NO_STRINGS, new ArrayList[] { EMPTY_LIST, EMPTY_LIST });
@@ -145,137 +132,62 @@
 			// If we weren't able to compute the set of children from the index (either the index was disabled or didn't
 			// contain an up-to-date entry for this .jar) then fetch it directly from the .jar
 			if (!usedIndex) {
-				IPath path = getPath();
-				Object target = JavaModel.getTarget(path, true);
-				File localFile = JavaModelManager.getLocalFile(path);
-				long classLevel = Util.getJdkLevel(target);
+				Object file = JavaModel.getTarget(getPath(), true);
+				long classLevel = Util.getJdkLevel(file);
 				String projectCompliance = this.getJavaProject().getOption(JavaCore.COMPILER_COMPLIANCE, true);
-				Path filePath = Paths.get(localFile.getAbsolutePath().toString());
-				URI uri = URI.create("jar:" + filePath.toUri());  //$NON-NLS-1$
+				long projectLevel = CompilerOptions.versionToJdkLevel(projectCompliance);
+				ZipFile jar = null;
 				try {
-					synchronized (this) {
-						this.sync_count++;
-						try {
-							fs = FileSystems.getFileSystem(uri);
-						}
-						catch (FileSystemNotFoundException e) {
-							// move on
-						}
-						if (fs == null) {
-							HashMap<String, ?> env = new HashMap<>();
-							fs = FileSystems.newFileSystem(uri, env);
-						}
-					}
-					if (fs != null) {
-						Path rootPath = fs.getPath("/"); //$NON-NLS-1$
-						Path versionsPath = fs.getPath("/", "META-INF", "versions");  //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
+					jar = getJar();
+					String version = "META-INF/versions/";  //$NON-NLS-1$
+					List<String> versions = new ArrayList<>();
+					if (projectLevel >= ClassFileConstants.JDK9 && jar.getEntry(version) != null) {
 						int earliestJavaVersion = ClassFileConstants.MAJOR_VERSION_9;
 						long latestJDK = CompilerOptions.releaseToJDKLevel(projectCompliance);
 						int latestJavaVer = (int) (latestJDK >> 16);
-						List<Path> versions = new ArrayList<>();
+
 						for(int i = latestJavaVer; i >= earliestJavaVersion; i--) {
-							Path p = fs.getPath("/", "META-INF", "versions", "" + (i - 44));  //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
-							if (Files.exists(p)) {
-								versions.add(p);
+							String s = "" + + (i - 44); //$NON-NLS-1$
+							String versionPath = version + s;
+							if (jar.getEntry(versionPath) != null) {
+								versions.add(s);
 							}
 						}
-						Path[] supportedVersions = versions.toArray(new Path[versions.size()]);
-						if (supportedVersions.length > 0) {
-							this.multiVersion = true;
-						}
-						try {
-							for (Path pa : supportedVersions) {
-								Files.walkFileTree(pa, new FileVisitor<java.nio.file.Path>() {
-									@Override
-									public FileVisitResult preVisitDirectory(java.nio.file.Path dir, BasicFileAttributes attrs)
-											throws IOException {
-										return FileVisitResult.CONTINUE;
-									}
-									@Override
-									public FileVisitResult visitFile(java.nio.file.Path file, BasicFileAttributes attrs)
-											throws IOException {
-										String fileName = file.getFileName().toString();
-										if (!overridden.containsKey(fileName)) {
-											overridden.put(fileName, rootPath.relativize(pa).toString());
-										}
-										initRawPackageInfo(rawPackageInfo, pa.relativize(file).toString(), false, CompilerOptions.versionFromJdkLevel(classLevel));
-										return FileVisitResult.CONTINUE;
-									}
-
-									@Override
-									public FileVisitResult visitFileFailed(java.nio.file.Path file, IOException exc) throws IOException {
-										return FileVisitResult.CONTINUE;
-									}
-
-									@Override
-									public FileVisitResult postVisitDirectory(java.nio.file.Path dir, IOException exc)
-											throws IOException {
-										return FileVisitResult.CONTINUE;
-									}
-								});
-							}
-							Files.walkFileTree(rootPath, new FileVisitor<java.nio.file.Path>() {
-								@Override
-								public FileVisitResult preVisitDirectory(java.nio.file.Path dir, BasicFileAttributes attrs)
-										throws IOException {
-									if (dir.equals(versionsPath)) {
-										return FileVisitResult.SKIP_SUBTREE;
-									}
-									return FileVisitResult.CONTINUE;
-								}
-								@Override
-								public FileVisitResult visitFile(java.nio.file.Path file, BasicFileAttributes attrs)
-										throws IOException {
-									initRawPackageInfo(rawPackageInfo, rootPath.relativize(file).toString(), false, CompilerOptions.versionFromJdkLevel(classLevel));
-									return FileVisitResult.CONTINUE;
-								}
-
-								@Override
-								public FileVisitResult visitFileFailed(java.nio.file.Path file, IOException exc) throws IOException {
-									return FileVisitResult.CONTINUE;
-								}
-
-								@Override
-								public FileVisitResult postVisitDirectory(java.nio.file.Path dir, IOException exc)
-										throws IOException {
-									return FileVisitResult.CONTINUE;
-								}
-							});
-							// loop through all of referenced packages, creating package fragments if necessary
-							// and cache the entry names in the rawPackageInfo table
-							children = new IJavaElement[rawPackageInfo.size()];
-							int index = 0;
-							for (int i = 0, length = rawPackageInfo.keyTable.length; i < length; i++) {
-								String[] pkgName = (String[]) rawPackageInfo.keyTable[i];
-								if (pkgName == null) continue;
-								children[index++] = getPackageFragment(pkgName);
-							}
-						} catch (IOException e) {
-							Util.log(IStatus.ERROR, "Error reading archive: " + toStringWithAncestors()); //$NON-NLS-1$
-						}
 					}
-				} catch (FileSystemNotFoundException fse) {
-					Util.log(IStatus.ERROR, "Error reading archive: " + toStringWithAncestors()); //$NON-NLS-1$
-					children = NO_ELEMENTS;
-				} catch (ProviderNotFoundException e) {
-					Util.log(IStatus.ERROR, "Provider not found: " + toStringWithAncestors()); //$NON-NLS-1$
-					children = NO_ELEMENTS;
-				} catch (IOException e) {
-					Util.log(IStatus.ERROR, "Error reading archive: " + toStringWithAncestors()); //$NON-NLS-1$
-					children = NO_ELEMENTS;
+					
+					String[] supportedVersions = versions.toArray(new String[versions.size()]);
+					if (supportedVersions.length > 0) {
+						this.multiVersion = true;
+					}
+					int length = version.length();
+					for (Enumeration<? extends ZipEntry> e= jar.entries(); e.hasMoreElements();) {
+						ZipEntry member= e.nextElement();
+						String name = member.getName();
+						if (this.multiVersion && name.length() > (length + 2) && name.startsWith(version)) {
+							int end = name.indexOf('/', length);
+							if (end >= name.length()) continue;
+							String versionPath = name.substring(0, end);
+							String ver = name.substring(length, end);
+							if(versions.contains(ver) && org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(name)) {
+								name = name.substring(end + 1);
+								overridden.put(name, versionPath);
+							}
+						}
+						initRawPackageInfo(rawPackageInfo, name, member.isDirectory(), CompilerOptions.versionFromJdkLevel(classLevel));
+					}
 				}  finally {
-					synchronized (this) {
-						if (fs != null) {
-							try {
-								if (--this.sync_count == 0)
-									fs.close();
-							} catch (IOException e) {
-								Util.log(IStatus.ERROR, "Error reading archive: " + toStringWithAncestors()); //$NON-NLS-1$
-							}
-						}
-					}
+					JavaModelManager.getJavaModelManager().closeZipFile(jar);
 				}
 			}
+			// loop through all of referenced packages, creating package fragments if necessary
+			// and cache the entry names in the rawPackageInfo table
+			children = new IJavaElement[rawPackageInfo.size()];
+			int index = 0;
+			for (int i = 0, length = rawPackageInfo.keyTable.length; i < length; i++) {
+				String[] pkgName = (String[]) rawPackageInfo.keyTable[i];
+				if (pkgName == null) continue;
+				children[index++] = getPackageFragment(pkgName);
+			}
 		} catch (CoreException e) {
 			if (e.getCause() instanceof ZipException) {
 				// not a ZIP archive, leave the children empty
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathMultiReleaseJar.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathMultiReleaseJar.java
index 234f9e5..9b03ee6 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathMultiReleaseJar.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathMultiReleaseJar.java
@@ -75,7 +75,6 @@
 			ClassFileReader classfile = null;
 			try {
 				for (Path path : this.supportedVersions) {
-					System.out.println(path.toString());
 					classfile = ClassFileReader.read(file, path.toString() + '/' + IModule.MODULE_INFO_CLASS);
 					if (classfile != null)
 						break;