From 82213581b317d297f66ce52b4925f6b1963cf3d5 Mon Sep 17 00:00:00 2001
From: Mark Craig <mark.craig@forgerock.com>
Date: Fri, 29 May 2015 15:53:23 +0000
Subject: [PATCH] CR-7098 OPENDJ-2009 Result codes in logs should be explained

---
 opendj-sdk/src/main/docbkx/dev-guide/index.xml                                                                 |    8 
 opendj-sdk/opendj-doc-maven-plugin/pom.xml                                                                     |    5 
 opendj-sdk/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/GenerateResultCodeDocMojo.java |  184 ++++++++++++++++++++
 opendj-sdk/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/GenerateSchemaDocMojo.java     |   79 --------
 opendj-sdk/pom.xml                                                                                             |   20 ++
 opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ResultCode.java                                 |    6 
 opendj-sdk/opendj-server-legacy/pom.xml                                                                        |   12 +
 opendj-sdk/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/Utils.java                     |   79 ++++++++
 opendj-sdk/opendj-server-legacy/src/main/docbkx/reference/index.xml                                            |    8 
 opendj-sdk/opendj-doc-maven-plugin/src/main/resources/templates/appendix-ldap-result-codes.ftl                 |   82 +++++++++
 10 files changed, 400 insertions(+), 83 deletions(-)

diff --git a/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ResultCode.java b/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ResultCode.java
index b9de4c0..d72c6fa 100644
--- a/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ResultCode.java
+++ b/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/ResultCode.java
@@ -196,9 +196,6 @@
 
     private static final Map<Integer, ResultCode> ELEMENTS = new LinkedHashMap<>();
 
