From b4f8838b15342670c31753a484abf0129e3c9653 Mon Sep 17 00:00:00 2001
From: jcduff <jcduff@localhost>
Date: Thu, 23 Oct 2008 14:04:24 +0000
Subject: [PATCH] The commit will bring the following features :     - An updated version of the underlying database. BDB JE 3.3 is now used.     - Attribute API refactoring providing a better abstraction and offering improved performances.     - A new GUI called the Control-Panel to replace the Status-Panel: the specifications for this       GUI are available on OpenDS Wiki and contains a link to a mockup.        See <https://www.opends.org/wiki/page/ControlPanelUISpecification>.     - Some changes in the replication protocol to implement "Assured Replication Mode". The        specifications are on OpenDS Wiki at <https://www.opends.org/wiki/page/AssuredMode> and section 7       described some of the replication changes required to support this. Assured Replication is not finished,       but the main replication protocol changes to support it are done. As explained by Gilles on an email on       the Dev mailing list (http://markmail.org/message/46rgo3meq3vriy4a), with these changes the newer versions       of OpenDS may not be able to replicate with OpenDS 1.0 instances.     - Support for Service Tags on the platforms where the functionality is available and enabled. Specifications       are published at <https://www.opends.org/wiki/page/OpenDSServiceTagEnabled>. For more information on       Service Tags see <http://wikis.sun.com/display/ServiceTag/Sun+Service+Tag+FAQ>.     - The Admin Connector service. In order to provide agentry of the OpenDS server at any time, a new service       has been added, dedicated to the administration, configuration and monitoring of the server.       An overview of the Admin Connector service and it's use is available on the       OpenDS wiki <https://www.opends.org/wiki/page/ManagingAdministrationTrafficToTheServer>     - Updates to the various command line tools to support the Admin Connector service.     - Some internal re-architecting of the server to put the foundation of future developments such as virtual       directory services. The new NetworkGroups and WorkFlow internal services which have been specified in       <https://www.opends.org/wiki/page/BasicOperationRoutingThroughNetworkGroup> are now implemented.     - Many bug fixes...

---
 opendj-sdk/opends/src/server/org/opends/server/admin/ClassLoaderProvider.java |  133 ++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 133 insertions(+), 0 deletions(-)

diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/ClassLoaderProvider.java b/opendj-sdk/opends/src/server/org/opends/server/admin/ClassLoaderProvider.java
index 078ed0c..dd640cf 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/ClassLoaderProvider.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/ClassLoaderProvider.java
@@ -29,16 +29,20 @@
 
 
 import static org.opends.messages.AdminMessages.*;
+import static org.opends.messages.ExtensionMessages.*;
 import static org.opends.server.loggers.ErrorLogger.*;
 import static org.opends.server.loggers.debug.DebugLogger.*;
 import static org.opends.server.util.StaticUtils.*;
+import static org.opends.server.util.ServerConstants.EOL;
 
+import java.io.ByteArrayOutputStream;
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileFilter;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.io.PrintStream;
 import java.lang.reflect.Method;
 import java.net.MalformedURLException;
 import java.net.URL;
@@ -48,8 +52,10 @@
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
+import java.util.jar.Attributes;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
+import java.util.jar.Manifest;
 
 import org.opends.messages.Message;
 import org.opends.server.admin.std.meta.RootCfgDefn;
@@ -147,6 +153,15 @@
   // The singleton instance.
   private static final ClassLoaderProvider INSTANCE = new ClassLoaderProvider();
 
+  // Attribute name in jar's MANIFEST corresponding to the revision number.
+  private static final String REVISION_NUMBER = "Revision-Number";
+
+  // The attribute names for build information is name, version and revision
+  // number
+  private static final String[] BUILD_INFORMATION_ATTRIBUTE_NAMES =
+                 new String[]{Attributes.Name.EXTENSION_NAME.toString(),
+                              Attributes.Name.IMPLEMENTATION_VERSION.toString(),
+                              REVISION_NUMBER};
 
 
   /**
@@ -385,6 +400,112 @@
 
 
   /**
+   * Prints out all information about extensions.
+   *
+   * @return a String instance representing all information about extensions;
+   *         <code>null</code> if there is no information available.
+   */
+  public String printExtensionInformation() {
+    File extensionsPath =
+            new File(new StringBuilder(DirectoryServer.getServerRoot()).
+                                append(File.separator).
+                                append(LIB_DIR).
+                                append(File.separator).
+                                append(EXTENSIONS_DIR).
+                                toString());
+
+    if (!extensionsPath.exists() || !extensionsPath.isDirectory()) {
+      // no extensions' directory
+      return null;
+    }
+
+    File[] extensions = extensionsPath.listFiles(new FileFilter(){
+      public boolean accept(File pathname) {
+        // only files with names ending with ".jar"
+        return pathname.isFile() && pathname.getName().endsWith(".jar");
+      }
+    });
+
+    if ( extensions.length == 0 ) {
+      return null;
+    }
+
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    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(File extension : extensions) {
+      // retrieve MANIFEST entry and display name, build number and revision
+      // number
+      try {
+        String[] information = getBuildInformation(new JarFile(extension));
+
+        ps.append("Extension: ");
+        boolean addBlank = false;
+        for(String name : information) {
+          if ( addBlank ) {
+            ps.append(addBlank ? " " : ""); // add blank if not first append
+          } else {
+            addBlank = true;
+          }
+
+          ps.printf("%-20s", name);
+        }
+        ps.append(EOL);
+      } catch(Exception e) {
+        // ignore extra information for this extension
+      }
+    }
+
+    return baos.toString();
+  }
+
+
+
+  /**
+   * 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(JarFile extension) throws IOException {
+    String[] result = new String[3];
+
+    // retrieve MANIFEST entry and display name, version and revision
+    Manifest manifest = extension.getManifest();
+
+    if ( manifest != null ) {
+      Attributes attributes = manifest.getMainAttributes();
+
+      int index = 0;
+      for(String name : BUILD_INFORMATION_ATTRIBUTE_NAMES) {
+        String value = attributes.getValue(name);
+        if ( value == null ) {
+          value = "<unknown>";
+        }
+        result[index++] = value;
+      }
+    }
+
+    return result;
+  }
+
+
+
+  /**
    * Put extensions jars into the class loader and load all
    * configuration definition classes in that they contain.
    *
@@ -529,6 +650,18 @@
             .getName(), EXTENSION_MANIFEST, stackTraceToSingleLineString(e));
         throw new InitializationException(message);
       }
+      try {
+        // Log build information of extensions in the error log
+        String[] information = getBuildInformation(jarFile);
+        logError(
+          INFO_LOG_EXTENSION_INFORMATION.
+            get(jarFile.getName().replace(DirectoryServer.getServerRoot(),
+                                          "$SERVER_ROOT"),
+                information[1],
+                information[2]));
+      } catch(Exception e) {
+        // Do not log information for that extension
+      }
     }
   }
 

--
Gitblit v1.10.0