TextReplaceTF

Insert, modify or replace text in a file.

Task package:org.schmant.task.base
Java package:org.schmant.task.text
Category:Text tasks
Since:0.5
EntityFS-aware?Yes*
Implements:ActionTaskFactory
GeneratorTaskFactory
ProcessTaskFactory
Produces:The interpreted target property. The exact type depends on the type used for the target.
See also:TextAppendTF
TextPrependTF

Description:

This task takes a list of replaces and runs them on the contents of the source file. The result is saved in the target file. Each replace sees the results from previously run replaces.

A replace is a regular expression matching the text to replace paired with the text to replace it with. See replaces.

By using capturing groups, replacers can use the text to be replaced in the text that it replaces it with. This can, for instance, be used for inserting rather than replacing text. See example 4 and example 5.

Required properties

Properties

bufferSizetop

The size of internal buffers used when replacing text.

Setter method:
setBufferSize(int i)
parameters:
i – The buffer size, in bytes.
Default value:
8192 bytes
errorIfReplaceNotFoundtop

If the source text for one replace is not found, is that an error?

Setter method:
setErrorIfReplaceNotFound(boolean b)
parameters:
b – An error?
Default value:
false
inputEncodingtop

The character encoding of the input file. Use this if the input file has a non-standard encoding, i.e. an encoding different from the Java virtual machine's (platform dependent) default charset.

Setter method:
setInputEncoding(Charset c)
parameters:
c – The input charset.
Setter method:
setInputEncoding(String s)
parameters:
s – The name of a character encoding.
Default value:
The platform's default encoding.
logFootertop

The message that is logged to info level after the task has been successfully run.

Setter method:
setLogFooter(String s)
parameters:
s – The footer message.
Default value:
Empty (no footer message is logged.)
See also:
logHeader
logHeadertop

The message that is logged to info level before the task is run.

Setter method:
setLogHeader(String s)
parameters:
s – The header message.
Default value:
A task class specific message.
See also:
logFooter
maxNoOfReplacesPerReplacetop

Limit the number of times that a replace may be used. If this is set to a negative number, which is the default, each replace is used for all of the text segments that it matches in the processed document.

Setter method:
setMaxNoOfReplacesPerReplace(int n)
parameters:
n – Max number of replaces.
Default value:
-1 (Unlimited number of replaces for each replacer.)
outputEncodingtop

The character encoding of the output file. Use this if the output file should have a non-standard encoding, i.e. an encoding different from the Java virtual machine's (platform dependent) default charset.

Setter method:
setOutputEncoding(Charset c)
parameters:
c – The output charset.
Setter method:
setOutputEncoding(String s)
parameters:
s – The name of a character encoding.
Default value:
The platform's default encoding.
See also:
target
overwriteStrategytop

The overwrite strategy decides how the task will react if there already is an entity (file or directory) in a location where it wants to create a new entity.

If the strategy is to not overwrite existing entities, the task will fail when it cannot create the entities that it wants to create.

Non-empty directories are never overwritten, regardless of the chosen strategy.

Setter method:
setOverwrite(boolean b)
Setting this to a value of true means that the DoOverwriteAndLogWarning strategy is used. A value of false gives the DontOverwriteAndThrowException strategy.
parameters:
b – Should an existing entity be overwritten?
Setter method:
setOverwriteStrategy(OverwriteStrategy strat)
Set the overwrite strategy.
parameters:
strat – The overwrite strategy.
Default value:
DontOverwriteAndThrowException
See also:
target
replaces (required)top

A list of text replaces. Replaces are pairs of objects.

The first object is one of the following:

  • A Pattern.
  • A java.lang.CharSequence (a String, for instance) containing something that can be parsed using Pattern.compile(java.lang.String). In other words, the text is interpreted as a regular expression also when it is given as a CharSequence argument. To match exact strings, quote them using Pattern:s quoting constructs \Q and \E. For instance, "\\Qfoo.bar\\E" matches the exact string "foo.bar".

