?
Solved

ANT ?tion - alternative to "available file" option

Posted on 2003-02-19
9
Medium Priority
?
321 Views
Last Modified: 2012-08-13
I need to provide some info before I go into my question.  I am using a single ANT build.xml for several projects, the goal is to keep the build.xml generic and use properties files for each of the projects.  Due to this I've built it to accomodate all projects.

Using a web module (WSAD terminology) for an example I will have one OR more replace strings for files within that module for the different projects.  The information regarding the replacement strings resides in each Projects property file, and looks something like this:

** PROPERTIES SET IN THE PROJECTS PROPERTY FILE ******
WEB.Modify1.file=C:\\ccView\\${VOB.project.name}\\${VOB.project.name}_vob\\code\\${WEB1.project.name}\\${WEB.content}\\WEB-INF\\ibm-web-bnd.xmi
WEB.Token1.string=virtualHostName="default_host"
WEB.Value1.string=virtualHostName="VHMyTime"
** END **

I currently using the following code to look for the presence of a file (stringreplacement1.txt) to determine if I should call the target "replaceString1".  This is a real pain, because I have to remember to create the stringreplacement1.txt file, and it is an even bigger pain when there are lots of replacements (i.e. have to create stringreplacement2.txt, etc..).

** CODE USED TO CHECK FOR EXISTENCE OF STRINGREPLACEMENT1.TXT **
     <available file="${global.vobAppBuildCode.dir}/${module.project.name}/stringreplacement1.txt" type="file" property="stringreplacement1.exists"/>
     <antcall target="replaceString1">
          <param name="Modify1.file" value="${WEB.Modify1.file}"/>
          <param name="Replace1.string" value="${WEB.Token1.string}"/>
          <param name="Replacement1.string" value="${WEB.Value1.string}"/>
     </antcall>
** END **

Can anyone suggest a better way to do this?  Is there a way to check if there is a value associated with "WEB.Modify1.file", and if so then do the antcall?

Thanks,

Lisa
0
Comment
Question by:lphillips120898
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
9 Comments
 
LVL 5

Expert Comment

by:msmolyak
ID: 7983880
Lisa,

I am not exactly sure what you are trying to accomplish. If it is just string replacement you need, Ant has filtering capabilities allowing you to replace tokens surrounded by @ character in the files being filtered with the respective values.

Please clarify the goal, so that I could suggest a solution.

Michael
0
 

Author Comment

by:lphillips120898
ID: 7986975
Okay - I'll try and explain this better by taking another approach.  I have multiple projects which may have a file(s) that need string replacements.

For example, ApplicationCAT has the file abc.xml that has two lines that require string replacements.  ApplicationDOG has file abc.xml that only needs one string replacement.

I'm using one build.xml for all my projects (applications).  In the properties file of each of the projects I specify the file(s)/existingString/replacementString that needs to take place during the build.

** EXAMPLE from the projects properties file **
WEB.Modify1.file=C:\\ccView\\${VOB.project.name}\\${VOB.project.name}_vob\\code\\${WEB1.project.name}\\${WEB.content}\\WEB-INF\\abc.xml
WEB.Token1.string=virtualHostName="default_host"
WEB.Value1.string=virtualHostName="VHMyTime"
** END EXAMPLE **

There will be as many of these entries in the properties files as there are string replacements.  If there was a second string replacement I would have something like the above with the parameters: WEB.Modify2.file, WEB.Token2.string,WEB.Value2.string.

So at this point I have all the file and string replacement info in all of my projects properties files.

In my build.xml I must accomodate for the project that has the most string replacements.  Here is an example of what is in the build.xml:

** CODE USED TO CHECK FOR EXISTENCE OF STRINGREPLACEMENT1.TXT **
    <antcall target="replaceString1">
         <param name="Modify1.file" value="${WEB.Modify1.file}"/>
         <param name="Replace1.string" value="${WEB.Token1.string}"/>
         <param name="Replacement1.string" value="${WEB.Value1.string}"/>
    </antcall>

    <antcall target="replaceString1">
         <param name="Modify2.file" value="${WEB.Modify2.file}"/>
         <param name="Replace2.string" value="${WEB.Token2.string}"/>
         <param name="Replacement2.string" value="${WEB.Value2.string}"/>
    </antcall>
** END **

So the above code will execute the string replacement command in targets "replaceString1" and "replaceString2".  The problem is that project ApplicationDOG (going back to the example) only has ONE string replacement that needs to take place, so the build fails with it tries to do the second string replacement because there are no values.

The way I worked around this was to put a "dummy" file on the file system (stringreplacement"x".txt).  For each project I have an area that I place these.  ApplicationDOG would just have "stringreplacement1", while ApplicationCAT would have "stringreplacement1.txt" and "stringreplacment2.txt".