-    private static final List<ResultCode> IMMUTABLE_ELEMENTS = Collections.unmodifiableList(new ArrayList<ResultCode>(
-            ELEMENTS.values()));
-
     /**
      * The result code that should only be used if the actual result code has
      * not yet been determined.
@@ -867,6 +864,9 @@
         return result;
     }
 
+    private static final List<ResultCode> IMMUTABLE_ELEMENTS = Collections.unmodifiableList(new ArrayList<ResultCode>(
+            ELEMENTS.values()));
+
     /**
      * Returns an unmodifiable list containing the set of available result codes
      * indexed on their integer value as defined in RFC 4511 section 4.1.9.
diff --git a/opendj-sdk/opendj-doc-maven-plugin/pom.xml b/opendj-sdk/opendj-doc-maven-plugin/pom.xml
index c443c62..5ebc2b9 100644
--- a/opendj-sdk/opendj-doc-maven-plugin/pom.xml
+++ b/opendj-sdk/opendj-doc-maven-plugin/pom.xml
@@ -66,6 +66,11 @@
       <version>2.2.0</version>
     </dependency>
     <dependency>
+      <groupId>com.thoughtworks.qdox</groupId>
+      <artifactId>qdox</artifactId>
+      <version>2.0-M3</version>
+    </dependency>
+    <dependency>
       <groupId>org.apache.maven.plugin-tools</groupId>
       <artifactId>maven-plugin-annotations</artifactId>
       <version>3.2</version>
diff --git a/opendj-sdk/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/GenerateResultCodeDocMojo.java b/opendj-sdk/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/GenerateResultCodeDocMojo.java
new file mode 100644
index 0000000..134a053
--- /dev/null
+++ b/opendj-sdk/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/GenerateResultCodeDocMojo.java
@@ -0,0 +1,184 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at legal-notices/CDDLv1_0.txt.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2015 ForgeRock AS.
+ */
+package org.forgerock.opendj.maven.doc;
+
+import static org.forgerock.opendj.maven.doc.Utils.*;
+
+import com.thoughtworks.qdox.JavaProjectBuilder;
+import com.thoughtworks.qdox.model.JavaClass;
+import com.thoughtworks.qdox.model.JavaField;
+import com.thoughtworks.qdox.model.JavaType;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.forgerock.opendj.ldap.ResultCode;
+
+import java.io.File;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Generates documentation source for LDAP result codes based on
+ * {@code org.forgerock.opendj.ldap.ResultCode}.
+ * <br>
+ * This implementation parses the source to match Javadoc comments with result codes.
+ * It is assumed that the class's ResultCode fields are named with result code enum values,
+ * and that those fields have Javadoc comments describing each result code.
+ */
+@Mojo(name = "generate-result-code-doc", defaultPhase = LifecyclePhase.COMPILE)
+public class GenerateResultCodeDocMojo extends AbstractMojo {
+    /**
+     * The Java file containing the source of the ResultCode class,
+     * {@code org.forgerock.opendj.ldap.ResultCode}.
+     * <br>
+     * For example, {@code opendj-core/src/main/java/org/forgerock/opendj/ldap/ResultCode.java}.
+     */
+    @Parameter(required = true)
+    private File resultCodeSource;
+
+    /** The XML file to generate. */
+    @Parameter(required = true)
+    private File xmlFile;
+
+    /**
+     * Generates documentation source for LDAP result codes.
+     *
+     * @throws MojoExecutionException   Generation failed
+     * @throws MojoFailureException     Not used
+     */
+    @Override
+    public void execute() throws MojoExecutionException, MojoFailureException {
+        final Map<String, Object> map = new HashMap<>();
+        map.put("year", new SimpleDateFormat("yyyy").format(new Date()));
+
+        // The overall explanation in the generated doc is the class comment.
+        final JavaClass resultCodeClass;
+        try {
+            resultCodeClass = getJavaClass();
+        } catch (IOException e) {
+            throw new MojoExecutionException("Could not read " + resultCodeSource.getPath(), e);
+        }
+        map.put("classComment", cleanComment(resultCodeClass.getComment()));
+
+        // Documentation for each result code comes from the Javadoc for the code,
+        // and from the value and friendly name of the code.
+        final Map<String, Object> comments = new HashMap<>();
+        for (final JavaField field : resultCodeClass.getFields()) {
+            final JavaType type = field.getType();
+            if (type.getValue().equals("ResultCode")) {
+                comments.put(field.getName(), cleanComment(field.getComment()));
+            }
+        }
+        map.put("resultCodes", getResultCodesDoc(comments));
+
+        final String template = "appendix-ldap-result-codes.ftl";
+        try {
+            writeStringToFile(applyTemplate(template, map), xmlFile);
+        } catch (IOException e) {
+            throw new MojoExecutionException("Could not write to " + xmlFile.getPath(), e);
+        }
+        getLog().info("Wrote " + xmlFile.getPath());
+    }
+
+    /**
+     * Returns an object to access to the result code Java source.
+     * @return An object to access to the result code Java source.
+     * @throws IOException  Could not read the source
+     */
+    private JavaClass getJavaClass() throws IOException {
+        final JavaProjectBuilder builder = new JavaProjectBuilder();
+        builder.addSource(resultCodeSource);
+        return builder.getClassByName("org.forgerock.opendj.ldap.ResultCode");
+    }
+
+    /**
+     * Returns a clean string for use in generated documentation.
+     * @param comment   The comment to clean.
+     * @return A clean string for use in generated documentation.
+     */
+    private String cleanComment(String comment) {
+        return stripCodeValueSentences(stripTags(convertLineSeparators(comment))).trim();
+    }
+
+    /**
+     * Returns a string with line separators converted to spaces.
+     * @param string    The string to convert.
+     * @return A string with line separators converted to spaces.
+     */
+    private String convertLineSeparators(String string) {
+        return string.replaceAll(System.lineSeparator(), " ");
+    }
+
+    /**
+     * Returns a string with the HTML tags removed.
+     * @param string    The string to strip.
+     * @return A string with the HTML tags removed.
+     */
+    private String stripTags(String string) {
+        return string.replaceAll("<[^>]*>", "");
+    }
+
+    /**
+     * Returns a string with lines sentences of the following form removed:
+     * This result code corresponds to the LDAP result code value of &#x7b;&#x40;code 0&#x7d;.
+     * @param string    The string to strip.
+     * @return A string with lines sentences of the matching form removed.
+     */
+    private String stripCodeValueSentences(String string) {
+        return string
+                .replaceAll("This result code corresponds to the LDAP result code value of \\{@code \\d+\\}.", "");
+    }
+
+    /**
+     * Returns a list of documentation objects for all result codes.
+     * @param comments  A map of field names to the clean comments.
+     * @return A list of documentation objects for all result codes.
+     */
+    private List<Map<String, Object>> getResultCodesDoc(Map<String, Object> comments) {
+        final List<Map<String, Object>> list = new LinkedList<>();
+        if (comments == null || comments.isEmpty()) {
+            return list;
+        }
+
+        for (ResultCode resultCode : ResultCode.values()) {
+            final Map<String, Object> doc = new HashMap<>();
+            doc.put("intValue", resultCode.intValue());
+            doc.put("name", resultCode.getName());
+            final Object comment = comments.get(resultCode.asEnum().toString());
+            doc.put("comment", comment);
+            list.add(doc);
+        }
+        return list;
+    }
+}
diff --git a/opendj-sdk/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/GenerateSchemaDocMojo.java b/opendj-sdk/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/GenerateSchemaDocMojo.java
index 3cb48fb..a5b8195 100644
--- a/opendj-sdk/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/GenerateSchemaDocMojo.java
+++ b/opendj-sdk/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/GenerateSchemaDocMojo.java
@@ -25,10 +25,8 @@
 package org.forgerock.opendj.maven.doc;
 
 import static com.forgerock.opendj.ldap.CoreMessages.*;