The second object is one of the following:

  • A String. Matched text will be replaced with the contents of the string. This string can contain references to capturing groups in the matched text. Capture group n is referenced by the placeholder \\n See Pattern documentation and examples 4 and 5.
  • A ReplacementTextStrategy. Matched text will be replaced with the text that is returned from the strategy.
  • A FutureEntity that evaluates to any of the above.
  • A closure with one or two arguments. When the closure is evaluated it should return the replacement text in a string. The closure can have one or two arguments. The first, mandatory, argument is a string containing the text to replace. The second, optional, argument is the Matcher that matched the text to replace. The closure may not update the matcher's state in any way. See example 2 and example 3 below.

There are several different ReplacementTextStrategy implementations available:

The replaces are applied in the order that they are added to this property. When run, a replacer sees the results from previous replacers.

If the task has more than one replacer, files created by intermediate replacing steps are put in the target file system's temporary files directory. See FileSystem.

Setter method:
addReplace(String pattern, Object o)
Add one replace.
parameters:
pattern – A String containing a valid Pattern pattern. The pattern is compiled without setting any Pattern flags.
o – The replace.
Setter method:
addReplace(Pattern p, Object o)
Add one replace.
parameters:
p – The pattern.
o – The replace.
Interpreted by TextReplaceTask.createReplaces(org.entityfs.ReadableFile).
Setter method:
addReplace(TwoObjects<?, ?> p)
Add one replace.
parameters:
p – The replace.
Setter method:
addReplaces(Object o)
Add one or several replaces.
parameters:
o – One replace or an array or collection of replaces (TwoObjects<?, ?> objects).
Interpreted by TextReplaceTask.createReplaces(org.entityfs.ReadableFile).
Setter method:
clearReplaces()
Clear the list of replaces.
reportLeveltop

This property is used to change the Report level for all task created by this task factory. The report level is changed for the thread running the task when the it is run, and is restored to its previous level when the it is done.

Setter method:
setReportLevel(Level l)
Set the report level
parameters:
l – The new report level.
source (required)top

The source file to read text from.

Setter method:
setSource(Object o)
parameters:
o – The source file.
Interpreted by InterpretAsReadOnlyFileStrategy.
See also:
inputEncoding
target (required)top

The target file to write text to.

Setter method:
setTarget(Object o)
parameters:
o – The target file.
Interpreted by InterpretAsNewWritableFileStrategy.
See also:
outputEncoding
tempDirectorytop

A temporary files directory where intermediate replace results are put if there are more than one replace for this task.

Setter method:
setTempDirectory(Object o)
parameters:
o – The temporary files directory.
Interpreted by |si:ai_directory;InterpretAsDirectoryStrategy|.
Default value:
The target file system's default temporary files directory.
traceLoggingtop

If trace logging is enabled for a task, it reports its configuration before it is run.

Trace logging may also be enabled globally for all tasks by calling TraceMode.setTraceMode(boolean).

Setter method:
setTraceLogging(boolean b)
Enable or disable trace logging.
parameters:
b – Enable trace logging?

Examples

Example 1

Replace all occurrences of the string !!!VERSION!!! with the string 1.0 in all text files in the directory hierarchy under the directory d.

new RecursiveActionTF(). addSource(new DirectoryAndFilter(d, new EFileNameExtensionFilter("txt"))). setTaskFactory( new ReplaceSourceFileTF(). setTaskFactory( new TextReplaceTF(). addReplace("!!!VERSION!!!", "1.0"))).run();

Example 2

Replace all occurrences of strings matching the regular expression pattern dat(a)+ in the text file txt with the same string enclosed in <code> tags using a closure to generate the replacement text.

