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