Index: /main/branches/stable_gs3/ant-tasks/build.xml
===================================================================
--- /main/branches/stable_gs3/ant-tasks/build.xml	(revision 21854)
+++ /main/branches/stable_gs3/ant-tasks/build.xml	(revision 21854)
@@ -0,0 +1,146 @@
+<project name="compile-ant-tasks" default="compile">
+
+	<condition property="libs.set">
+		<and>
+			<isset property="crypt.jar"/>
+		</and>
+	</condition>
+
+	<target name="compile" depends="check-libs">
+
+		<mkdir dir="classes"/>
+		<javac
+			srcdir="src/org/greenstone/anttasks"
+			destdir="classes"
+			classpath="${crypt.jar}"/>
+
+		<jar
+			destfile="anttasks.jar"
+			basedir="classes"/>
+
+	</target>
+
+	<target name="clean">
+		<delete dir="classes"/>
+		<delete file="anttasks.jar"/>
+	</target>
+
+	<target name="check-libs" unless="libs.set">
+		<echo>Please set crypt.jar property to the path of the crypt.jar file</echo>
+		<echo>E.g., ant -Dcrypt.jar=/path/to/crypt.jar</echo>
+		<fail>paths to libs not set</fail>
+	</target>
+
+	<target name="test-setup">
+		<path id="test.classpath">
+			<pathelement path="anttasks.jar"/>
+			<pathelement path="${crypt.jar}"/>
+		</path>
+		<typedef name="dcff" classname="org.greenstone.anttasks.DeleteChunkFromFile" classpathref="test.classpath"/>
+		<typedef name="rsr" classname="org.greenstone.anttasks.RegexSearchReplace" classpathref="test.classpath"/>
+		<typedef name="gpv" classname="org.greenstone.anttasks.GetPropertyValue" classpathref="test.classpath"/>
+		<mkdir dir="test"/>
+	</target>
+
+	<target name="test" depends="test-setup">
+		<antcall target="test-rsr"/>
+		<antcall target="test-dcff"/>
+		<antcall target="test-gpv"/>
+	</target>
+
+	<target name="test-rsr" depends="test-setup">
+
+		<!-- test 1 -->
+		<copy file="src/test/rsr.txt" tofile="test/rsr1.txt"/>
+		<rsr file="test/rsr1.txt" pattern="things" replacement="strings"/>
+
+		<!-- test 2 -->
+		<copy file="src/test/rsr.txt" tofile="test/rsr2.txt"/>
+		<rsr file="test/rsr2.txt">
+			<job pattern="things" replacement="objects"/>
+			<job pattern="Or" replacement="And"/>
+		</rsr>
+
+		<!-- test 3 -->
+		<copy file="src/test/rsr.txt" tofile="test/rsr3.txt"/>
+		<rsr file="test/rsr3.txt" pattern="@path@" replacement="C:\Program Files\Greenstone 2.80"/>
+		<rsr file="test/rsr3.txt" pattern="@path-with-winpath@" replacement="C:\Program Files\Greenstone 2.80" winPath="true"/>
+
+		<!-- test 4 -->
+		<copy file="src/test/rsr.txt" tofile="test/rsr4.txt"/>
+		<rsr file="test/rsr4.txt">
+			<job pattern="@path@" replacement="C:\Program Files\Greenstone 2.80"/>
+			<job pattern="@path-with-winpath@" replacement="C:\Program Files\Greenstone 2.80" winPath="true"/>
+		</rsr>
+
+		<!-- test 5 -->
+		<copy file="src/test/rsr.txt" tofile="test/rsr5-1.txt"/>
+		<copy file="src/test/rsr.txt" tofile="test/rsr5-2.txt"/>
+		<rsr>
+			<fileset dir="test" includes="rsr5-*"/>
+			<job pattern="@path@" replacement="C:\Program Files\Greenstone 2.80"/>
+			<job pattern="@path-with-winpath@" replacement="C:\Program Files\Greenstone 2.80" winPath="true"/>
+		</rsr>
+
+		<!-- test 6 -->
+		<copy file="src/test/rsr.txt" tofile="test/rsr6-1.txt"/>
+		<copy file="src/test/rsr.txt" tofile="test/rsr6-2.txt"/>
+		<copy file="src/test/rsr.txt" tofile="test/rsr6-3.txt"/>
+		<copy file="src/test/rsr.txt" tofile="test/rsr6-4.txt"/>
+		<rsr file="test/rsr6-1.txt" pattern="e" replacement="*" lines="8"/>
+		<rsr file="test/rsr6-2.txt" pattern="e" replacement="*" lines="4-9"/>
+		<rsr file="test/rsr6-3.txt" pattern="e" replacement="*" lines="-8"/>
+		<rsr file="test/rsr6-4.txt" pattern="e" replacement="*" lines="4-"/>
+
+	</target>
+
+	<target name="test-dcff" depends="test-setup">
+
+		<!-- test 1 -->
+		<copy file="src/test/dcff.txt" tofile="test/dcff1.txt"/>
+		<dcff file="test/dcff1.txt" startTag="The" endTag="brown" leaveTags="true"/>
+
+		<!-- test 2 -->
+		<copy file="src/test/dcff.txt" tofile="test/dcff2.txt"/>
+		<dcff file="test/dcff2.txt" startTag="quick" endTag="brown"/>
+
+		<!-- test 3 -->
+		<copy file="src/test/dcff.txt" tofile="test/dcff3.txt"/>
+		<dcff file="test/dcff3.txt" startTag="fox" leaveTags="true"/>
+
+		<!-- test 4 -->
+		<copy file="src/test/dcff.txt" tofile="test/dcff4.txt"/>
+		<dcff file="test/dcff4.txt" startTag="&lt;!--start--&gt;" endTag="&lt;!--end--&gt;"/>
+
+		<!-- test 5 -->
+		<copy file="src/test/dcff.txt" tofile="test/dcff5.txt"/>
+		<dcff file="test/dcff5.txt" startTag="&lt;!--\s*if\s*(?!.*linux)[^ ]+\s*--&gt;" endTag="&lt;!--\s*/if\s*--&gt;" />
+
+
+		</target>
+
+	<target name="test-gpv" depends="test-setup">
+
+		<!-- test 1 -->
+		<gpv propertiesFile="src/test/gpv.txt"  propertyName="startmenu.path" outputProperty="gpv.startmenu.path"/>
+		<echo>startmenu.path =  '${gpv.startmenu.path}'</echo>
+
+		<gpv propertiesFile="src/test/gpv.txt"  propertyName="my.second.property" outputProperty="gpv.my.second.property"/>
+		<echo>my.second.property = '${gpv.my.second.property}'</echo>
+
+
+	</target>
+
+	<target name="test-win-sevenzip" depends="test-setup">
+
+		<!-- test 1 -->
+		<copy file="src/test/sevenzip.lzma" tofile="test/sevenzip1.lzma"/>
+		<sevenzip task="decode" input="test/sevenzip1.lzma" output="test/sevenzip1.comp"/>
+
+	</target>
+
+	<target name="test-clean">
+		<delete dir="test"/>
+	</target>
+
+</project>
Index: /main/branches/stable_gs3/ant-tasks/src/org/greenstone/anttasks/AddGreenstoneUserToDatabase.java
===================================================================
--- /main/branches/stable_gs3/ant-tasks/src/org/greenstone/anttasks/AddGreenstoneUserToDatabase.java	(revision 21854)
+++ /main/branches/stable_gs3/ant-tasks/src/org/greenstone/anttasks/AddGreenstoneUserToDatabase.java	(revision 21854)
@@ -0,0 +1,119 @@
+/*
+ *	  AddGreenstoneUserToDatabase.java
+ *    A task to add a user to the Greenstone User Database
+ *
+ *    Copyright (C) 2008 New Zealand Digital Library, http://www.nzdl.org
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.greenstone.anttasks;
+
+import org.apache.tools.ant.*;
+import org.apache.tools.ant.taskdefs.*;
+import java.io.File;
+import java.io.BufferedWriter;
+import java.io.OutputStreamWriter;
+import lib.Crypt;
+
+public class AddGreenstoneUserToDatabase extends Task {
+
+	private File txt2db = null;
+	private File usersDb = null;
+	private String username = null;
+	private String password = null;
+	private String groups = null;
+	private String comment = null;
+
+	public static void main( String[] args ) {
+		AddGreenstoneUserToDatabase agu = new AddGreenstoneUserToDatabase();
+		agu.setTxt2db( new File(args[0]) );
+		agu.setUsersDb( new File(args[1]) );
+		agu.setUsername( args[2] );
+		agu.setPassword( args[3] );
+		agu.setGroups( args[4] );
+		agu.setComment( args[5] );
+		agu.execute();
+	}
+
+	public void execute() {
+
+		if ( txt2db == null ) { throw new BuildException( "Error - txt2db not specified!!" ); }
+		if ( usersDb == null ) { throw new BuildException( "Error - usersDb not specified!!" ); }
+		if ( username == null ) { throw new BuildException( "Error - username not specified!!" ); }
+		if ( password == null ) { throw new BuildException( "Error - password not specified!!" ); }
+		if ( groups == null ) { throw new BuildException( "Error - groups not specified!!" ); }
+		if ( comment == null ) { comment = ""; }
+
+		String encryptedPassword = Crypt.crypt("Tp", password);
+
+		long usersDbFileLastModified = 0;
+		try {
+			// Get the users.db file's last modification date so it can be reset afterwards
+			usersDbFileLastModified = usersDb.lastModified();
+		} catch (Exception exception) {
+			throw new BuildException( "Failed to get the last modified time of the users db" );
+        }
+
+		Process txt2dbProcess = null;
+		try {
+			// Write directly to the txt2db process to append to the users.db file
+			String[] cmdAndArgs = { txt2db.getAbsolutePath(), "-append", usersDb.getAbsolutePath() };
+			txt2dbProcess = Runtime.getRuntime().exec( cmdAndArgs );
+		} catch ( Exception e ) {
+			System.err.println( e.getMessage() );
+			e.printStackTrace();
+			throw new BuildException( "Failed to execute the txt2db process" );
+        }
+
+		BufferedWriter txt2dbIn = null;
+		try {
+			txt2dbIn = new BufferedWriter(new OutputStreamWriter(txt2dbProcess.getOutputStream()));
+		} catch (Exception exception) {
+			throw new BuildException( "Failed to get an input stream" );
+        }
+
+		try {
+			txt2dbIn.write("[" + username + "]"); txt2dbIn.newLine();
+			txt2dbIn.write("<comment>" + comment); txt2dbIn.newLine();
+			txt2dbIn.write("<enabled>true"); txt2dbIn.newLine();
+			txt2dbIn.write("<groups>" + groups); txt2dbIn.newLine();
+			txt2dbIn.write("<password>" + encryptedPassword); txt2dbIn.newLine();
+			txt2dbIn.write("<username>" + username); txt2dbIn.newLine();
+			txt2dbIn.write("----------------------------------------------------------------------"); txt2dbIn.newLine();
+
+			txt2dbIn.flush();
+			txt2dbIn.close();
+			txt2dbProcess.waitFor();
+
+		} catch (Exception exception) {
+			throw new BuildException( "Failed to add the user to the user database" );
+        }
+
+		try {
+			usersDb.setLastModified(usersDbFileLastModified);
+		} catch (Exception exception) {
+			throw new BuildException( "Failed to reset the last modified time of the users db" );
+        }
+
+    }
+
+	public void setTxt2db( File txt2db ) { this.txt2db = txt2db; }
+	public void setUsersDb( File usersDb ) { this.usersDb = usersDb; }
+	public void setUsername( String username ) { this.username = username; }
+	public void setPassword( String password ) { this.password = password; }
+	public void setGroups( String groups ) { this.groups = groups; }
+	public void setComment( String comment ) { this.comment = comment; }
+
+}
Index: /main/branches/stable_gs3/ant-tasks/src/org/greenstone/anttasks/DeleteChunkFromFile.java
===================================================================
--- /main/branches/stable_gs3/ant-tasks/src/org/greenstone/anttasks/DeleteChunkFromFile.java	(revision 21854)
+++ /main/branches/stable_gs3/ant-tasks/src/org/greenstone/anttasks/DeleteChunkFromFile.java	(revision 21854)
@@ -0,0 +1,214 @@
+/*
+ *    RegexSearchReplace.java
+ *    A task to delete from a given starting nugget to a given ending nugget or the end of the file
+ *
+ *    Copyright (C) 2005 New Zealand Digital Library, http://www.nzdl.org
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.greenstone.anttasks;
+
+import org.apache.tools.ant.*;
+import org.apache.tools.ant.taskdefs.*;
+import java.util.*;
+import java.io.*;
+import java.util.regex.*;
+
+
+public class DeleteChunkFromFile extends Task {
+
+	private File file = null;
+	private Pattern startTag = null;
+	private Pattern endTag = null;
+	private boolean leaveTags = false;
+
+	public static void main( String[] args ) {
+
+		DeleteChunkFromFile dcff = new DeleteChunkFromFile();
+		dcff.setFile(new File (args[0]));
+		dcff.setStartTag(args[1]);
+		dcff.setEndTag(args[2]);
+
+		dcff.execute();
+
+	}
+
+	public void execute() {
+
+		if ( file == null ) {
+			throw new BuildException( "Error - No file specified !!" );
+		}
+
+		if ( startTag == null ) {
+			throw new BuildException( "Error - No startTag specified !!" );
+		}
+		
+		System.out.println( "File: " + file );
+		System.out.println( "StartTag: " + startTag );
+		System.out.println( "EndTag: " + endTag );
+		System.out.println( "LeaveTags: " + leaveTags );
+
+		int noReplaces = 0;
+
+		//create the output stream
+		BufferedWriter out = null;
+		File temp = null;
+		try {
+			//create temp file.
+			temp = File.createTempFile("dcff", ".tmp");
+
+			//delete temp file when program exits.
+			temp.deleteOnExit();
+
+			//writer to temp file
+			out = new BufferedWriter( new OutputStreamWriter(new FileOutputStream(temp), "UTF8") );
+
+		} catch (IOException e) {
+			throw new BuildException( "Error - Couldn't create or open the temp file" );
+		}
+
+
+		//create the input stream
+		BufferedReader in = null;
+		try {
+			in = new BufferedReader( new InputStreamReader(new FileInputStream(file), "UTF8") );
+		} catch ( Exception e ) {
+			throw new BuildException( "Error - Couldn't open the specified file" );
+		}
+
+		//pass the file through, searching and replacing
+		String line;
+		boolean hasMoreLines = true;
+		boolean lookingForStartTag = true;
+		String toDefer = null;
+
+		while ( hasMoreLines ) {
+
+			//get the next line - either from the file of the leftovers from the last loop around
+			if ( toDefer != null ) {
+				line = toDefer;
+				toDefer = null;
+			} else {
+				try {
+					line = in.readLine();
+				} catch ( Exception e ) {
+					throw new BuildException( "Error - Couldn't read from the specified file" );
+				}
+			}
+
+			if ( line == null ) {
+				hasMoreLines = false;
+			} else {
+
+				String toWrite = null;
+				boolean endLine = false;
+				if ( lookingForStartTag ) {
+					Matcher m = startTag.matcher(line);
+					if ( m.find() ) {
+						lookingForStartTag = false;
+						toWrite = line.substring(0,leaveTags?m.end():m.start());
+						toDefer = line.substring(m.end());
+					} else {
+						toWrite = line;
+						endLine = true;
+					}
+				} else if ( endTag != null ) {
+					Matcher m = endTag.matcher(line);
+					if ( m.find() ) {
+						lookingForStartTag = true;
+						toDefer = line.substring(leaveTags?m.start():m.end());
+					}
+				}
+
+				if ( toWrite != null ) {
+					try {
+						out.write(toWrite);
+						if ( endLine ) {
+							out.newLine();
+						}
+					} catch ( Exception e ) {
+						throw new BuildException( "Error - Couldn't write to the temp file" );
+					}
+				}
+			}
+		}
+			
+
+		try {
+			//close them both up
+			in.close();
+			out.close();
+		} catch ( Exception e ) {
+			throw new BuildException( "Error - Couldn't close a file" );
+		}
+
+
+		//copy the new file (temp) over the original
+		InputStream i;
+		OutputStream o;
+		try {
+			i = new FileInputStream(temp);
+			o = new FileOutputStream(file);
+
+		} catch ( Exception e ) {
+			throw new BuildException( "Error - Couldn't open the temp file" );
+		}
+
+		try {
+	
+			// Transfer bytes from in to out
+			byte[] buf = new byte[1024];
+			int len;
+			while ((len = i.read(buf)) > 0) {
+			   o.write(buf, 0, len);
+			}
+
+			//close them up
+			i.close();
+			o.close();
+		} catch ( Exception e ) {
+			throw new BuildException( "Error - Couldn't write to the specified file" );
+		}
+
+		System.out.println( "Finished" );
+	}
+
+   
+	public void setFile(File file) {
+		this.file = file;
+	}
+
+	public void setStartTag(String st) {
+		try {
+			this.startTag = Pattern.compile(st);
+		} catch ( PatternSyntaxException pse ) {
+			throw new BuildException( "Invalid start tag!!" );
+		}
+	}
+
+	public void setEndTag(String et) {
+		try {
+			this.endTag = Pattern.compile(et);
+		} catch ( PatternSyntaxException pse ) {
+			throw new BuildException( "Invalid start tag!!" );
+		}
+	}
+
+	public void setLeaveTags( boolean lt ) {
+		this.leaveTags = lt;
+	}
+
+
+}
Index: /main/branches/stable_gs3/ant-tasks/src/org/greenstone/anttasks/GetFreePath.java
===================================================================
--- /main/branches/stable_gs3/ant-tasks/src/org/greenstone/anttasks/GetFreePath.java	(revision 21854)
+++ /main/branches/stable_gs3/ant-tasks/src/org/greenstone/anttasks/GetFreePath.java	(revision 21854)
@@ -0,0 +1,85 @@
+/*
+ *	  GetFreePath.java
+ *    A task to find a free folder to put something in
+ *
+ *    Copyright (C) 2008 New Zealand Digital Library, http://www.nzdl.org
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.greenstone.anttasks;
+
+import org.apache.tools.ant.*;
+import org.apache.tools.ant.taskdefs.*;
+import java.io.File;
+
+/**
+ * Returns a path, based on the given path, which does not exist on the filesystem
+ * If the given path doesn't exist on the system, just returns the path
+ * If the given path does exist, return the path appended with "(n)" where
+ * where n is the lowest possible integer greater than 1 which would result in a
+ * path that does not exist on the file system.
+ */
+public class GetFreePath extends Task {
+
+	private File path = null;
+	private String property = null;
+
+	/**
+	 * for testing
+	 */
+	public static void main( String[] args ) {
+		GetFreePath gfp = new GetFreePath();
+		gfp.setPath( new File(args[0]) );
+		gfp.setProperty( args[1] );
+		gfp.execute();
+	}
+
+	public void execute() {
+
+		//check both attributes set
+		if ( path == null ) {
+			throw new BuildException( "Error - No path specified !!" );
+		}
+
+		if ( property == null ) {
+			throw new BuildException( "Error - No property specified !!" );
+		}
+
+		//find a free path
+		File returnPath = new File(path.getPath());
+		for ( int i=2; returnPath.exists(); i++ ) {
+			returnPath = new File(path.getPath() + "(" + i + ")" );
+		}
+
+		//set the found path in the project
+		Project pr = getProject();
+		if ( pr != null && pr.getProperty(property) == null ) {
+			pr.setProperty( property, returnPath.getPath() );
+		}
+		System.out.println(returnPath.getPath());
+		
+
+	}
+
+   
+	public void setPath(File path) {
+		this.path = path;
+	}
+
+	public void setProperty(String property) {
+		this.property = property;
+	}
+
+}
Index: /main/branches/stable_gs3/ant-tasks/src/org/greenstone/anttasks/GetPropertyValue.java
===================================================================
--- /main/branches/stable_gs3/ant-tasks/src/org/greenstone/anttasks/GetPropertyValue.java	(revision 21854)
+++ /main/branches/stable_gs3/ant-tasks/src/org/greenstone/anttasks/GetPropertyValue.java	(revision 21854)
@@ -0,0 +1,134 @@
+/*
+ *    GetPropertyValue.java
+ *    A task to get the value of a given property from a given properties file
+ *
+ *    Copyright (C) 2005 New Zealand Digital Library, http://www.nzdl.org
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.greenstone.anttasks;
+
+import org.apache.tools.ant.*;
+import org.apache.tools.ant.taskdefs.*;
+import java.util.*;
+import java.io.*;
+import java.util.regex.*;
+
+/**
+ * Gets looks up a property in a properties file and returns its value
+ */
+public class GetPropertyValue extends Task {
+
+	private File propertiesFile = null;
+	private String propertyName = null;
+	private String outputProperty = null;
+	
+
+	/**
+	 * for testing
+
+	public static void main( String[] args ) {
+
+		GetPropertyValue gpv = new GetPropertyValue();
+		gpv.setPropertiesFile( new File(args[0]) );
+		gpv.setPropertyName( args[1] );
+		gpv.setOutputProperty( args[2] );
+		gpv.execute();
+
+	}
+	 */
+
+	public void execute() {
+
+		if ( propertiesFile == null ) {
+			throw new BuildException( "Error - No properties file specified !!" );
+		}
+
+		if ( propertyName == null ) {
+			throw new BuildException( "Error - No property name specified !!" );
+		}
+
+		if ( outputProperty == null ) {
+			throw new BuildException( "Error - No output property specified !!" );
+		}
+
+		//compile the regex we're looking for
+		//System.err.println( "compile the regex we're looking for" );
+		String regex = "^" + propertyName.replaceAll("\\.","\\\\.") + "[:=]\\s*(.*)$";
+		//System.err.println( "regex: " + regex );
+		Pattern wantedLine = Pattern.compile( regex );
+
+		//create the input stream
+		//System.err.println( "create the input stream" );
+		BufferedReader in = null;
+		try {
+			in = new BufferedReader(new FileReader( propertiesFile ));
+		} catch ( Exception e ) {
+			throw new BuildException( "Error - couldn't open the properties file " + propertiesFile );
+		}
+
+		//System.err.println( "pass over the file" );
+		//pass over the file
+		String line, value = null;
+
+		try {
+			
+			boolean found = false;
+			while ( (line = in.readLine()) != null && !found ) {
+
+				Matcher matcher = wantedLine.matcher( line );
+				if ( matcher.matches() ) {
+					//found the property
+					//System.err.println( "found the property" );
+					value = matcher.group(1);
+					value = value.replaceAll( "#.*", "" ).trim();
+					found = true;
+				}
+
+
+			}
+
+			//close the input stream
+			//System.err.println( "close the input stream" );
+			in.close();
+
+		} catch ( Exception e ) {
+			throw new BuildException( "Error - couldn't read from the properties file" );
+		}
+
+		//set the property in ant
+		if ( value != null ) {
+			//System.err.println( "set the property in ant" );
+			this.getProject().setProperty(outputProperty, value);
+		}
+
+		//System.err.println( "done" );
+
+	}
+
+   
+	public void setPropertiesFile(File file) {
+		this.propertiesFile = file;
+	}
+
+	public void setPropertyName(String name) {
+		this.propertyName = name;
+	}
+
+	public void setOutputProperty(String property) {
+		this.outputProperty = property;
+	}
+
+}
Index: /main/branches/stable_gs3/ant-tasks/src/org/greenstone/anttasks/MyGetUserAndPassword.java
===================================================================
--- /main/branches/stable_gs3/ant-tasks/src/org/greenstone/anttasks/MyGetUserAndPassword.java	(revision 21854)
+++ /main/branches/stable_gs3/ant-tasks/src/org/greenstone/anttasks/MyGetUserAndPassword.java	(revision 21854)
@@ -0,0 +1,235 @@
+/*
+ *    MyGetUserAndPassword.java
+ *    Copyright (C) 2005 New Zealand Digital Library, http://www.nzdl.org
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.greenstone.anttasks;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.event.*;
+
+/** A new ant task to prompt the user for username and password.
+ * To use this task, the compiled class must be put in the classpath. add a taskdef line to the build.xml:
+ * <taskdef name="getuserandpassword" classname="org.greenstone.anttasks.MyGetUserAndPassword" />
+ * and call it like the following:
+ *  <getuserandpassword 
+ *       message="a message to display at the top of the dialog" 
+ *       userproperty="the name of the username property to set (optional)" 
+ *       pwordproperty="the name of the password property to set" 
+ *       username="default value for username (optional)" 
+ *       if="property name (optional)" 
+ *       unless="property name (optional)"/>
+ * the if and unless attributes are used to control whether this task runs or not. If the 'if' attribute is set, the task will only run if the specified property is defined. If the unless attribute is set, the task will only run if the property is not defined.
+*/
+
+public class MyGetUserAndPassword
+    extends org.apache.tools.ant.Task {
+    
+    private String message = null;
+    private String user_property = null;
+    private String pword_property = null;
+    private String username = null;
+    private String password = null;
+    private boolean cancelled = false;
+
+    private Dimension SIZE = new Dimension(300, 150);
+    private JButton ok_button = null;
+    private JTextField name_field = null;
+    private JPasswordField pass_field = null;
+    
+    private boolean do_the_task = true;
+    public void setMessage(String m) {
+	message = m;
+    }
+
+    /** specify a property name - the task will only execute if this property is set */
+    public void setIf(String property) {
+	String value = getProject().getProperty(property);
+	if (value== null) {
+	    do_the_task = false;
+	}
+    }
+
+    public void setPwordproperty(String p_prop) {
+	pword_property = p_prop;
+    }
+    
+    /** specify a property name - the task will only execute if this property is not set */
+    public void setUnless(String property) {
+	String value = getProject().getProperty(property);
+	if (value != null) {
+	    do_the_task = false;
+	}
+    }
+    
+    public void setUsername(String user) {
+	username = user;
+    }
+
+    public void setUserproperty(String u_prop) {
+	user_property = u_prop;
+    }
+    public void execute() throws org.apache.tools.ant.BuildException {
+	
+	if (!do_the_task) {
+	    return;
+	}
+	if (pword_property == null) {
+	    throw new org.apache.tools.ant.BuildException("pwordproperty attribute must be specified");
+	}
+	
+	JFrame hiddenFrame = new JFrame("Username and Password Hidden Frame");
+	final JDialog dialog = new JDialog(hiddenFrame, "Username and Password", true);
+	JPanel content_pane = (JPanel)dialog.getContentPane();
+	content_pane.setLayout(new BorderLayout(5,5));
+	content_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
+	dialog.setLocation(200, 300);
+	dialog.setSize(SIZE);
+	dialog.addWindowListener(new WindowAdapter() {
+		public void windowClosing(WindowEvent windowEvent) {
+		    cancelled = true;
+		    dialog.dispose();
+		} 
+	    });
+	
+	JPanel button_pane = new JPanel();
+	button_pane.setLayout(new GridLayout(1,2));
+	JPanel details_pane = new JPanel();
+	details_pane.setLayout(new BorderLayout(5,5));
+	JPanel labels_pane = new JPanel();
+	labels_pane.setLayout(new GridLayout(2,1));
+	JPanel fields_pane = new JPanel();
+	fields_pane.setLayout(new GridLayout(2,1));
+	
+        JTextArea instruction_textarea = new JTextArea();
+	instruction_textarea.setEditable(false);
+	instruction_textarea.setLineWrap(true);
+	instruction_textarea.setRows(2);
+	instruction_textarea.setWrapStyleWord(true);
+	if (message == null) {
+	    message = "Please enter your username and password";
+	}
+	instruction_textarea.setText(message);
+		
+	JLabel name_label = new JLabel("User name:");
+	name_field = new JTextField(16);
+	if (username != null) {
+	    name_field.setText(username);
+	}
+	if (user_property == null ) {
+	    name_field.setEditable(false);
+	} 
+	JLabel pass_label = new JLabel("Password:");
+	pass_field = new JPasswordField(16);
+	
+	FieldListener field_listener = new FieldListener();
+	name_field.addActionListener(field_listener);
+	name_field.getDocument().addDocumentListener(field_listener);
+	pass_field.addActionListener(field_listener);
+	pass_field.getDocument().addDocumentListener(field_listener);
+
+	ok_button = new JButton("Ok");
+	ok_button.setEnabled(false);
+	ok_button.addActionListener(new ActionListener() {
+		public void actionPerformed(ActionEvent actionEvent) {
+		    username = name_field.getText();
+		    password = new String(pass_field.getPassword());
+		    dialog.dispose();
+		}
+	    });
+		
+	JButton cancel_button = new JButton("Cancel");
+	cancel_button.addActionListener(new ActionListener() {
+		public void actionPerformed(ActionEvent actionEvent) {
+		    cancelled = true;
+		    dialog.dispose();
+		}
+	    });
+	
+	button_pane.add(ok_button);
+	button_pane.add(cancel_button);
+		
+	labels_pane.add(name_label);
+	labels_pane.add(pass_label);
+
+	fields_pane.add(name_field);
+	fields_pane.add(pass_field);
+
+	details_pane.add(labels_pane, BorderLayout.WEST);
+	details_pane.add(fields_pane, BorderLayout.CENTER);
+	
+	content_pane.add(instruction_textarea, BorderLayout.NORTH);
+	content_pane.add(details_pane, BorderLayout.CENTER);
+	content_pane.add(button_pane, BorderLayout.SOUTH);
+		
+	dialog.show();
+	hiddenFrame.dispose();
+
+	if (cancelled) {
+	    throw new org.apache.tools.ant.BuildException("Cancelled by user.");
+	}
+	
+	if (user_property != null) {
+	    getProject().setProperty(user_property, username);
+	}
+	getProject().setProperty(pword_property, password);
+	
+	
+	
+    }
+    private class FieldListener
+	implements ActionListener, DocumentListener {
+	
+	public void actionPerformed(ActionEvent actionEvent) {
+	    validateOkButton();
+	}
+	public void changedUpdate(DocumentEvent e) {
+	    
+	    validateOkButton();
+	}
+
+	public void insertUpdate(DocumentEvent e) {
+            
+	    validateOkButton();
+	}
+	
+	public void removeUpdate(DocumentEvent e) {
+            
+	    validateOkButton();
+	}
+	
+	private void validateOkButton() {
+	    if (name_field.getText().length()!=0 && 
+		pass_field.getPassword().length!=0) {		
+		ok_button.setEnabled(true);
+	    } else {
+		ok_button.setEnabled(false);
+	    }
+	}
+    }
+    
+
+    public static void main(String [] args) {
+	MyGetUserAndPassword task = new MyGetUserAndPassword();
+	task.setMessage("hi there kath");
+	task.setUserproperty("username");
+	task.setPwordproperty("password");
+	task.execute();
+
+    }
+}
Index: /main/branches/stable_gs3/ant-tasks/src/org/greenstone/anttasks/MySetProxy.java
===================================================================
--- /main/branches/stable_gs3/ant-tasks/src/org/greenstone/anttasks/MySetProxy.java	(revision 21854)
+++ /main/branches/stable_gs3/ant-tasks/src/org/greenstone/anttasks/MySetProxy.java	(revision 21854)
@@ -0,0 +1,70 @@
+/*
+ *    MyGetUserAndPassword.java
+ *    Copyright (C) 2005 New Zealand Digital Library, http://www.nzdl.org
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.greenstone.anttasks;
+
+import java.net.Authenticator;
+import java.net.PasswordAuthentication;      
+
+/** A new ant task for as the setproxy task has a bug in it.
+ * To use this task, the compiled class must be put in the classpath. add a taskdef line to the build.xml:
+ * <taskdef name="mysetproxy" classname="MySetProxy" />
+ * and call it like the following:
+ *  <mysetproxy proxyhost="" proxyport="" proxyuser="" proxypassword=""/>
+*/
+public class MySetProxy 
+    extends org.apache.tools.ant.Task {
+
+    String host = null;
+    String port = null;
+    String user = null;
+    String password = null;
+
+    public void setProxyhost(String proxy_host) {
+	host = proxy_host;
+    }
+
+    public void setProxyPort(int proxy_port) {
+	port = Integer.toString(proxy_port);
+    }
+
+    public void setProxyuser(String proxy_user) {
+	user = proxy_user;
+    }
+    
+    public void setProxypassword(String proxy_password) {
+	password = proxy_password;
+    }
+
+    public void execute() {
+
+	try {
+	    System.setProperty("http.proxyType", "4");
+	    System.setProperty("http.proxyHost", host);
+	    System.setProperty("http.proxyPort", port);
+	    System.setProperty("http.proxySet", "true");
+	    Authenticator.setDefault(new Authenticator(){ 
+		    protected PasswordAuthentication getPasswordAuthentication(){ 
+			return new PasswordAuthentication(user, new String(password).toCharArray()); 
+		    } 
+		}); 
+	} catch (Exception e) {
+	    System.err.println("MySetProxy Error: couldn't set up the proxy");    
+	}
+    }
+}
Index: /main/branches/stable_gs3/ant-tasks/src/org/greenstone/anttasks/RegexSearchReplace.java
===================================================================
--- /main/branches/stable_gs3/ant-tasks/src/org/greenstone/anttasks/RegexSearchReplace.java	(revision 21854)
+++ /main/branches/stable_gs3/ant-tasks/src/org/greenstone/anttasks/RegexSearchReplace.java	(revision 21854)
@@ -0,0 +1,331 @@
+/*
+ *    RegexSearchReplace.java
+ *    A task to replace occurences of a given pattern with a given replacement in a given file
+ *
+ *    Copyright (C) 2005 New Zealand Digital Library, http://www.nzdl.org
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.greenstone.anttasks;
+
+import java.util.ArrayList;
+import org.apache.tools.ant.*;
+import org.apache.tools.ant.taskdefs.*;
+import java.util.*;
+import java.io.*;
+import java.util.regex.*;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.DirectoryScanner;
+
+public class RegexSearchReplace extends Task {
+
+	private File file = null;
+	private ArrayList jobs = null;
+	private FileSet fileset = null;
+	private String pattern = null;
+	private String replacement = null;
+	private int fromLine = -1;
+	private int toLine = -1;
+	private boolean winPath = false;
+
+	public static void main( String[] args ) {
+
+		RegexSearchReplace rsr = new RegexSearchReplace();
+		rsr.setFile(new File (args[0]));
+		rsr.setPattern(args[1]);
+		rsr.setReplacement(args[2]);
+		rsr.setLines(args[3]);
+
+		rsr.execute();
+
+	}
+
+	public void execute() {
+
+		if ( file == null && fileset == null ) {
+			throw new BuildException( "Error - No file or fileset specified !!" );
+		}
+
+		if ( file != null && !file.exists() ) {
+			throw new BuildException( "Error - File not found !!" );
+		}
+
+		DirectoryScanner dirScanner = null;
+		if ( fileset != null ) {
+			dirScanner = fileset.getDirectoryScanner(project);
+			dirScanner.scan();
+		}
+
+		if ( jobs == null && pattern == null ) {
+			throw new BuildException( "Error - No pattern attribute and no nested jobs !!" );
+		}
+
+		if ( jobs != null && pattern != null ) {
+			throw new BuildException( "Error - Both pattern attribute and nested jobs given !!" );
+		}
+
+		if ( pattern != null && replacement == null ) {
+			throw new BuildException( "Error - pattern attribute given but no replacement attribute given !!" );
+		}
+
+		if ( jobs != null ) {
+			for ( int i=0; i<jobs.size(); i++ ) {
+				if ( ((RegexSearchReplaceJob)(jobs.get(i))).getPattern() == null ) {
+					throw new BuildException( "Error - One of the jobs lacks a pattern!!" );
+				}
+				if ( ((RegexSearchReplaceJob)(jobs.get(i))).getReplacement() == null ) {
+					throw new BuildException( "Error - One of the jobs lacks a replacement!!" );
+				}
+			}
+		}
+
+
+		//sus out filename(s)
+		File[] files = null;
+		if ( file != null ) {
+			files = new File[1];
+			files[0] = file;
+		} else {
+			String[] fileStrings = dirScanner.getIncludedFiles();
+			files = new File[fileStrings.length];
+			for ( int i=0; i<fileStrings.length; i++ ) {
+				files[i] = new File( dirScanner.getBasedir() + File.separator + fileStrings[i] );
+			}
+		}
+
+		//output greeting
+		System.out.println( "--------------------" );
+		System.out.println( " RegexSearchReplace " );
+		System.out.println( "--------------------" );
+
+		//output replacement(s)
+		System.out.println( "Replacements:" );
+		if ( pattern != null ) {
+			System.out.println( " " + pattern + " -> " + replacement );
+		} else {
+			for ( int i=0; i<jobs.size(); i++ ) {
+				System.out.println( " " + ((RegexSearchReplaceJob)(jobs.get(i))).getPattern() + " -> " + ((RegexSearchReplaceJob)(jobs.get(i))).getReplacement() );
+			}
+		}
+		System.out.println();
+
+		//output lines if necessary
+		if ( this.fromLine != -1 || this.toLine != -1 ) {
+			System.out.println( "Lines: " + (this.fromLine==-1?"Start":Integer.toString(this.fromLine)) + " ~ " + (this.toLine==-1?"End":Integer.toString(this.toLine)) );
+			System.out.println();
+		}
+
+		System.out.println( "Files: " );
+		for ( int fileIndex=0; fileIndex<files.length; fileIndex++ ) {
+
+			int noReplaces = 0;
+
+			File inputFile = files[fileIndex];
+			System.out.println( " " + inputFile );
+
+			//create the output stream
+			BufferedWriter out = null;
+			File temp = null;
+			try {
+				//create temp file.
+				temp = File.createTempFile("rsr", ".tmp");
+
+				//delete temp file when program exits.
+				temp.deleteOnExit();
+
+				//writer to temp file
+				out = new BufferedWriter( new OutputStreamWriter(new FileOutputStream(temp), "UTF8") );
+
+			} catch (IOException e) {
+				throw new BuildException( "Error - Couldn't create or open the temp file" );
+			}
+
+
+			//create the input stream
+			BufferedReader in = null;
+			try {
+				in = new BufferedReader( new InputStreamReader(new FileInputStream(inputFile), "UTF8") );
+			} catch ( Exception e ) {
+				throw new BuildException( "Error - Couldn't open the specified file" );
+			}
+
+			//pass the file through, searching and replacing
+			String line = null;
+			int lineNumber = 1;
+			boolean hasMoreLines = true;
+			while ( hasMoreLines ) {
+
+				try {
+					line = in.readLine();
+				} catch ( Exception e ) {
+					System.err.println( e.getMessage() );
+					throw new BuildException( "Error - Couldn't read from the specified file" );
+				}
+
+				if ( line == null ) {
+					hasMoreLines = false;
+				} else {
+
+					//only if within the given line range
+					if ( ( fromLine == -1 || lineNumber >= fromLine ) && ( toLine == -1 || lineNumber < toLine ) ) {
+						String oldLine = line;
+						if ( pattern != null ) {
+							String rp = replacement;
+							if ( winPath ) {
+								rp = rp.replaceAll("\\\\","\\\\\\\\");
+							}
+							line = line.replaceAll((String)pattern, (String)rp);
+						} else {
+							for ( int i=0; i<jobs.size(); i++ ) {
+								String rp = ((RegexSearchReplaceJob)(jobs.get(i))).getReplacement();
+								if ( ((RegexSearchReplaceJob)(jobs.get(i))).getWinPath() ) {
+									rp = rp.replaceAll("\\\\","\\\\\\\\");
+								}
+								line = line.replaceAll( ((RegexSearchReplaceJob)(jobs.get(i))).getPattern(), rp );
+							}
+						}
+
+						if ( !oldLine.equals( line ) ) {
+							noReplaces++;
+						}
+					}
+
+					try {
+						out.write( line );
+						out.newLine();
+					} catch ( Exception e ) {
+						throw new BuildException( "Error - Couldn't write to the temp file" );
+					}
+				}
+				lineNumber++;
+			}
+			
+			try {
+				//close them both up
+				in.close();
+				out.close();
+			} catch ( Exception e ) {
+				throw new BuildException( "Error - Couldn't close a file" );
+			}
+
+
+			//copy the new file (temp) over the original
+			InputStream i;
+			OutputStream o;
+			try {
+				i = new FileInputStream(temp);
+				o = new FileOutputStream(inputFile);
+
+			} catch ( Exception e ) {
+				throw new BuildException( "Error - Couldn't open the temp file" );
+			}
+
+			try {
+		
+				// Transfer bytes from in to out
+				byte[] buf = new byte[1024];
+				int len;
+				while ((len = i.read(buf)) > 0) {
+				   o.write(buf, 0, len);
+				}
+
+				//close them up
+				i.close();
+				o.close();
+			} catch ( Exception e ) {
+				throw new BuildException( "Error - Couldn't write to the specified file" );
+			}
+
+		
+			if ( noReplaces == 0 ) {
+				System.out.println( " No Changes Made" );
+			} else if ( noReplaces == 1 ) {
+				System.out.println( " Successfully changed 1 line" );
+			} else {
+				System.out.println( " Successfully changed " + noReplaces + " lines" );
+			}
+			System.out.println();
+
+		}
+
+	}
+
+	public void setFile(File file) {
+		if ( this.fileset != null || this.file != null ) {
+			throw new BuildException( "Error - Only one file or one fileset may be given!!" );
+		}
+		this.file = file;
+	}
+
+	public void setLines(String lines) {
+		//lines should be in the form "2" or "2-5"
+
+		//trim
+		lines.replaceAll("\\s","");
+
+		if ( lines == "" ) {
+			throw new BuildException( "Error - no line number(s) given in lines attribute!! " );
+		}
+
+		//split into parts
+		String[] parts = lines.split("-",2);
+
+		try {
+			if ( parts.length == 1 ) {
+				this.fromLine = Integer.parseInt( parts[0] );
+				this.toLine = this.fromLine + 1;
+			} else {
+				if ( !parts[0].equals("") ) this.fromLine = Integer.parseInt( parts[0] );
+				if ( !parts[1].equals("") ) this.toLine = Integer.parseInt( parts[1] );
+			}
+		} catch( NumberFormatException nfe ) {
+			throw new BuildException( "Error - invalid line numbers given in lines attribute!! '" + parts[0] + "' - '" + parts[1] + "'" );
+		}
+
+	}
+
+
+	public void setPattern(String pattern) {
+		this.pattern = pattern;
+	}
+
+	public void setReplacement(String replacement) {
+		replacement = replacement.replaceAll( "\\\\", "\\\\\\\\" );
+		this.replacement = replacement;
+	}
+
+	public void setWinPath( boolean isWinPath ) {
+		this.winPath = isWinPath;
+	}
+
+	public RegexSearchReplaceJob createJob() {
+		RegexSearchReplaceJob job = new RegexSearchReplaceJob();
+		if ( jobs == null ) {
+			jobs = new ArrayList();
+		}
+		jobs.add( job );
+		return job;
+
+	}
+
+	public FileSet createFileset() {
+		if ( this.fileset != null || this.file != null ) {
+			throw new BuildException( "Error - Only one file or one fileset may be given!!" );
+		}
+		fileset = new FileSet();
+		return fileset;
+	}
+
+}
Index: /main/branches/stable_gs3/ant-tasks/src/org/greenstone/anttasks/RegexSearchReplaceJob.java
===================================================================
--- /main/branches/stable_gs3/ant-tasks/src/org/greenstone/anttasks/RegexSearchReplaceJob.java	(revision 21854)
+++ /main/branches/stable_gs3/ant-tasks/src/org/greenstone/anttasks/RegexSearchReplaceJob.java	(revision 21854)
@@ -0,0 +1,32 @@
+package org.greenstone.anttasks;
+public class RegexSearchReplaceJob extends org.apache.tools.ant.types.DataType {
+
+	String pattern = null;
+	String replacement = null;
+	boolean winPath = false;
+
+	public void setPattern(String pattern) {
+		this.pattern = pattern;
+	}
+
+	public void setReplacement(String replacement) {
+		replacement = replacement.replaceAll( "\\\\", "\\\\\\\\" );
+		this.replacement = replacement;
+	}
+
+	public void setWinPath( boolean winPath ) {
+		this.winPath = winPath;
+	}
+
+	public String getPattern() {
+		return pattern;
+	}
+	public String getReplacement() {
+		return replacement;
+	}
+	public boolean getWinPath() {
+		return winPath;
+	}
+
+}
+
Index: /main/branches/stable_gs3/ant-tasks/src/org/greenstone/anttasks/SplitResource.java
===================================================================
--- /main/branches/stable_gs3/ant-tasks/src/org/greenstone/anttasks/SplitResource.java	(revision 21854)
+++ /main/branches/stable_gs3/ant-tasks/src/org/greenstone/anttasks/SplitResource.java	(revision 21854)
@@ -0,0 +1,200 @@
+/*
+ *    SplitResource.java
+ *    A task to split a file into chunks and optionally add references to those
+ *    chunks in an rc (resource compiler) script
+ *
+ *    Copyright (C) 2005 New Zealand Digital Library, http://www.nzdl.org
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.greenstone.anttasks;
+
+import org.apache.tools.ant.*;
+import org.apache.tools.ant.taskdefs.*;
+import java.util.*;
+import java.io.*;
+import java.util.regex.*;
+
+/**
+ * Splits a file (resource) into chunks of a given size and puts them in files 
+ * with the same name as the resource but appended with a dot followed by the chunk number
+ */
+public class SplitResource extends Task {
+
+	private File resource = null;
+	private File resourceScript = null;
+	private File outputDir = null;
+	private String resourceName = null;
+	private String resourceType = null;
+	private int chunkSize = 0;
+	
+
+	/**
+	 * for testing
+	 */
+	public static void main( String[] args ) {
+
+		SplitResource sr = new SplitResource();
+		sr.setResource( new File(args[0]) );
+		sr.setOutputDir( new File(args[1]) );
+		sr.setResourceScript( new File(args[2]) );
+		sr.setResourceName( args[3] );
+		sr.setResourceType( args[4] );
+		sr.setChunkSize( Integer.parseInt(args[5]) );
+		sr.execute();
+
+	}
+
+	public void execute() {
+
+		if ( resource == null ) {
+			throw new BuildException( "Error - No resource specified !!" );
+		}
+
+		if ( outputDir == null ) {
+			outputDir = new File(".");
+		}
+		outputDir.mkdir();
+
+		if ( chunkSize == 0 ) {
+			throw new BuildException( "Error - No chunk size specified !!" );
+		}
+
+		DataInputStream is;
+
+		try {
+			is = new DataInputStream( new FileInputStream( resource ) );
+		} catch ( IOException e ) {
+			throw new BuildException( "Error - couldn't open the resource file" );
+		}
+
+		//figure out how many chunks to do this in
+		int noChunks = (int)(resource.length() / chunkSize) + 1;
+
+		System.out.println( "Splitting file into chunks" );
+		System.out.println( "file: " + resource.getAbsolutePath() );
+		System.out.println( "file size: " + resource.length() );
+		System.out.println( "chunk size: " + chunkSize );
+		System.out.println( "ergo, num chunks: " + noChunks );
+
+		long written = 0;
+		for ( int i=0; i<noChunks; i++  ) {
+
+			//open a file for output
+			DataOutputStream os;
+			File partFile = new File( outputDir, resource.getName() + "." + i );
+			//System.out.println( "partFile: " + partFile );
+
+			try {
+				os = new DataOutputStream( new FileOutputStream( partFile ) );
+			} catch ( IOException e ) {
+				throw new BuildException( "Error - couldn't create a part file" );
+			}
+
+
+			//sort out thisChunkSize
+			int thisChunkSize = chunkSize;
+			if ( i == noChunks - 1 ) {
+				//System.out.println( "(Last Chunk)");
+				thisChunkSize = (int)(resource.length() % chunkSize);
+			}
+
+			//System.out.println( "Read a chunk (" + thisChunkSize + " bytes)" );
+			byte[] data = new byte[thisChunkSize];
+			try {
+				is.readFully( data, 0, thisChunkSize );
+			} catch( EOFException eof ) {
+				throw new BuildException( "Error - unexpectedly hit the end of the resource file" );
+			} catch ( IOException e ) {
+				throw new BuildException( "Error - couldn't read a byte from the resource file" );
+			}
+
+			//System.out.println( "Write to the file");
+			try {
+				os.write( data, 0, thisChunkSize );
+				written += thisChunkSize;
+			} catch ( IOException e ) {
+				throw new BuildException( "Error - couldn't write out a byte to the part file" );
+			}
+
+			try {
+				os.close();
+			} catch ( IOException e ) {
+				throw new BuildException( "Error - couldn't close a chunk output stream" );
+			}
+      }
+		
+		//System.out.println( "Total written: " + written + " bytes" );
+
+		try {
+	      is.close();
+		} catch ( IOException e ) {
+			throw new BuildException( "Error - couldn't close the input stream" );
+		}
+
+
+		//if they have specified a resource script and resource name, write an rc file
+		if ( resourceScript != null && resourceName != null && resourceType != null ) {
+			System.out.println( "Putting references into a resource script" );
+			System.out.println( "resourceScript: " + resourceScript.getAbsolutePath() );
+			System.out.println( "resourceName  : " + resourceName );
+			System.out.println( "resourceType  : " + resourceType );
+			
+			//open the resource script
+			PrintWriter out = null;
+			try {
+				out = new PrintWriter(new FileWriter( resourceScript, true ));
+			} catch ( IOException e ) {
+				throw new BuildException( "Error - couldn't open the resource script" );
+			}
+
+			//put a line in for each chunk
+			for ( int i=0; i<noChunks; i++ ){
+				out.println(
+					resourceName + "_" + (i+1) + " " + resourceType + " \"" + resource.getName() + "." + i + "\""
+					);
+			}
+			
+			//close the resource script
+  		   out.close();
+		}
+	}
+
+   
+	public void setResource(File resource) {
+		this.resource = resource;
+	}
+
+	public void setResourceScript(File resourceScript) {
+		this.resourceScript = resourceScript;
+	}
+
+	public void setResourceName(String resourceName) {
+		this.resourceName = resourceName;
+	}
+	public void setResourceType(String resourceType) {
+		this.resourceType = resourceType;
+	}
+
+	public void setOutputDir(File outputDir) {
+		this.outputDir = outputDir;
+	}
+
+	public void setChunkSize(int chunkSize) {
+		this.chunkSize = chunkSize;
+	}
+
+}
Index: /main/branches/stable_gs3/ant-tasks/src/test/dcff.txt
===================================================================
--- /main/branches/stable_gs3/ant-tasks/src/test/dcff.txt	(revision 21854)
+++ /main/branches/stable_gs3/ant-tasks/src/test/dcff.txt	(revision 21854)
@@ -0,0 +1,29 @@
+The
+quick
+brown
+fox
+jumps
+over
+a
+lazy
+dog
+
+FranÃ§ais
+EspaÃ±ol
+ÑÑÑÑÐºÐžÐ¹ ÑÐ·ÑÐº
+äž­æ
+
+more text
+b<!--start-->row<!--end-->n
+
+<!-- if linux -->
+linux stuff
+<!-- /if -->
+<!-- if windows -->
+windows stuff -->
+<!-- /if -->
+<!-- if mac|windows -->
+mac and windows stuff
+<!-- /if -->
+
+even more text
Index: /main/branches/stable_gs3/ant-tasks/src/test/gpv.txt
===================================================================
--- /main/branches/stable_gs3/ant-tasks/src/test/gpv.txt	(revision 21854)
+++ /main/branches/stable_gs3/ant-tasks/src/test/gpv.txt	(revision 21854)
@@ -0,0 +1,10 @@
+
+startmenu.path:/home/oranfry/Start Menu/Greenstone-2s2008.11.12
+my.second.property:/home/oranfry/Start Menu/Greenstone2s2008.11.12 # a tail comment
+
+#a lone comment
+
+#a commented out property
+#commented.out:out
+commented.out:in
+
Index: /main/branches/stable_gs3/ant-tasks/src/test/rsr.txt
===================================================================
--- /main/branches/stable_gs3/ant-tasks/src/test/rsr.txt	(revision 21854)
+++ /main/branches/stable_gs3/ant-tasks/src/test/rsr.txt	(revision 21854)
@@ -0,0 +1,20 @@
+This is a test of the rsr task
+To see if it can replace strings with other strings
+Or if those strings
+Stay the same strings
+
+Or not
+
+Replace with a path
+@path@
+
+Replace with a path, with winPath on
+@path-with-winpath@
+
+English
+FranÃ§ais
+EspaÃ±ol
+ÑÑÑÑÐºÐžÐ¹ ÑÐ·ÑÐº
+äž­æ
+
+