import org.schmant.task.proxy.ReplaceSourceFileTF import org.schmant.task.text.TextReplaceTF new ReplaceSourceFileTF(). addSource(txt). setTaskFactory( new TextReplaceTF(). // Use a closure to return the replacement text. // // Even though we don't use the matcher argument, we have to define it for // Groovy to accept the call to the closure. addReplace("dat(a)+", { text, matcher -> "<code>" + text + "</code>" } )).run()

Example 3

Replace all occurrences of strings matching the regular expression pattern #insert:.*?# (for instance #insert:d2/f.txt# matches) in the file f with the contents of the file that the "tag" references. The "tag" files are stored in or under the directory d. The result is put in the file fp.

import RelativeLocation import org.entityfs.util.* import org.schmant.task.text.TextReplaceTF new TextReplaceTF(). setSource(f). setTarget(fp). // Use a closure to return the replacement text. The closure will access the // variable "d" that is defined further up in the script (not included in the // example). // // We have to define the "matcher" parameter even though we don't use it. addReplace( "#insert:d2/f.txt#", { text, matcher -> // Extract the name of the file to insert def f = text.substring(8, text.length() - 1); return Files.readTextFile( Directories.getFile(d, new RelativeLocation(f))); }).run()

Example 4

In the file report.html, add the text " - confirmed!" to all occurrences of "wild hypothesis no n", where n is a digit. Use capturing group zero to repeat the whole matched text.

new TextReplaceTF(). setSource(new File("report.html")). setTarget(new File("report-final.html")). addReplace("wild hypothesis \\d+", "\\0 - confirmed!").run(); // Given the following report.html: // Jada jada, wild hypothesis 0 Jada jada wild hypothesis 1 // // report-final.html will contain (on one row): // Jada jada, wild hypothesis 0 - confirmed! Jada jada wild hypothesis 1 - \ // confirmed!

Example 5

"Auto-comment" each start tag in the file info.html. Use capturing group zero to repeat the whole matched text and capturing group one to repeat the name of the tag.

new ReplaceSourceFileTF(). setSource(new File("info.html")). setTaskFactory( new TextReplaceTF(). addReplace( // A regular expression that matches all start tags, independent of // case. Pattern.compile( "<\\s*(\\p{Alpha}+)\\s?(\\s|\\p{Print})*?>", Pattern.CASE_INSENSITIVE), "\\0<!-- A \\1 tag -->")).run(); // Given the following info.html: // <html> // <HEAD id="foo"> // <title>Title</title> // </HEAD> // <body type="large">foo</body> // </html> // // After the transformation, it will contain: // <html><!-- A html tag --> // <HEAD id="foo"><!-- A HEAD tag --> // <title><!-- A title tag -->Title</title> // </HEAD> // <body type="large"><!-- A body tag -->foo</body> // </html>

Example 6

Replace the ###city### and ###country### placeholders with values supplied in an EntityFS Properties object.

// The PropertyValueTextStrategy uses EntityFS' Properties object. p = new PropertiesImpl(); p.putStringValue("country", "Sweden"); p.putStringValue("city", "Stockholm"); new ReplaceSourceFileTF(). setSource(new File("weather_report.txt")). setTaskFactory( new TextReplaceTF(). addReplace( // A regular expression that matches our placeholder format ###x###. // Use capturing group 1 to extract the placeholder name. Pattern.compile("###(\\w+)###"), new PropertyValueTextStrategy( p, // Use capturing group 1 1, // We want an exception if we encounter an unknown property key. // Don't ignore missing properties. false))).run(); // Given the following weather_report.txt: // Forecast for ###city###, ###country###: // Cloudy, zero degrees, 50% chance of precipitation. // // After the transformation, it will contain: // Forecast for Stockholm, Sweden: // Cloudy, zero degrees, 50% chance of precipitation.


* An EntityFS-aware task is implemented using EntityFS. This means that it uses the filter settings of DirectoryView:s and also that it often can work with other file system implementations than File-based, such as the RAM file system.