mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Gaetan Boismal
21.46.2016 3e2a1649d693d7b6d09d238c082dd5aae542775f
OPENDJ-2941 Fix extension listing in tools

Use the directory server install and instance path to compute the
extensions path.
Before the fix, extensions were listed only if the tool was run from the
opendj instance root.

Make the extension information computation static since there is no
adherence with a ConfigurationFramework instance.
2 files modified
257 ■■■■ changed files
opendj-config/src/main/java/org/forgerock/opendj/config/ConfigurationFramework.java 251 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java 6 ●●●●● patch | view | raw | blame | history
opendj-config/src/main/java/org/forgerock/opendj/config/ConfigurationFramework.java
@@ -143,6 +143,134 @@
        return INSTANCE;
    }
    /**
     * Prints out all information about extensions.
     *
     * @param installPath
     *            The path where application binaries are located.
     * @param instancePath
     *            The path where application data are located.
     *
     * @return A string representing all information about extensions;
     *         <code>null</code> if there is no information available.
     */
    public static String printExtensionInformation(final String installPath, final String instancePath) {
        final File extensionsPath = buildExtensionPath(installPath);
        final List<File> extensions = new ArrayList<>();
        if (extensionsPath.exists() && extensionsPath.isDirectory()) {
            extensions.addAll(listFiles(extensionsPath));
        }
        File instanceExtensionsPath = buildExtensionPath(instancePath);
        if (!extensionsPath.getAbsolutePath().equals(instanceExtensionsPath.getAbsolutePath())) {
            extensions.addAll(listFiles(instanceExtensionsPath));
        }
        if (extensions.isEmpty()) {
            return null;
        }
        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
        final PrintStream ps = new PrintStream(baos);
        // prints:
        // --
        // Name Build number Revision number
        ps.printf("--%s           %-20s %-20s %-20s%s", EOL, "Name", "Build number",
                  "Revision number", EOL);
        for (final File extension : extensions) {
            printExtensionDetails(ps, extension);
        }
        return baos.toString();
    }
    private static File buildExtensionPath(String directory)  {
        File libDir = new File(directory, LIB_DIR);
        try {
            return new File(libDir, EXTENSIONS_DIR).getCanonicalFile();
        } catch (Exception e) {
            return new File(libDir, EXTENSIONS_DIR);
        }
    }
    private static List<File> listFiles(File path) {
        if (path.exists() && path.isDirectory()) {
            return Arrays.asList(path.listFiles(new FileFilter() {
                @Override
                public boolean accept(File pathname) {
                    // only files with names ending with ".jar"
                    return pathname.isFile() && pathname.getName().endsWith(".jar");
                }
            }));
        }
        return Collections.emptyList();
    }
    private static void printExtensionDetails(PrintStream ps, File extension) {
        // retrieve MANIFEST entry and display name, build number and revision number
        try (JarFile jarFile = new JarFile(extension)) {
            JarEntry entry = jarFile.getJarEntry(MANIFEST_RELATIVE_PATH);
            if (entry == null) {
                return;
            }
            String[] information = getBuildInformation(jarFile);
            ps.append("Extension: ");
            boolean addBlank = false;
            for (String name : information) {
                if (addBlank) {
                    ps.append(" ");
                } else {
                    addBlank = true;
                }
                ps.printf("%-20s", name);
            }
            ps.append(EOL);
        } catch (Exception e) {
            // ignore extra information for this extension
        }
    }
    /**
     * Returns a String array with the following information : <br>
     * index 0: the name of the extension. <br>
     * index 1: the build number of the extension. <br>
     * index 2: the revision number of the extension.
     *
     * @param extension
     *            the jar file of the extension
     * @return a String array containing the name, the build number and the revision number
     *            of the extension given in argument
     * @throws java.io.IOException
     *             thrown if the jar file has been closed.
     */
    private static String[] getBuildInformation(final JarFile extension) throws IOException {
        final String[] result = new String[3];
        // retrieve MANIFEST entry and display name, version and revision
        final Manifest manifest = extension.getManifest();
        if (manifest != null) {
            final Attributes attributes = manifest.getMainAttributes();
            int index = 0;
            for (final String name : BUILD_INFORMATION_ATTRIBUTE_NAMES) {
                String value = attributes.getValue(name);
                if (value == null) {
                    value = "<unknown>";
                }
                result[index++] = value;
            }
        }
        return result;
    }
    /** Set of registered Jar files. */
    private Set<File> jarFiles = new HashSet<>();