+import static org.forgerock.opendj.maven.doc.Utils.*;
 
-import freemarker.template.Configuration;
-import freemarker.template.Template;
-import freemarker.template.TemplateExceptionHandler;
 import org.apache.maven.plugin.AbstractMojo;
 import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugin.MojoFailureException;
@@ -36,13 +34,8 @@
 import org.apache.maven.plugins.annotations.Parameter;
 import org.forgerock.opendj.ldap.schema.CoreSchemaSupportedLocales;
 
-import java.io.ByteArrayOutputStream;
 import java.io.File;
-import java.io.FileNotFoundException;
 import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.io.Writer;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.HashMap;
@@ -77,12 +70,9 @@
         final String localeReference = getLocalesAndSubTypesDocumentation(currentLocale);
         final File localeReferenceFile = new File(outputDirectory, "sec-locales-subtypes.xml");
         try {
-            createOutputDirectory();
             writeStringToFile(localeReference, localeReferenceFile);
-        } catch (FileNotFoundException e) {
-            throw new MojoFailureException("Failed to write doc reference file.", e);
         } catch (IOException e) {
-            throw new MojoExecutionException("Failed to create output directory");
+            throw new MojoExecutionException("Failed to write " + localeReferenceFile.getPath());
         }
     }
 
@@ -102,74 +92,9 @@
         return applyTemplate("sec-locales-subtypes.ftl", map);
     }
 
-    /**
-     * Create the output directory if it does not exist.
-     * @throws IOException  Failed to create the directory.
-     */
-    private void createOutputDirectory() throws IOException {
-        if (outputDirectory != null && !outputDirectory.exists()) {
-            if (!outputDirectory.mkdirs()) {
-                throw new IOException("Failed to create output directory.");
-            }
-        }
-    }
-
-    /**
-     * Writes a string to a file.
-     * @param string    The string to write.
-     * @param file      The file to write to.
-     * @throws FileNotFoundException The file did not exist, or could not be created for writing.
-     */
-    private void writeStringToFile(final String string, final File file) throws FileNotFoundException {
-        PrintWriter printWriter = new PrintWriter(file);
-        printWriter.print(string);
-        printWriter.close();
-    }
-
     private final Map<String, String> localeTagsToOids =
             CoreSchemaSupportedLocales.getJvmSupportedLocaleNamesToOids();
 
