From e1fc6e590de8875550dcbb521272f45a5c139611 Mon Sep 17 00:00:00 2001
From: Nicolas Capponi <nicolas.capponi@forgerock.com>
Date: Fri, 03 Jan 2014 17:07:38 +0000
Subject: [PATCH] Script to automate code replacement using regular expressions.

---
 opendj-sdk/opendj3-server-dev/replace.rb |  261 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 261 insertions(+), 0 deletions(-)

diff --git a/opendj-sdk/opendj3-server-dev/replace.rb b/opendj-sdk/opendj3-server-dev/replace.rb
new file mode 100755
index 0000000..6edfef5
--- /dev/null
+++ b/opendj-sdk/opendj3-server-dev/replace.rb
@@ -0,0 +1,261 @@
+#!/usr/bin/env ruby
+
+require 'fileutils'
+
+#
+# Automate code replacements using regular expressions
+#
+# To define a new replacement, add a new constant like VALIDATOR.
+#
+# It should be a ruby Hash with three mandatory keys and one optional key:
+#
+#  :dirs => a list of directory to run replacements. All subdirs are processed.
+#  :extensions => a list of file extensions. Only file with these extensions are processed.
+#  :replacements => a list of replacements, lines are processed 2 by 2
+#    - first line gives the pattern to replace, as a ruby regexp (see http://rubular.com/ for help and tool)
+#    - second line gives the replacement string, using \1, \2, ... to insert matching groups. This is a string,
+#       use simple quote if no special char is inserted, or use double quote if using special char like \n
+#    Don't forget to put a comma at end of each line, this is the array element separator.
+#    It is ok to leave a new line to separate each pair of line for readability.
+#    It is ok to use a comment in the array (use # as first non blank character of line).
+#
+# The optional key is :stopwords => a list of stopword. If any word in this list appears in a file name, the file
+#   is not processed. Use it to exclude some files or directory that must not be processed.
+#
+# Once you have define your replacement, add the constant in REPLACEMENTS array. it will be taken into account when
+# running the program (run it at root of project) with command: ./replace.rb
+#
+class Replace
+
+  # All directories that contains java code
+  JAVA_DIRS = ["src/server", "src/quicksetup", "src/ads", "src/guitools", "tests/unit-tests-testng/src"]
+
+  # Replacement for Validator
+  # Modify 88 files, for a total of 227 replacements - leaves 21 compilation errors
+  VALIDATOR = {
+    :dirs => JAVA_DIRS,
+    :extensions => ["java"],
+    :replacements =>
+      [
+        /import org.opends.server.util.\*;/,
+        "import org.opends.server.util.*;\nimport org.forgerock.util.Reject;",
+
+        /import static org.opends.server.util.Validator.ensureNotNull;/,
+        'import static org.forgerock.util.Reject.ifNull;',
+
+        /import static org.opends.server.util.Validator.ensureTrue;/,
+        'import static org.forgerock.util.Reject.ifFalse;',
+
+        /import static org.opends.server.util.Validator.\*;/,
+        'import static org.forgerock.util.Reject.*;',
+
+        /import org.opends.server.util.Validator;/,
+        'import org.forgerock.util.Reject;',
+
+        /(Validator\.| )ensureNotNull\((.*)$/,
+        '\1ifNull(\2',
+
+        /(Validator\.| )ensureTrue\((.*)$/,
+        '\1ifFalse(\2',
+
+        / Validator\./,
+        ' Reject.'
+      ]
+  }
+
+  # Replacement for messages
+  # Modify 1052 files, for a total of 2366 replacements - leaves 10274 compilation errors mostly due to generated messages
+  MESSAGES = {
+    :dirs => JAVA_DIRS,
+    :extensions => ["java"],
+    :replacements =>
+      [
+        /import org.opends.messages.Message;/,
+        'import org.forgerock.i18n.LocalizableMessage;',
+
+        /([ <(])Message([ >)(.]|$)/,
+        '\1LocalizableMessage\2',
+
+        /import org.opends.messages.MessageBuilder;/,
+        'import org.forgerock.i18n.LocalizableMessageBuilder;',
+
+        /([ <(])MessageBuilder([ >)(.]|$)/,
+        '\1LocalizableMessageBuilder\2'
+      ]
+  }
+
+  # Replacement for types
+  # Modify 688 files, for a total of 783 replacements - leaves 7605 compilation errors
+  TYPES = {
+    :dirs => JAVA_DIRS,
+    :extensions => ["java"],
+    :replacements =>
+      [
+        /import org.opends.server.types.(DN|RDN|Attribute|ByteString|Entry|ResultCode);/,
+        'import org.forgerock.opendj.ldap.\1;',
+
+        /import org.opends.server.(types|api).(AttributeType|MatchingRule);/,
+        'import org.forgerock.opendj.ldap.schema.\2;',
+
+      ]
+  }
+
+  # Replacement for exceptions
+  # Modify 36 files, for a total of 134 replacements - leaves 1277 compilation errors but mostly from generated config
+  EXCEPTIONS = {
+    :dirs => JAVA_DIRS,
+    :extensions => ["java"],
+    :replacements =>
+      [
+        /import org.opends.server.admin.client.AuthorizationException;/,
+        'import org.forgerock.opendj.ldap.ErrorResultException;',
+
+        /\bAuthorizationException\b/,
+        'ErrorResultException',
+
+        /import org.opends.server.admin.client.CommunicationException;\n/,
+        '',
+
+        /throws CommunicationException\b, /,
+        'throws ',
+
+        /, CommunicationException\b(, )?/,
+        '\1',
+
+        /\bCommunicationException\b/,
+        'ErrorResultException',
+      ]
+  }
+
+  # Replacement for loggers
+  # Modify 454 files, for a total of 2427 replacements - leaves 72 compilation errors
+  # TODO: add I18N loggers
+  LOGGERS = {
+    :dirs => JAVA_DIRS,
+    :stopwords => ['src/server/org/opends/server/loggers', 'DebugLogPublisher'],
+    :extensions => ["java"],
+    :replacements =>
+      [
+        /import org.opends.server.loggers.debug.DebugTracer;/,
+        "import org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;",
+
+        /import java.util.logging.Logger;/,
+        "import org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;",
+
+        /import java.util.logging.Level;\n/,
+        '',
+
+        /import org.opends.server.types.DebugLogLevel;\n/,
+        '',
+
+        /import (static )?org.opends.server.loggers.debug.DebugLogger.*;\n/,
+        '',
+
+        /DebugTracer TRACER = (DebugLogger.)?getTracer\(\)/,
+        "Logger debugLogger = LoggerFactory.getLogger({CLASSNAME}.class)",
+
+        /^\s*\/\*\*\n.*The tracer object for the debug logger.\n\s*\*\/$\n/,
+        '',
+
+        /^\s*\/\/\s*The tracer object for the debug logger.$\n/,
+        '',
+
+        /if \(debugEnabled\(\)\)\s*{\s* TRACER.debugCaught\(DebugLogLevel.ERROR, (\b.*\b)\);\s*\n\s*}$/,
+        'debugLogger.trace("Error", \1);',
+
+        /TRACER\.debugCaught\(DebugLogLevel.ERROR, (\b.*\b)\);/,
+        'debugLogger.trace("Error", \1);',
+
+        /TRACER.debug[^(]+\(/,
+        'debugLogger.trace(',
+
+        /debugLogger.trace\(DebugLogLevel.\b\w+\b, ?/,
+        'debugLogger.trace(',
+
+        /debugLogger.trace\(e\)/,
+        'debugLogger.trace("Error", e)',
+
+        /(DebugLogger\.|\b)debugEnabled\(\)/,
+        'debugLogger.isTraceEnabled()',
+
+        /(LOG|logger).log\((Level.)?WARNING, ?/,
+        '\1.warn(',
+
+        /(LOG|logger).log\((Level.)?CONFIG, ?/,
+        '\1.info(',
+
+        /(LOG|logger).log\((Level.)?INFO, ?/,
+        '\1.debug(',
+
+        /(LOG|logger).log\((Level.)?SEVERE, ?/,
+        '\1.error(',
+
+        /(LOG|logger).log\((Level.)?FINE, ?/,
+        '\1.trace(',
+
+        /Logger.getLogger\((\n\s+)?(\b\w+\b).class.getName\(\)\);/,
+        'LoggerFactory.getLogger(\2.class);',
+      ]
+  }
+
+  # List of replacements to run
+  REPLACEMENTS = [ VALIDATOR ]
+  #REPLACEMENTS = [ VALIDATOR, MESSAGES, TYPES, EXCEPTIONS, LOGGERS ]
+
+  # Run replacements
+  def run
+    REPLACEMENTS.each { |repl|
+      puts "Replacing " + Replace.constants.find{ |name| Replace.const_get(name)==repl }.to_s
+      stopwords = repl[:stopwords] || ["--nostopword--"]
+      replace_dirs(repl[:replacements], repl[:dirs], stopwords, repl[:extensions])
+    }
+  end
+
+  def replace_dirs(replacements, dirs, stopwords, extensions)
+    count_files = 0
+    count_total = 0
+    dirs.each { |directory|
+      files = files_under_directory(directory, extensions)
+      files.each { |file|
+        exclude_file = stopwords.any? { |stopword| file.include?(stopword) }
+        next if exclude_file
+        count = replace_file(file, replacements)
+        if count > 0
+          count_files += 1
+          count_total += count
+        end
+      }
+    }
+    puts "Replaced in #{count_files} files, for a total of #{count_total} replacements"
+  end
+
+  def replace_file(file, replacements)
+    count = 0
+    File.open(file) { |source|
+      contents = source.read
+      (0..replacements.size-1).step(2).each { |index|
+        pattern, replace = replacements[index], replacements[index+1]
+        replace = replace.gsub('{CLASSNAME}', classname(file))
+        is_replaced = contents.gsub!(pattern, replace)
+        if is_replaced then count += 1 end
+      }
+      File.open(file + ".copy", "w+") { |f| f.write(contents) }
+    }
+    FileUtils.mv(file + ".copy", file, :verbose => false)
+    count
+  end
+
+  def classname(file)
+    name = file.gsub(/.*\/(.*).java$/, '\1')
+    if name.nil? then '' else name end
+  end
+
+  def files_under_directory(directory, extensions)
+    Dir[directory + '/**/*.{' + extensions.join(",") + '}']
+  end
+
+end
+
+# Launch replacement
+Replace.new.run
+

--
Gitblit v1.10.0