Discussion:
replaceregexp and backslashes
Andrew van Renen
2002-09-05 15:29:10 UTC
Permalink
I want to use <replaceregexp> to update a configuration file in a standard
'name=value' construct, where the value is a Windows path name, as in:

DocumentName=D:\apps\foo\schema.xml

I further want to store the path name in a properties file (for obvious
reasons)

It all works fine, except that it appears I have to octuply(= x 8) my
backslashes for the entry in my properties file, and quadruply the
backslashes in my build file. So this:

build.properties:

App_Root_Dir=D:\\\\\\\\apps\\\\\\\\foo

build.xml:

<replaceregexp file="app.ini"
match="DocumentName=.*"
replace="DocumentName=${App_Root_Dir}\\\\schema.xml)"/>

works but is rather unwieldy.

I realise that part of it is the whole business of escapes in Java and XML,
but is there perhaps a way to either:

a. escape the whole string in one go (eg \'${App_Root_Dir}\schema.xml', or

b. do a scan/replace on the string to multiply the \s before submitting it
to regexp

Any ideas out there?


_________________________________________________________________
Chat with friends online, try MSN Messenger: http://messenger.msn.com
Brian Pontarelli
2002-09-05 16:03:38 UTC
Permalink
I'm sure that this stuff has been covered multiple times before, but I'm
having trouble locating stuff in the archives as well as location in the
code.

Here's my dilemna:
I have a foreach tag (groan right?) that does multiple things. It calls to
targets and executes embedded tasks. The call to targets works fine with the
whole delegation to the "antcall" task (which is annoying, but works). The
embedded tasks, doesn't work at all.

Here's what my build file looks like

<foreach list="foo,bar" property="current">
<echo message="Current is ${current}"/>
</foreach>

My code is roughly this:

// If there are embedded tasks, set the local property and then
// execute those. The 'tasks' variable is a List that is populated
// via the addTask(Task) method
if (!tasks.isEmpty()) {
project.setProperty(property, token);

Iterator iter = tasks.iterator();
Task curTask;
while (iter.hasNext()) {
// curTask.setProject(project); tried this to no avail
curTask = (Task) iter.next();
curTask.perform();
}
}

This does not work because the embedded tasks do not see the property at
all. They don't even see the first value or anything. Here's my output:

[foreach] Current is ${current}
[foreach] Current is ${current}

First off, can someone point me the the code in the ant framework that makes
properties immutable so that you must use the "antcall" hack to call other
targets correctly? Also, could someone please explain to me what ant is
doing when it constructs the embedded tasks that prevent them from seeing
properties? Last, does anyone have any work-arounds for this problem?

Thanks
Brian Pontarelli
Stefan Bodewig
2002-09-06 06:38:38 UTC
Permalink
Also, could someone please explain to me what ant is doing when it
constructs the embedded tasks that prevent them from seeing
properties?
The "normal" mode of Ant is to configure all nested elements of a task
before executing that task. "configure" here includes invoking the
setters for the attributes and expanding properties. So the
attributes for your nested tasks get set before the property has been
defined.
Last, does anyone have any work-arounds for this problem?
Take a look at how <seqential> avoids this "normal" mode to allow
property expansion to work for nested tasks in Ant 1.5 (it doesn't
work in 1.4.x). The relevant change has been this
<http://cvs.apache.org/viewcvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Sequential.java.diff?r1=1.7&r2=1.7.2.1>

Stefan
Dominique Devienne
2002-09-05 16:29:38 UTC
Permalink
If you look at the code of <echo>, you'll see that setMessage(String msg)
never calls getProject().replaceProperties(msg);, and it's not done
elsewhere in the code either. This implies it's done by the framework
*before* calling that attribute setter method, and most likely done *before*
you ever get the chance to set the property...

I don't know how you could delay this stuff to happen, short of relying on
dynamic configurator, which would leave you with the painful task of doing
of the work the framework is already doing (creating the sub-element, and
initializing their attributes).

And also, property immutability is likely to bite you, since Ant doesn't
support the notion of a variable you can change for each invocatin. The
Ant-contrib task gets away from that by using <antcall> internally, but then
the resource hog (dixit Stefan today) issue bites you, and of course
property changes are not propagated.

Can you explain what you're doing that would require this modified
<foreach>? --DD

-----Original Message-----
From: Brian Pontarelli [mailto:***@pontarelli.com]
Sent: Thursday, September 05, 2002 11:04 AM
To: Ant Users List
Subject: TaskContainer and setProperty


I'm sure that this stuff has been covered multiple times before, but I'm
having trouble locating stuff in the archives as well as location in the
code.

Here's my dilemna:
I have a foreach tag (groan right?) that does multiple things. It calls to
targets and executes embedded tasks. The call to targets works fine with the
whole delegation to the "antcall" task (which is annoying, but works). The
embedded tasks, doesn't work at all.

Here's what my build file looks like

<foreach list="foo,bar" property="current">
<echo message="Current is ${current}"/>
</foreach>

My code is roughly this:

// If there are embedded tasks, set the local property and then
// execute those. The 'tasks' variable is a List that is populated
// via the addTask(Task) method
if (!tasks.isEmpty()) {
project.setProperty(property, token);

Iterator iter = tasks.iterator();
Task curTask;
while (iter.hasNext()) {
// curTask.setProject(project); tried this to no avail
curTask = (Task) iter.next();
curTask.perform();
}
}

This does not work because the embedded tasks do not see the property at
all. They don't even see the first value or anything. Here's my output:

[foreach] Current is ${current}
[foreach] Current is ${current}

First off, can someone point me the the code in the ant framework that makes
properties immutable so that you must use the "antcall" hack to call other
targets correctly? Also, could someone please explain to me what ant is
doing when it constructs the embedded tasks that prevent them from seeing
properties? Last, does anyone have any work-arounds for this problem?

Thanks
Brian Pontarelli


--
To unsubscribe, e-mail: <mailto:ant-user-***@jakarta.apache.org>
For additional commands, e-mail: <mailto:ant-user-***@jakarta.apache.org>
Brian Pontarelli
2002-09-05 17:11:09 UTC
Permalink
<snip>

Can you explain what you're doing that would require this modified
<foreach>? --DD

</snip>

Well, I'm not really doing anything special except that flexibility is nice.
To be able to place the tasks inside the foreach rather than in a new target
keeps the build file cleaner.

The ant API seems to be lacking in these respects. Think how easy it would
be for the foreach tag to be written and how much faster it would be if you
could simply use project.executeTarget() rather than having to basically
re-execute ant with the same build file calling the specific target (which
is basically what the antcall does because it uses the ant task).

Also, there doesn't seem to be a robust way to managing properties scopes.
For example:

<someTask1>
<someTask1.1>
<someTask1.1.1/>
</someTask1.1>

<someTask1.2>
<someTask1.2.1/>
</someTask1.2>
</someTask>

If someTask1 sets a property, then someTask1.* should see it. However, if
someTask1.1 sets a property someTask1.2 should not see it, unless it is
marked parent visible or something. This is a fundamental programming
language concept and that's basically what ant is, a scripting language of
sorts.

Anyways, that seems to be something that ant2 should really consider because
it would make like much easier for developers.

Brian
Stefan Bodewig
2002-09-06 06:44:31 UTC
Permalink
Post by Brian Pontarelli
Also, there doesn't seem to be a robust way to managing properties scopes.
Well, "all properties are global" is quite robust 8-)