I then use an "available file" statement before the <antcall target="replaceStringx"> statement, which will check for the existence of the stringreplacementx.txt file.  If it exist it executes the ant call, if not it skips it.

THE GOAL - FINALLY!!
I don't want to have to put the stringreplacmentx.txt file(s) on the file system as a means to check if it should execute the ant call.  I would prefer it if there was a way to check if there was a value for WEB.modify1.file, WEB.modify2.file, etc.  If a value has been set in the projects properties file there should be a value in there.

Is this possible?  I initially though I could use something like the "available" task to check for a "JVM system resource" (I'm not sure if this would qualifies as as a JVM System Resource though).

I don't know if this makes any more sense than it did before, I hope so.  If you want to take a look at the projects properties file and the build.xml I will gladly send it to you.

I'm going to increase the points to 200, as I would really like to come up with a solution for this.

Thanks,

Lisa


0
 
LVL 5

Expert Comment

by:msmolyak
ID: 7988061
Lisa,

Did you consider modularizing the build file setup? You can have one parent build file common to all your projects and multiple child files, one per each project. The parent file would call targets in the child files. Each child file would be specific to each project and will knwo what strings to replace. You would parameterise the parent file to specify which project you are building. You invoke target in the child build files by using <ant> task. You can also pass and/or inherit parameters into the child build files. This is the at-large solution.

For your string replacement needs I find your methodology overly complex. Ant has a feature called filtering. It is used in <copy> task and allows you to replace the placeholders in your ASCII files with the values known to Ant. You specify a placeholder in your abc.xml file by putting the following in the target file:

<element1>@WEB.Token2.string@</element1>

In your build.xml file in your copy task you enable filtering for files being copied. Then you specify abc.xml among the files being copied. Ant will replace @WEB.Token2.string@ token in the copied abc.xml with the value of its parameter WEB.Token2.string.

Typically you will specify the parameters for replacement in a separate properties file much like you are doing now. The filter task accepts the name of the properties file. That file looks like a typical Java properties file:

WEB.Token2.string=thevalue

The result will be

<element1>thevalue</element1>

Then you use the copied file instead of the original.

You should probably have one properties file per project, so that the same tokens could have different values for different projects. The name of the properties file will be a parameter to the build process. Or you can name the properties file with the name of the project and parameterise it.

For example:

<filter filtersfile="${PROJECT_NAME}.properties"/>

<copy filtering="true" ...>
...
</copy>

Let me know if that helps.

Michael
0
TCP/IP Network Protocol Cheat Sheet

TCP/IP is a set of network protocols which is best known for connecting the machines that make up the Internet. The truth is that TCP/IP is one of the oldest network protocols and its survival is mainly based on its simplicity and universality.

 

Author Comment

by:lphillips120898
ID: 7993362
Michael,

I'm interested in setting up what you've explained, but am not sure I completely understand it.  I have a few question, maybe that will clear things up enough so I can set this up.

Is the syntax to call one of the "child files", which I will refer to as the <appName>Build.xml from now on, as follows?

  <ant antfile="ApplicationCATBuild.xml">
    <property name="stringvalues1" value="WEB.Modify1.file"/>
    <property file="ApplicationCAT.properties"/>
  </ant>

>>> you specify a placeholder in your abc.xml file by putting the following in the target file: <element1>@WEB.Token2.string@</element1>

What file are you referring to when you say "target file" - the abc.xml?

I hope I'm not asking too much, but it would really be helpful if you could provide a small example of what the code would be in the build.xml, and the code in the abc.xml before the string replacement.  What you're saying makes sense, but I'm an example type person.  For example, I don't quite understand where the <element1> tags go.

I appreciate your help, I'm sure it will click when I see a code example.

Lisa
0
 
LVL 5

Accepted Solution

by:
msmolyak earned 800 total points
ID: 7995722
Lisa,

I did not think you should pass the string name, value and file name as parameters of the <ant> task. You would use file filtering instead. The child ant file simply knows what filtering to apply. Here is how filtering works.

I have a weblogic.xml file from my deployment:

<weblogic-web-app>
    <jsp-descriptor>
      <jsp-param>
        <param-name>pageCheckSeconds</param-name>
        <param-value>1</param-value>
      </jsp-param>
      <jsp-param>
        <param-name>verbose</param-name>
        <param-value>true</param-value>
      </jsp-param>
      <jsp-param>
        <param-name>keepgenerated</param-name>
        <param-value>true</param-value>
      </jsp-param>
      <jsp-param>
        <param-name>workingDir</param-name>
        <param-value>config/lww/applications/working</param-value>
      </jsp-param>
      @precompile.commented.out.begin@
      <jsp-param>
        <param-name>precompile</param-name>
        <param-value>true</param-value>
      </jsp-param>
      @precompile.commented.out.end@
    </jsp-descriptor>

    <security-role-assignment>
      <role-name>paceViewing</role-name>
      <principal-name>paceViewing</principal-name>
    </security-role-assignment>
    <security-role-assignment>
      <role-name>paceAdmins</role-name>
      <principal-name>paceAdmins</principal-name>
    </security-role-assignment>
    <security-role-assignment>
      <role-name>paceSpecialAdmins</role-name>
      <principal-name>paceSpecialAdmins</principal-name>
    </security-role-assignment>

</weblogic-web-app>


Notice @precompile.commented.out.begin@ and
@precompile.commented.out.end@ tokens. They will be replaced with some values during the build process.

Now I can define several files defining the substitution.

In one file local.properties (for local deployment) I want to comment the precompile option, so I define

# Whether or not precompile is commented out in weblogic.xml
precompile.commented.out.begin=<!--
precompile.commented.out.end=-->

In another file, client.properties (for client deployment) I want to leave the precompilation alone:

precompile.commented.out.begin=
precompile.commented.out.end=

Now in my build file I simply need to specify whether I want to use local.properties or client.properties (in your case you child projects will decide which properties file to use).

This is the example:

  <target name="copyProps">
    <mkdir dir="${staging}"/>
    <mkdir dir="${staging.props}"/>
    <!-- set up filtering to replace machine-specific values where needed -->
    <filter filtersfile="${dd}/${env}.properties"/>
    <!-- copy some properties files from ${src} into the staging area -->
    <copy todir="${staging.props}" filtering="true">
      <fileset dir="${src}" includes="**/*.properties" excludes="dd/**/*,**/web/resources/*,**/Extractor.properties"/>
      <fileset dir="${src}" includes="**/web/resources/ApplicationResources.properties"/>
    </copy>
  </target>


${dd}/${env}.properties is the file used by Ant for filtering definitions. We pass variable env from the command line to make it easy to switch between different properties files. Copy task in this example copies the files while replacing the keywords enclosed in @@ with the values from the property files.

Hope this answers your questions.
0
 

Author Comment

by:lphillips120898
ID: 8009074
Okay, I understand what and how you are doing this.  I do have a question about the example though.  In your weblogic.xml file you have placed the @@ markers where you want to replace code.  I can't edit the files I need to have replacments done in.  When I get ready to do a deployment I check the code out of ClearCase.  Before that a team of developers are working in WebSphere Application Developer and they check this code in.  So unless I'm missing something it won't be practical in this case to have "@@" tags in the files that require the replacements.  Do you agree?  Or, am I still not understanding something you're trying to tell me!

I can still take the suggestion and examples you gave me and try a different approach.  Thank you for all your help!

Lisa
0
 
LVL 5

Expert Comment

by:msmolyak
ID: 8011163
Lisa,

My approach does assume that you can change the file. And if the file does need replacements why shouldn't you be able to change it? Do developers use Ant to build in their environemtns?

Michael
0
 

Author Comment

by:lphillips120898
ID: 8016515
No, the developers don't use Ant.  They develop locally in WSAD.  When they are ready to do integration testing they check their code into ClearCase, I then use Ant to build and deploy into our "DEV" environment.

I haven't tried this yet, but if I have them use the @string@ markers in their "live" xml files will they still work (i.e. the app sees this as a comment and doesn't break)?