-    /** FreeMarker template configuration. */
-    private Configuration configuration;
-
-    /**
-     * Returns a FreeMarker configuration for applying templates.
-     * @return A FreeMarker configuration for applying templates.
-     */
-    private Configuration getConfiguration() {
-        if (configuration == null) {
-            configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
-            configuration.setClassForTemplateLoading(GenerateSchemaDocMojo.class, "/templates");
-            configuration.setDefaultEncoding("UTF-8");
-            configuration.setTemplateExceptionHandler(TemplateExceptionHandler.DEBUG_HANDLER);
-        }
-        return configuration;
-    }
-
-    /**
-     * Returns the String result from applying a FreeMarker template.
-     * @param template The name of a template file found in {@code resources/templates/}.
-     * @param map      The map holding the data to use in the template.
-     * @return The String result from applying a FreeMarker template.
-     */
-    private String applyTemplate(final String template, final Map<String, Object> map) {
-        // FreeMarker requires a configuration to find the template.
-        configuration = getConfiguration();
-
-        // FreeMarker takes the data and a Writer to process the template.
-        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-        Writer writer = new OutputStreamWriter(outputStream);
-        try {
-            Template configurationTemplate = configuration.getTemplate(template);
-            configurationTemplate.process(map, writer);
-            return outputStream.toString();
-        } catch (Exception e) {
-            throw new RuntimeException(e.getMessage(), e);
-        } finally {
-            org.forgerock.util.Utils.closeSilently(writer, outputStream);
-        }
-    }
-
     /** Container for documentation regarding a locale. */
     private class LocaleDoc {
         String tag;
diff --git a/opendj-sdk/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/Utils.java b/opendj-sdk/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/Utils.java
index 7d23e0b..4af5529 100644
--- a/opendj-sdk/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/Utils.java
+++ b/opendj-sdk/opendj-doc-maven-plugin/src/main/java/org/forgerock/opendj/maven/doc/Utils.java
@@ -27,16 +27,23 @@
 
 import static org.forgerock.util.Utils.*;
 
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+import freemarker.template.TemplateExceptionHandler;
 import org.apache.maven.artifact.DependencyResolutionRequiredException;
 import org.apache.maven.plugin.logging.Log;
 import org.apache.maven.project.MavenProject;
 
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.Writer;
 import java.net.MalformedURLException;
 import java.net.URISyntaxException;
 import java.net.URL;
@@ -44,6 +51,7 @@
 import java.util.Collections;
 import java.util.LinkedHashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 /**
@@ -96,9 +104,7 @@
         if (original == null) {
             throw new IOException("Could not read input to copy.");
         }
-        if (!copy.exists() && !copy.createNewFile()) {
-            throw new IOException("Failed to create " + copy);
-        }
+        createFile(copy);
         OutputStream outputStream = new FileOutputStream(copy);
         int bytesRead;
         byte[] buffer = new byte[4096];
@@ -108,6 +114,32 @@
         closeSilently(original, outputStream);
     }
 
+    /**
+     * Writes a string to a file.
+     * @param string    The string to write
+     * @param file      The file to write to
+     * @throws IOException  The file did not exist, or could not be created for writing.
+     */
+    static void writeStringToFile(final String string, final File file) throws IOException {
+        createFile(file);
+        PrintWriter printWriter = new PrintWriter(file);
+        printWriter.print(string);
+        printWriter.close();
+    }
+
+    /**
+     * Creates a file including parent directories if it does not yet exist.
+     * @param file          The file to create
+     * @throws IOException  Failed to create the file
+     */
+    private static void createFile(File file) throws IOException {
+        if (!file.exists()) {
+            createDirectory(file.getParent());
+            if (!file.createNewFile()) {
+                throw new IOException("Failed to create " + file.getPath());
+            }
+        }
+    }
 
     /**
      * Returns the classpath for the class loader and its parent.
@@ -171,6 +203,47 @@
         debugClassPathElements(classLoader.getParent(), log);
     }
 
+    /** FreeMarker template configuration. */
+    static Configuration configuration;
+
+    /**
+     * Returns a FreeMarker configuration for applying templates.
+     * @return A FreeMarker configuration for applying templates.
+     */
+    static Configuration getConfiguration() {
+        if (configuration == null) {
+            configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
+            configuration.setClassForTemplateLoading(Utils.class, "/templates");
+            configuration.setDefaultEncoding("UTF-8");
+            configuration.setTemplateExceptionHandler(TemplateExceptionHandler.DEBUG_HANDLER);
+        }
+        return configuration;
+    }
+
+    /**
+     * Returns the String result from applying a FreeMarker template.
+     * @param template The name of a template file found in {@code resources/templates/}.
+     * @param map      The map holding the data to use in the template.
+     * @return The String result from applying a FreeMarker template.
+     */
+    static String applyTemplate(final String template, final Map<String, Object> map) {
+        // FreeMarker requires a configuration to find the template.
+        configuration = getConfiguration();
+
+        // FreeMarker takes the data and a Writer to process the template.
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        Writer writer = new OutputStreamWriter(outputStream);
+        try {
+            Template configurationTemplate = configuration.getTemplate(template);
+            configurationTemplate.process(map, writer);
+            return outputStream.toString();
+        } catch (Exception e) {
+            throw new RuntimeException(e.getMessage(), e);
+        } finally {
+            org.forgerock.util.Utils.closeSilently(writer, outputStream);
+        }
+    }
+
     private Utils() {
         // Not used.
     }
diff --git a/opendj-sdk/opendj-doc-maven-plugin/src/main/resources/templates/appendix-ldap-result-codes.ftl b/opendj-sdk/opendj-doc-maven-plugin/src/main/resources/templates/appendix-ldap-result-codes.ftl
new file mode 100644
index 0000000..dc8c5f0
--- /dev/null
+++ b/opendj-sdk/opendj-doc-maven-plugin/src/main/resources/templates/appendix-ldap-result-codes.ftl
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ! CCPL HEADER START
+  !
+  ! This work is licensed under the Creative Commons
+  ! Attribution-NonCommercial-NoDerivs 3.0 Unported License.
+  ! To view a copy of this license, visit
+  ! http://creativecommons.org/licenses/by-nc-nd/3.0/
+  ! or send a letter to Creative Commons, 444 Castro Street,
+  ! Suite 900, Mountain View, California, 94041, USA.
+  !
+  ! You can also obtain a copy of the license at legal-notices/CC-BY-NC-ND.txt.
+  ! See the License for the specific language governing permissions
+  ! and limitations under the License.
+  !
+  ! If applicable, add the following below this CCPL HEADER, with the fields
+  ! enclosed by brackets "[]" replaced with your own identifying information:
+  !      Portions Copyright [yyyy] [name of copyright owner]
+  !
+  ! CCPL HEADER END
+  !
+  !      Copyright ${year} ForgeRock AS.
+  !
+-->
+<#-- Comment text comes from the Javadoc, so the language is English. -->
+<appendix xml:id="appendix-ldap-result-codes"
+          xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en"
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+          xsi:schemaLocation="http://docbook.org/ns/docbook
+                              http://docbook.org/xml/5.0/xsd/docbook.xsd"
+          xmlns:xlink="http://www.w3.org/1999/xlink">
+ <title>LDAP Result Codes</title>
+
+ <para>
+  ${classComment}
+ </para>
+
+ <indexterm>
+  <primary>LDAP</primary>
+  <secondary>Result codes</secondary>
+ </indexterm>
+
+ <table pgwide="1">
+  <title>OpenDJ LDAP Result Codes</title>
+  <tgroup cols="3">
+   <colspec colnum="1" colwidth="1*" />
+   <colspec colnum="2" colwidth="2*" />
+   <colspec colnum="3" colwidth="3*" />
+
+   <thead>
+    <row>
+     <entry>Result Code</entry>
+     <entry>Name</entry>
+     <entry>Description</entry>
+    </row>
+   </thead>
+
+   <tbody>
+    <#list resultCodes as resultCode>
+    <row valign="top">
+     <entry>
+      <para>
+       ${resultCode.intValue}
+      </para>
+     </entry>
+     <entry>
+      <para>
+       ${resultCode.name}
+      </para>
+     </entry>
+     <entry>
+      <para>
+       ${resultCode.comment}
+      </para>
+     </entry>
+    </row>
+    </#list>
+   </tbody>
+
+  </tgroup>
+ </table>
+</appendix>
diff --git a/opendj-sdk/opendj-server-legacy/pom.xml b/opendj-sdk/opendj-server-legacy/pom.xml
index ea765a2..3baa946 100644
--- a/opendj-sdk/opendj-server-legacy/pom.xml
+++ b/opendj-sdk/opendj-server-legacy/pom.xml
@@ -1950,6 +1950,18 @@
                   </messageFileNames>
                 </configuration>
               </execution>
+
+              <execution>
+                <id>generate-result-code-doc</id>
+                <phase>pre-site</phase>
+                <goals>
+                  <goal>generate-result-code-doc</goal>
+                </goals>
+                <configuration>
+                  <resultCodeSource>../opendj-core/src/main/java/org/forgerock/opendj/ldap/ResultCode.java</resultCodeSource>
+                  <xmlFile>${project.build.directory}/docbkx-sources/reference/appendix-ldap-result-codes.xml</xmlFile>
+                </configuration>
+              </execution>
             </executions>
           </plugin>
 
diff --git a/opendj-sdk/opendj-server-legacy/src/main/docbkx/reference/index.xml b/opendj-sdk/opendj-server-legacy/src/main/docbkx/reference/index.xml
index 57a33a0..49cdad2 100644
--- a/opendj-sdk/opendj-server-legacy/src/main/docbkx/reference/index.xml
+++ b/opendj-sdk/opendj-server-legacy/src/main/docbkx/reference/index.xml
@@ -194,6 +194,14 @@
  <xinclude:include href="../shared/glossary.xml" />
 
  <xinclude:include href="appendix-rest2ldap.xml" />
+ <xinclude:include href="appendix-ldap-result-codes.xml">
+  <xinclude:fallback>
+   <appendix>
+    <title>LDAP Result Codes Missing</title>
+    <para>The generated LDAP result codes appendix is missing.</para>
+   </appendix>
+  </xinclude:fallback>
+ </xinclude:include>
  <xinclude:include href='appendix-file-layout.xml' />
  <xinclude:include href='appendix-ports-used.xml' />
  <xinclude:include href='appendix-standards.xml' />
diff --git a/opendj-sdk/pom.xml b/opendj-sdk/pom.xml
index ed37695..3b069a6 100644
--- a/opendj-sdk/pom.xml
+++ b/opendj-sdk/pom.xml
@@ -196,6 +196,26 @@
       </plugin>
 
       <plugin>
+        <groupId>org.forgerock.opendj</groupId>
+        <artifactId>opendj-doc-maven-plugin</artifactId>
+        <version>${project.version}</version>
+        <inherited>false</inherited>
+        <executions>
+          <execution>
+            <id>generate-result-code-doc</id>
+            <phase>pre-site</phase>
+            <goals>
+              <goal>generate-result-code-doc</goal>
+            </goals>
+            <configuration>
+              <resultCodeSource>opendj-core/src/main/java/org/forgerock/opendj/ldap/ResultCode.java</resultCodeSource>
+              <xmlFile>${project.build.directory}/docbkx-sources/dev-guide/appendix-ldap-result-codes.xml</xmlFile>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+
+      <plugin>
         <groupId>org.forgerock.commons</groupId>
         <artifactId>forgerock-doc-maven-plugin</artifactId>
         <inherited>false</inherited>
diff --git a/opendj-sdk/src/main/docbkx/dev-guide/index.xml b/opendj-sdk/src/main/docbkx/dev-guide/index.xml
index 721ccb3..4f7b965 100644
--- a/opendj-sdk/src/main/docbkx/dev-guide/index.xml
+++ b/opendj-sdk/src/main/docbkx/dev-guide/index.xml
@@ -131,6 +131,14 @@
   </xinclude:include>
  </reference>
 
+ <xinclude:include href="appendix-ldap-result-codes.xml">
+  <xinclude:fallback>
+   <appendix>
+    <title>LDAP Result Codes Missing</title>
+    <para>The generated LDAP result codes appendix is missing.</para>
+   </appendix>
+  </xinclude:fallback>
+ </xinclude:include>
  <xinclude:include href="../shared/glossary.xml" />
 
  <index />

--
Gitblit v1.10.0