Stefan

Stefan Bodewig
2002-09-06 06:42:44 UTC
Permalink
Post by Dominique Devienne
I don't know how you could delay this stuff to happen,
see my other mail
Post by Dominique Devienne
And also, property immutability is likely to bite you, since Ant
doesn't support the notion of a variable you can change for each
invocatin.
Well, this is not entirely true. It is possible to change property
values via Ant's API (and thus via a custom task), there is just no
built-in task that would do so.

The bigger problem with a foreach like task setup would be that the
nested task will only get "configured" (attributes set, properties
expanded) once, not once per iteration. So you are basically forced
to do the configuration yourself (in the container) rather than
letting Ant do it.

Stefan
Dominique Devienne
2002-09-05 18:27:25 UTC
Permalink
I don't disagree with you. I just think that given the state of the Ant code
base, what you want to do is difficult, and would require major refactorings
you would be likely enable to get past the committer. So my advise would be
to stick with Ant-contrib's <foreach> calling another target, and live with
the expense of the implicit <antcall>... --DD

-----Original Message-----
From: Brian Pontarelli [mailto:***@pontarelli.com]
Sent: Thursday, September 05, 2002 12:11 PM
To: Ant Users List
Subject: RE: TaskContainer and setProperty



<snip>

Can you explain what you're doing that would require this modified
<foreach>? --DD

</snip>

Well, I'm not really doing anything special except that flexibility is nice.
To be able to place the tasks inside the foreach rather than in a new target
keeps the build file cleaner.

The ant API seems to be lacking in these respects. Think how easy it would
be for the foreach tag to be written and how much faster it would be if you
could simply use project.executeTarget() rather than having to basically
re-execute ant with the same build file calling the specific target (which
is basically what the antcall does because it uses the ant task).

Also, there doesn't seem to be a robust way to managing properties scopes.
For example:

<someTask1>
<someTask1.1>
<someTask1.1.1/>
</someTask1.1>

<someTask1.2>
<someTask1.2.1/>
</someTask1.2>
</someTask>

If someTask1 sets a property, then someTask1.* should see it. However, if
someTask1.1 sets a property someTask1.2 should not see it, unless it is
marked parent visible or something. This is a fundamental programming
language concept and that's basically what ant is, a scripting language of
sorts.

Anyways, that seems to be something that ant2 should really consider because
it would make like much easier for developers.

Brian



--
To unsubscribe, e-mail: <mailto:ant-user-***@jakarta.apache.org>
For additional commands, e-mail: <mailto:ant-user-***@jakarta.apache.org>
Loading...