{"id":37,"date":"2013-05-09T01:28:00","date_gmt":"2013-05-08T15:28:00","guid":{"rendered":""},"modified":"2018-05-22T21:19:30","modified_gmt":"2018-05-22T11:19:30","slug":"ant-edit-property-values","status":"publish","type":"post","link":"https:\/\/pbw.id.au\/blog\/2013\/05\/ant-edit-property-values\/","title":{"rendered":"Ant: edit property values"},"content":{"rendered":"<p>One of the frustrations of using <i>ant<\/i>\u00a0was the difficulty of deriving one property value performing some sort of editing operation on an existing property value. The <i>mapper<\/i> task does a lot of grunt work for file names, but not for property values as such.<\/p>\n<p>A common requirement is to map a Java package name to a corresponding directory structure. I have a property containing the package name, and I want to create another property with the directories. Here&#8217;s one way to do that.<!--more--><\/p>\n<pre>&lt;property name=\"my.package\" value=\"my.java.package\"\/&gt;\n&lt;!-- ... Some time later ... --&gt;\n&lt;loadresource property=\"my.package.dirs\"&gt;\n&lt;string value=\"${my.package}\"\/&gt;\n&lt;filterchain&gt;\n&lt;replacestring from=\".\" to=\"${file.separator}\"\/&gt;\n&lt;striplinebreaks\/&gt;\n      &lt;\/filterchain&gt;\n&lt;\/loadresource&gt;<\/pre>\n<p>For more complex transformations, a replaceregexp filter can be used. The above example would then be:<\/p>\n<pre>&lt;property name=\"my.package\" value=\"my.java.package\"\/&gt;\n&lt;!-- ... Some time later ... --&gt;\n&lt;loadresource property=\"my.package.dirs\"&gt;\n&lt;string value=\"${my.package}\"\/&gt;\n&lt;filterchain&gt;\n&lt;striplinebreaks\/&gt;\n&lt;replaceregex pattern=\".\" replace=\"${file.separator}\" flags=\"g\"\/&gt;\n&lt;\/filterchain&gt;\n&lt;\/loadresource&gt;<\/pre>\n<div>\n<p>Here&#8217;s a macrodef to perform string editing, included in an ant build file called editstring.xml with a test invocation. The base file, without the test, can be downloaded <a href=\"http:\/\/pbw.id.au\/src\/ant\/editstring.xml\">here<\/a>.<\/p>\n<pre>&lt;project name=\"editstring\"&gt;\n  &lt;macrodef name=\"editstring\"\n    description=\"Edit a string using a regexp pattern and repacement, with optional flags, placing result in a property.\"&gt;\n    &lt;attribute name=\"string\"\n      description=\"String being edited.\"\/&gt;\n    &lt;attribute name=\"dest\"\n      description=\"Name of the property receiving the edit result.\"\/&gt;\n    &lt;attribute name=\"pattern\"\n      description=\"Regexp pattern to be replaced.\"\/&gt;\n    &lt;attribute name=\"replace\"\n      description=\"Regexp replacement pattern.\"\/&gt;\n    &lt;attribute name=\"flags\"\n      description=\"Regexp replacement flags.\"\n      default=\"-g\"\/&gt;\n    &lt;sequential&gt;\n      &lt;loadresource property=\"@{dest}\"&gt;\n        &lt;string value=\"@{string}\"\/&gt;\n          &lt;filterchain&gt;\n            &lt;replaceregex pattern=\"@{pattern}\"\n             replace=\"@{replace}\" flags=\"@{flags}\"\/&gt;\n            &lt;striplinebreaks\/&gt;\n          &lt;\/filterchain&gt;\n      &lt;\/loadresource&gt;\n    &lt;\/sequential&gt;\n  &lt;\/macrodef&gt;\n\n  &lt;target name=\"junk\"&gt;\n    &lt;property name=\"teststr\" value=\"My test string.\"\/&gt;\n    &lt;editstring string=\"${teststr}\" dest=\"result\"\n      pattern=\"^(S+s+)S+(s+.*)$\" replace=\"1result2\"\/&gt;\n    &lt;echo&gt;${teststr} : ${result}&lt;\/echo&gt;\n  &lt;\/target&gt;\n&lt;\/project&gt;<\/pre>\n<p>Be aware of the <i>striplinebreaks<\/i> filter. I found when I used this method that I was getting a spurious newline on the end of my edited string, so I inserted <i>striplinebreaks<\/i>. However, if you are editing a multiline string, this will break your replacement. You will have to experiment in those circumstances. I suspect that this is an artifact of the line-at-a-time processing of replacement text. I think it appends a line break after replacement.<\/p>\n<p>I first read about this solution in a post by <a href=\"http:\/\/markmelvin.blogspot.com.au\/2008\/09\/ant-wizardry.html\">Mark Melvin<\/a>. Thanks to Mark.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>One of the frustrations of using ant\u00a0was the difficulty of deriving one property value performing some sort of editing operation on an existing property value. The mapper task does a lot of grunt work for file names, but not for property values as such. A common requirement is to map a Java package name to &hellip; <a href=\"https:\/\/pbw.id.au\/blog\/2013\/05\/ant-edit-property-values\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Ant: edit property values&#8221;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[19],"tags":[],"class_list":["post-37","post","type-post","status-publish","format-standard","hentry","category-code"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p8SCfl-B","jetpack-related-posts":[{"id":36,"url":"https:\/\/pbw.id.au\/blog\/2013\/05\/ant-process-elements-in-a-list\/","url_meta":{"origin":37,"position":0},"title":"Ant: process elements in a list","author":"pbw","date":"Sun 19th May '13","format":false,"excerpt":"I was looking for a way to process a list of items in an ant build file, similar to what you would do in Java with a construct like: for ( Element element : elements ) { \/\/ do stuff with element } The approach of XSLT, using recursive calls\u2026","rel":"","context":"In &quot;Code&quot;","block_context":{"text":"Code","link":"https:\/\/pbw.id.au\/blog\/category\/code\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1109,"url":"https:\/\/pbw.id.au\/blog\/2023\/05\/what-happens-in-wieambilla-stays-in-wieambilla\/","url_meta":{"origin":37,"position":1},"title":"What Happens In Wieambilla, Stays In Wieambilla","author":"Me","date":"Wed 17th May '23","format":false,"excerpt":"First published at NewCatallaxy blog, 4 January, 2023 Six people died at Wieambilla. Not two. Not three. But six. Almost lost in the public clamour about the deaths of the police officers, is the death of the neighbour, already attributed to the now-dead occupants of the property. Unlike the police\u2026","rel":"","context":"In &quot;Law&quot;","block_context":{"text":"Law","link":"https:\/\/pbw.id.au\/blog\/category\/culture\/law\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":506,"url":"https:\/\/pbw.id.au\/blog\/2018\/04\/consciousness-time-part-1\/","url_meta":{"origin":37,"position":2},"title":"Consciousness &#038; Time: Part 1","author":"admin","date":"Sun 29th Apr '18","format":false,"excerpt":"Vulcans, zombies, and desert islands Imagine, for the moment, that at some time in the 1850s a Royal Navy vessel, operating to the south of Samoa, in running from a cyclone, finds a large uncharted desert isle.\u00a0 Inhabitants are nowhere to be found, but inhabitants there were, at least the\u2026","rel":"","context":"In &quot;All&quot;","block_context":{"text":"All","link":"https:\/\/pbw.id.au\/blog\/category\/all\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":32,"url":"https:\/\/pbw.id.au\/blog\/2015\/02\/monad-thats-a-wrap\/","url_meta":{"origin":37,"position":3},"title":"Monad; that&#8217;s a wrap!","author":"pbw","date":"Mon 16th Feb '15","format":false,"excerpt":"Just like everybody else who starts to look at monads, I found it was like coming to the face of a sheer cliff. \u00a0Let me qualify that: just like every other programmer who is not a mathematician (and that's most of us). \u00a0I am looking at monads in the context\u2026","rel":"","context":"In &quot;Code&quot;","block_context":{"text":"Code","link":"https:\/\/pbw.id.au\/blog\/category\/code\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":39,"url":"https:\/\/pbw.id.au\/blog\/2013\/05\/setting-environment-variables-in-os-x-lion\/","url_meta":{"origin":37,"position":4},"title":"Setting Environment Variables in OS X Lion","author":"pbw","date":"Fri 3rd May '13","format":false,"excerpt":"If you want to set environment variables in OS X in such a way as to be recognised in applications run from Finder, it is not enough to set the env var in .profile. \u00a0You must also ensure that the variables are set in the file ~\/.MacOSX\/environment.plist. Setting values in\u2026","rel":"","context":"In &quot;Code&quot;","block_context":{"text":"Code","link":"https:\/\/pbw.id.au\/blog\/category\/code\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":31,"url":"https:\/\/pbw.id.au\/blog\/2015\/03\/help-for-digest-checking\/","url_meta":{"origin":37,"position":5},"title":"Help for digest checking","author":"pbw","date":"Fri 20th Mar '15","format":false,"excerpt":"Updated 2018-02-14 It's pretty important to check the digests of software you download. \u00a0When a downloaded file is accompanied by a signature file, for example a gnupg .asc file, you can verify the signature with various tools. \u00a0Often though, a download site will include the MD5 or SHA1 digest hash\u2026","rel":"","context":"In &quot;Code&quot;","block_context":{"text":"Code","link":"https:\/\/pbw.id.au\/blog\/category\/code\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/pbw.id.au\/blog\/wp-json\/wp\/v2\/posts\/37","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pbw.id.au\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pbw.id.au\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pbw.id.au\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/pbw.id.au\/blog\/wp-json\/wp\/v2\/comments?post=37"}],"version-history":[{"count":6,"href":"https:\/\/pbw.id.au\/blog\/wp-json\/wp\/v2\/posts\/37\/revisions"}],"predecessor-version":[{"id":575,"href":"https:\/\/pbw.id.au\/blog\/wp-json\/wp\/v2\/posts\/37\/revisions\/575"}],"wp:attachment":[{"href":"https:\/\/pbw.id.au\/blog\/wp-json\/wp\/v2\/media?parent=37"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pbw.id.au\/blog\/wp-json\/wp\/v2\/categories?post=37"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pbw.id.au\/blog\/wp-json\/wp\/v2\/tags?post=37"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}