From b2f1fd1e7766af2f99d1bf94d64a581cd34e7cbe Mon Sep 17 00:00:00 2001
From: Nicolas Capponi <nicolas.capponi@forgerock.com>
Date: Thu, 05 Feb 2015 13:20:04 +0000
Subject: [PATCH] OPENDJ-1741 Add maven plugin to concatenate schema LDIF files

---
 opendj-sdk/opendj-concat-schema-maven-plugin/src/main/java/org/forgerock/maven/ConcatSchemaMojo.java |  259 +++++++++++++++++++++++++++++++++++++++++++
 opendj-sdk/opendj-concat-schema-maven-plugin/pom.xml                                                 |   38 ++++++
 opendj-sdk/opendj-concat-schema-maven-plugin/src/main/java/org/forgerock/maven/package-info.java     |   29 ++++
 3 files changed, 326 insertions(+), 0 deletions(-)

diff --git a/opendj-sdk/opendj-concat-schema-maven-plugin/pom.xml b/opendj-sdk/opendj-concat-schema-maven-plugin/pom.xml
new file mode 100644
index 0000000..2132876
--- /dev/null
+++ b/opendj-sdk/opendj-concat-schema-maven-plugin/pom.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+  xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>opendj-project</artifactId>
+    <groupId>org.forgerock.opendj</groupId>
+    <version>3.0.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>opendj-concat-schema-maven-plugin</artifactId>
+  <version>1.0.0-SNAPSHOT</version>
+  <name>OpenDJ Concat Schema Maven Plugin</name>
+  <description>
+    Generation of schema file by concatenation of LDIF files.
+  </description>
+  <packaging>maven-plugin</packaging>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.twdata.maven</groupId>
+      <artifactId>mojo-executor</artifactId>
+      <version>2.2.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-plugin-api</artifactId>
+      <version>2.0</version>
+    </dependency>
+    <!-- dependencies to annotations -->
+    <dependency>
+      <groupId>org.apache.maven.plugin-tools</groupId>
+      <artifactId>maven-plugin-annotations</artifactId>
+      <version>3.4</version>
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/opendj-sdk/opendj-concat-schema-maven-plugin/src/main/java/org/forgerock/maven/ConcatSchemaMojo.java b/opendj-sdk/opendj-concat-schema-maven-plugin/src/main/java/org/forgerock/maven/ConcatSchemaMojo.java
new file mode 100644
index 0000000..405c9cf
--- /dev/null
+++ b/opendj-sdk/opendj-concat-schema-maven-plugin/src/main/java/org/forgerock/maven/ConcatSchemaMojo.java
@@ -0,0 +1,259 @@
+/*
+ * 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.maven;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.TreeSet;
+
+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.apache.maven.project.MavenProject;
+
+/**
+ * Concatenates the contents of the files in the schema directory to create a
+ * base schema that may be used during the upgrade process. Each element will
+ * also include the X-SCHEMA-FILE extension to indicate the source schema file.
+ * <p>
+ * There is a single goal that generates the base schema.
+ * <p>
+ *
+ * @Checkstyle:ignoreFor 3
+ */
+@Mojo(name="concat", defaultPhase=LifecyclePhase.GENERATE_SOURCES)
+public final class ConcatSchemaMojo extends AbstractMojo {
+
+    /**
+     * The Maven Project.
+     */
+    @Parameter(property="project", required=true, readonly=true)
+    private MavenProject project;
+
+    /**
+     * The path to the directory containing the schema files.
+     */
+    @Parameter(required=true, defaultValue="${basedir}/resource/schema")
+    private String schemaDirectory;
+
+    /**
+     * The directory path of the concatenated schema file to create.
+     * Must be in ${project.build.directory}
+     */
+    @Parameter(required=true)
+    private String outputDirectory;
+
+    /**
+     * The file name of the concatenated schema file to create.
+     */
+    @Parameter(required=true)
+    private String outputFile;
+
+
+    /** {@inheritDoc} */
+    public void execute() throws MojoExecutionException, MojoFailureException
+    {
+      String projectBuildDir = project.getBuild().getDirectory();
+      String outputFilePath = outputDirectory + System.getProperty("file.separator") + outputFile;
+
+      if (!outputDirectory.contains(projectBuildDir))
+      {
+        String errorMsg = String.format("outputDirectory parameter (%s) must be included "
+            + "in ${project.build.directory} (%s)", outputDirectory, projectBuildDir);
+        getLog().error(errorMsg);
+        throw new MojoExecutionException(errorMsg);
+      }
+      getLog().info(String.format("Concatenating all ldif files from directory: %s", schemaDirectory));
+      getLog().info(String.format("Concatenated file: %s", outputFilePath));
+
+      new File(outputFilePath).getParentFile().mkdirs();
+
+      // Get a sorted list of the files in the schema directory.
+      TreeSet<String> schemaFileNames = new TreeSet<String>();
+      for (File f : new File(schemaDirectory).listFiles())
+      {
+        if (f.isFile())
+        {
+          schemaFileNames.add(f.getName());
+        }
+      }
+
+
+      // Create a set of lists that will hold the schema elements read from the
+      // files.
+      LinkedList<String> attributeTypes    = new LinkedList<String>();
+      LinkedList<String> objectClasses     = new LinkedList<String>();
+      LinkedList<String> nameForms         = new LinkedList<String>();
+      LinkedList<String> ditContentRules   = new LinkedList<String>();
+      LinkedList<String> ditStructureRules = new LinkedList<String>();
+      LinkedList<String> matchingRuleUses  = new LinkedList<String>();
+      LinkedList<String> ldapSyntaxes      = new LinkedList<String>();
+      int curLineNumber = 0;
+
+      // Open each of the files in order and read the elements that they contain,
+      // appending them to the appropriate lists.
+      for (String name : schemaFileNames)
+      {
+        // Read the contents of the file into a list with one schema element per
+        // list element.
+        LinkedList<StringBuilder> lines = new LinkedList<StringBuilder>();
+        try
+        {
+          BufferedReader reader = new BufferedReader(new FileReader(
+                                           new File(schemaDirectory, name)));
+          String line = reader.readLine();
+          while (line != null)
+          {
+            curLineNumber++;
+            if (line.length() > 0 && !line.startsWith("#"))
+            {
+              if (line.startsWith(" "))
+              {
+                lines.getLast().append(line.substring(1));
+              }
+              else
+              {
+                lines.add(new StringBuilder(line));
+              }
+            }
+            line = reader.readLine();
+          }
+          reader.close();
+        }
+        catch (Exception e)
+        {
+            getLog().error(String.format(
+                "Error while reading schema file %s at line %d: %s", name, curLineNumber, e.getMessage()));
+            throw new MojoExecutionException(e.getMessage());
+        }
+
+
+        // Iterate through each line in the list.  Find the colon and get the
+        // attribute name at the beginning.  If it's someting that we don't
+        // recognize, then skip it.  Otherwise, add the X-SCHEMA-FILE extension
+        // and add it to the appropriate schema element list.
+        for (StringBuilder buffer : lines)
+        {
+          // Get the line and add the X-SCHEMA-FILE extension to the end of it.
+          // All of them should end with " )" but some might have the parenthesis
+          // crammed up against the last character so deal with that as well.
+          String line = buffer.toString().trim();
+          if (line.endsWith(" )"))
+          {
+           line = line.substring(0, line.length() - 1) + "X-SCHEMA-FILE '" + name + "' )";
+          }
+          else if (line.endsWith(")"))
+          {
+           line = line.substring(0, line.length() - 1) + " X-SCHEMA-FILE '" + name + "' )";
+          }
+          else
+          {
+            continue;
+          }
+
+          String lowerLine = line.toLowerCase();
+          if (lowerLine.startsWith("attributetypes:"))
+          {
+            attributeTypes.add(line);
+          }
+          else if (lowerLine.startsWith("objectclasses:"))
+          {
+            objectClasses.add(line);
+          }
+          else if (lowerLine.startsWith("nameforms:"))
+          {
+            nameForms.add(line);
+          }
+          else if (lowerLine.startsWith("ditcontentrules:"))
+          {
+            ditContentRules.add(line);
+          }
+          else if (lowerLine.startsWith("ditstructurerules:"))
+          {
+            ditStructureRules.add(line);
+          }
+          else if (lowerLine.startsWith("matchingruleuse:"))
+          {
+            matchingRuleUses.add(line);
+          }
+          else if (lowerLine.startsWith("ldapsyntaxes:"))
+          {
+            ldapSyntaxes.add(line);
+          }
+        }
+      }
+
+
+      // Write the resulting output to the merged schema file.
+      try
+      {
+        BufferedWriter writer = new BufferedWriter(new FileWriter(outputFilePath));
+        writer.write("dn: cn=schema");
+        writer.newLine();
+        writer.write("objectClass: top");
+        writer.newLine();
+        writer.write("objectClass: ldapSubentry");
+        writer.newLine();
+        writer.write("objectClass: subschema");
+        writer.newLine();
+
+        writeSchemaElements(ldapSyntaxes, writer);
+        writeSchemaElements(attributeTypes, writer);
+        writeSchemaElements(objectClasses, writer);
+        writeSchemaElements(nameForms, writer);
+        writeSchemaElements(ditContentRules, writer);
+        writeSchemaElements(ditStructureRules, writer);
+        writeSchemaElements(matchingRuleUses, writer);
+
+        writer.close();
+      }
+      catch (Exception e)
+      {
+        getLog().error(String.format(
+            "Error while writing concatenated schema file %s:  %s", outputFile, e.getMessage()));
+        throw new MojoExecutionException(e.getMessage());
+      }
+    }
+
+
+
+    private void writeSchemaElements(LinkedList<String> schemaElements, BufferedWriter writer) throws IOException {
+        for (String line : schemaElements)
+        {
+          writer.write(line);
+          writer.newLine();
+        }
+    }
+
+}
diff --git a/opendj-sdk/opendj-concat-schema-maven-plugin/src/main/java/org/forgerock/maven/package-info.java b/opendj-sdk/opendj-concat-schema-maven-plugin/src/main/java/org/forgerock/maven/package-info.java
new file mode 100644
index 0000000..7840667
--- /dev/null
+++ b/opendj-sdk/opendj-concat-schema-maven-plugin/src/main/java/org/forgerock/maven/package-info.java
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+/** Classes implementing the maven plugin to create a base schema that may be used during the upgrade process. */
+package org.forgerock.maven;
+

--
Gitblit v1.10.0