@@ -287,71 +415,6 @@
    }
    /**
     * Prints out all information about extensions.
     *
     * @return A string representing all information about extensions;
     *         <code>null</code> if there is no information available.
     */
    public String printExtensionInformation() {
        final File extensionsPath = buildExtensionPath(installPath);
        final List<File> extensions = new ArrayList<>();
        if (extensionsPath.exists() && extensionsPath.isDirectory()) {
            extensions.addAll(listFiles(extensionsPath));
        }
        File instanceExtensionsPath = buildExtensionPath(instancePath);
        if (!extensionsPath.getAbsolutePath().equals(instanceExtensionsPath.getAbsolutePath())) {
            extensions.addAll(listFiles(instanceExtensionsPath));
        }
        if (extensions.isEmpty()) {
            return null;
        }
        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
        final PrintStream ps = new PrintStream(baos);
        // prints:
        // --
        // Name Build number Revision number
        ps.printf("--%s           %-20s %-20s %-20s%s", EOL, "Name", "Build number",
            "Revision number", EOL);
        for (final File extension : extensions) {
            printExtensionDetails(ps, extension);
        }
        return baos.toString();
    }
    private void printExtensionDetails(PrintStream ps, File extension) {
        // retrieve MANIFEST entry and display name, build number and revision number
        try (JarFile jarFile = new JarFile(extension)) {
            JarEntry entry = jarFile.getJarEntry(MANIFEST_RELATIVE_PATH);
            if (entry == null) {
                return;
            }
            String[] information = getBuildInformation(jarFile);
            ps.append("Extension: ");
            boolean addBlank = false;
            for (String name : information) {
                if (addBlank) {
                    ps.append(" ");
                } else {
                    addBlank = true;
                }
                ps.printf("%-20s", name);
            }
            ps.append(EOL);
        } catch (Exception e) {
            // ignore extra information for this extension
        }
    }
    /**
     * Reloads the configuration framework.
     *
     * @throws ConfigException
@@ -418,41 +481,6 @@
        }
    }
    /**
     * Returns a String array with the following information : <br>
     * index 0: the name of the extension. <br>
     * index 1: the build number of the extension. <br>
     * index 2: the revision number of the extension.
     *
     * @param extension
     *            the jar file of the extension
     * @return a String array containing the name, the build number and the revision number
     *            of the extension given in argument
     * @throws java.io.IOException
     *             thrown if the jar file has been closed.
     */
    private String[] getBuildInformation(final JarFile extension) throws IOException {
        final String[] result = new String[3];
        // retrieve MANIFEST entry and display name, version and revision
        final Manifest manifest = extension.getManifest();
        if (manifest != null) {
            final Attributes attributes = manifest.getMainAttributes();
            int index = 0;
            for (final String name : BUILD_INFORMATION_ATTRIBUTE_NAMES) {
                String value = attributes.getValue(name);
                if (value == null) {
                    value = "<unknown>";
                }
                result[index++] = value;
            }
        }
        return result;
    }
    private void initialize0() throws ConfigException {
        if (parent != null) {
            loader = new MyURLClassLoader(parent);
@@ -477,15 +505,6 @@
        }
    }
    private File buildExtensionPath(String directory)  {
        File libDir = new File(directory, LIB_DIR);
        try {
            return new File(libDir, EXTENSIONS_DIR).getCanonicalFile();
        } catch (Exception e) {
            return new File(libDir, EXTENSIONS_DIR);
        }
    }
    /**
     * Put extensions jars into the class loader and load all configuration
     * definition classes in that they contain.
@@ -523,20 +542,6 @@
        }
    }
    private List<File> listFiles(File path) {
        if (path.exists() && path.isDirectory()) {
            return Arrays.asList(path.listFiles(new FileFilter() {
                @Override
                public boolean accept(File pathname) {
                    // only files with names ending with ".jar"
                    return pathname.isFile() && pathname.getName().endsWith(".jar");
                }
            }));
        }
        return Collections.emptyList();
    }
    /**
     * Make sure all core configuration definitions are loaded.
     *
opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java
@@ -5575,8 +5575,7 @@
    outputStream.write(PRINTABLE_VERSION_STRING.getBytes());
    // Print extensions' extra information
    String extensionInformation =
         ConfigurationFramework.getInstance().printExtensionInformation();
    String extensionInformation = ConfigurationFramework.printExtensionInformation(getServerRoot(), getInstanceRoot());
    if ( extensionInformation != null ) {
      outputStream.write(extensionInformation.getBytes());
    }
@@ -6505,8 +6504,7 @@
    System.out.println(SetupUtils.BUILD_JVM_VENDOR+separator+BUILD_JVM_VENDOR);
    // Print extensions' extra information
    String extensionInformation =
                  ConfigurationFramework.getInstance().printExtensionInformation();
    String extensionInformation = ConfigurationFramework.printExtensionInformation(getServerRoot(), getInstanceRoot());
    if ( extensionInformation != null ) {
      System.out.print(extensionInformation);
    }