Bug 546649 - [9][model] API to get exports and opens from an
IModuleDescription

Change-Id: I09fcaa4cc94e96ef6d54cff3717f6fc69c4d82e7
Signed-off-by: Stephan Herrmann <stephan.herrmann@berlin.de>
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IModuleDescription.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IModuleDescription.java
index ebda6d8..5455e73 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IModuleDescription.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IModuleDescription.java
@@ -54,7 +54,27 @@
 	 * @since 3.18
 	 */
 	String[] getUsedServiceNames() throws JavaModelException;
-	
+
+	/**
+	 * Get names of exported packages.
+	 *
+	 * @param targetModule filter the result to include only packages exported to the given module, unless {@code null}.
+	 * @return a non-null array of exported package names
+	 * @throws JavaModelException
+	 * @since 3.18
+	 */
+	String[] getExportedPackageNames(IModuleDescription targetModule) throws JavaModelException;
+
+	/**
+	 * Get names of opened packages.
+	 *
+	 * @param targetModule filter the result to include only packages opened to the given module, unless {@code null}.
+	 * @return a non-null array of opened package names
+	 * @throws JavaModelException
+	 * @since 3.18
+	 */
+	String[] getOpenedPackageNames(IModuleDescription targetModule) throws JavaModelException;
+
 	/**
 	 * 
 	 * @return true if automatic module, else false
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/AbstractModule.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/AbstractModule.java
index 761778f..b95f900 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/AbstractModule.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/AbstractModule.java
@@ -15,11 +15,13 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 
 import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.IModuleDescription;
 import org.eclipse.jdt.core.ITypeRoot;
 import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.compiler.env.IModule;
 import org.eclipse.jdt.internal.compiler.env.IModule.IModuleReference;
 import org.eclipse.jdt.internal.compiler.env.IModule.IPackageExport;
@@ -80,6 +82,38 @@
 	default IModule getModuleInfo() throws JavaModelException {
 		return (IModule) getElementInfo();
 	}
+	@Override
+	default String[] getExportedPackageNames(IModuleDescription targetModule) throws JavaModelException {
+		IModule info = getModuleInfo();
+		if (info != null) {
+			List<String> result = new ArrayList<>();
+			for (IPackageExport packageExport : info.exports()) {
+				if (targetModule == null || !packageExport.isQualified()
+						|| CharOperation.containsEqual(packageExport.targets(), targetModule.getElementName().toCharArray()))
+				{
+					result.add(new String(packageExport.name()));
+				}
+			}
+			return result.toArray(new String[result.size()]);
+		}
+		return new String[0];
+	}
+	@Override
+	default String[] getOpenedPackageNames(IModuleDescription targetModule) throws JavaModelException {
+		IModule info = getModuleInfo();
+		if (info != null) {
+			List<String> result = new ArrayList<>();
+			for (IPackageExport packageOpen : info.opens()) {
+				if (targetModule == null || !packageOpen.isQualified()
+						|| CharOperation.containsEqual(packageOpen.targets(), targetModule.getElementName().toCharArray()))
+				{
+					result.add(new String(packageOpen.name()));
+				}
+			}
+			return result.toArray(new String[result.size()]);
+		}
+		return new String[0];
+	}
 	default IModuleReference[] getRequiredModules() throws JavaModelException {
 		return getModuleInfo().requires();
 	}