I have yet a new problem I need to solve and if I can get them to use @ markers it may solve my problem.

Also, can  you recommend a good Ant book?

Thanks,

Lisa
0
 
LVL 5

Expert Comment

by:msmolyak
ID: 8016780
I use 'Java Development with Ant' by Eric Hatchet and Steve Loughran and I like it. It is detailed, has many examples and covers a lot of grounds. It also explain how to write custom tasks.

If you cannot make your developers use Ant (which would be e sensible strategy to try), you can always write a custom task to do your replacements.

All the logic you were trying to put into the Ant build file (trying to decide what to replace for what project) will go into that task which should read from some properties file. The properties files (one per project) will look similar to what they should look for filtering but instead of relying on @@ markers, the new task will know exactly what strings to replace.

Michael
0

Featured Post

Optimize your web performance

What's in the eBook?
- Full list of reasons for poor performance
- Ultimate measures to speed things up
- Primary web monitoring types
- KPIs you should be monitoring in order to increase your ROI

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

By the end of 1980s, object oriented programming using languages like C++, Simula69 and ObjectPascal gained momentum. It looked like programmers finally found the perfect language. C++ successfully combined the object oriented principles of Simula w…
Are you developing a Java application and want to create Excel Spreadsheets? You have come to the right place, this article will describe how you can create Excel Spreadsheets from a Java Application. For the purposes of this article, I will be u…
Video by: Michael
Viewers learn about how to reduce the potential repetitiveness of coding in main by developing methods to perform specific tasks for their program. Additionally, objects are introduced for the purpose of learning how to call methods in Java. Define …
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
Suggested Courses
Course of the Month15 days, 8 hours left to enroll

741 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question