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 two optional key.
#
# The mandatory keys are:
#
# :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 keys are:
#
# :whitelist => a list of mandatory words. If any word in this list appears in a file name, the file
# is processed, otherwise it is ignored. Use it to explicitely indicates files to process.
#
# :stoplist => a list of stop words. 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.
#
# Note that if you use both whitelist and stoplist, a word in stoplist can prevent processing a file even if it
# matches the whitelist content.
#
# 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
#
# All directories that contains java code
# Replacement for syntaxes
SYNTAXES_TO_SDK = {
:replacements =>
[
/import org.opends.server.api.\*;/,
"Syntax",
"Syntax",
/\bSyntax\b<\w*>/,
"Syntax",
/\bSyntax\b<\?>/,
"Syntax",
]
}
:dirs => JAVA_DIRS,
:replacements =>
[
'Syntax \1;',
/\w*Syntax.initializeSyntax\(null\);\s/,
''
]
}
# Replacement for matching rules
MRULES_TO_SDK = {
:replacements =>
[
]
}
MRULES_FACTORIES = {
:replacements =>
[
"public final void initializeMatchingRule(ServerContext serverContext, MatchingRuleCfg configuration)",
/\bmatchingRule = new \w*MatchingRule\(\);/,
"matchingRule = serverContext.getSchemaNG().getMatchingRule(EMR_);"
]
}
:replacements =>
[
/\bMatchingRule\b/,
]
}
MRULES = {
:replacements =>
[
'',
/\bSubstringMatchingRule\b/,
"MatchingRule",
]
}
# Replacement for attribute type
ATTRTYPE = {
:stoplist => [],
:replacements =>
[
/import org.opends.server.types.\*;/,
]
}
# Replacement for new config framework
NEW_CONFIG = {
:replacements =>
[
'',
/catch \(AuthorizationException e\)/,
'catch (LdapException e)',
/catch \(CommunicationException e\)/,
'catch (LdapException e)',
# Now bring back removed imports that have no replacement
/public ConfigChangeResult\s/,
/new ConfigChangeResult\(/,
/rdn\(\).getAttributeValue\(0\).getValue\(\).toString\(\)/,
'rdn().getFirstAVA().getAttributeValue().toString()',
'',
#/(config|configuration|cfg|currentConfig)\.dn\(\)/,
]
}
# Replacement for types
TYPES = {
:dirs => JAVA_DIRS,
:replacements =>
[
]
}
# Replacement for types
DN_TYPE = {
:replacements =>
[
/import org.opends.server.types.\*;/,
"DN.rootDN()"
]
}
:dirs => JAVA_DIRS,
:replacements =>
[
'\1',
]
}
:dirs => JAVA_DIRS,
:replacements =>
[
# Need to fix removing the last parentheses
'\1',
]
}
LOGGER_TOSTRING = {
:dirs => JAVA_DIRS,
:replacements =>
[
'\1',
]
}
:dirs => JAVA_DIRS,
:replacements =>
[
# Need to fix removing the last parentheses
'\1',
]
}
:dirs => JAVA_DIRS,
:replacements =>
[
/(logger\.\s*(?:trace|debug|warn|info|error)\s*\([^;]*)\s*(Character|Byte|Boolean|Short|Integer|Long|Float|Double)\s*\.\s*toString\s*\(/m,
'\1',
# Need to fix removing the last parentheses
/([A-Z0-9_]+\s*\.\s*get\s*\([^;]*)\s*(Character|Byte|Boolean|Short|Integer|Long|Float|Double)\s*\.\s*toString\s*\(/m,
'\1',
]
}
:dirs => JAVA_DIRS,
:replacements =>
[
/(logger\.\s*(?:trace|debug|warn|info|error)\s*\()\s*([A-Z0-9_]+)\s*\.\s*get\s*\(([^;]*)\)([^;]+)/m,
'\1\2, \3\4',
/(logger\.\s*(?:trace|debug|warn|info|error)\s*\()\s*([A-Z0-9_]+)\s*\.\s*get\s*\(([^;]*)\)([^;]+)/m,
'\1\2, \3\4',
]
}
:dirs => JAVA_DIRS,
:replacements =>
[
/(?:final)?\s*LocalizableMessage\s*(\w+)\s*=\s*((?:[^;]|\r\n|\r|\n)+);\s*(logger\s*\.(?:trace|debug|warn|info|error)\s*\()\s*\1/m,
'\3\2',
/(?: |\t)+$/m,
'',
]
}
:dirs => JAVA_DIRS,
:replacements =>
[
/if\s*\(\s*logger\s*\.\s*isTraceEnabled\s*\(\s*\)\s*\)\s*(logger\s*\.\s*trace(Exception)?\s*\(\s*\w+\s*\)\s*;)/,
'\1',
/if\s*\(\s*logger\s*\.\s*isTraceEnabled\s*\(\s*\)\s*\)\s*\{\s*(logger\s*\.\s*trace(Exception)?\s*\(\s*\w+\s*\)\s*;)\s*\}/,
'\1',
]
}
############################### List of replacements to run #################################
################################### Processing methods ########################################
# Main method : run replacements defined in REPLACEMENTS constant
replace_dirs(repl[:replacements], repl[:dirs], stoplist, whitelist, repl[:extensions])
}
end
# Process replacements on the provided directories
def replace_dirs(replacements, dirs, stoplist, whitelist, extensions)
count_files = 0
count_total = 0
files.each { |file|
next if filename_has_stopword || (!whitelist.empty? && !filename_has_whiteword)
if count > 0
count_files += 1
count_total += count
end
}
}
puts "Replaced in #{count_files} files, for a total of #{count_total} replacements"
end
# Process replacement on the provided file
count = 0
pattern, replace = replacements[index], replacements[index+1]
is_replaced = true
#while is_replaced
#puts "pattern: " + pattern.to_s
if is_replaced then count += 1 end
#end
}
}
end
# Return java class name from java filename
end
# Process provided directories
# Expects a processing block accepting a file as argument and returning a count of changes dones
def process_dirs(dirs, stoplist, whitelist, extensions)
count_files = 0
count_total = 0
files.each { |file|
next if filename_has_stopword || (!whitelist.empty? && !filename_has_whiteword)
if count > 0
count_files += 1
count_total += count
end
}
}
puts "Replaced in #{count_files} files, for a total of #{count_total} replacements"
end
# Process provided file
# Expects a processing block accepting a source string as argument and returning a count of changes + a new
# content
count = 0
}
end
# Return all files with provided extensions under the provided directory
# and all its subdirectories recursively
end
end
# Launch all replacements defined in the REPLACEMENTS constant