First steps at build simplification.
Removed Class-Path manifest entries for Squiggle and Rasterizer.
Introduced AppStarterUtil that handles the dynamic classpath setup when invoked using "java -jar" to make Class-Path manifest entries unnecessary.
Simplified javac class by using Ant's presetdef.

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/batik/branches/build-simplification@1066387 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/build.xml b/build.xml
index 4b85892..b637bde 100644
--- a/build.xml
+++ b/build.xml
@@ -92,7 +92,9 @@
     <property name="debug"              value="off"/>
     <property name="optimize"           value="on"/>
     <property name="deprecation"        value="on"/>
-  
+    <property name="javac.source"       value="1.5"/>
+    <property name="javac.target"       value="1.5"/>
+    
     <property name="src"                value="sources"/>
     <property name="src-internal-codec" value="sources-internal-codec"/>
     <property name="resources"          value="resources"/>
@@ -218,6 +220,11 @@
     <echo message="    JAVA_HOME: ${env.JAVA_HOME}"/>
     <echo message="    VM:        ${java.vm.version}, ${java.vm.vendor}"/>
 
+    <presetdef name="javac">
+      <javac source="${javac.source}" target="${javac.target}"
+        debug="${debug}" deprecation="${deprecation}" optimize="${optimize}"/>
+    </presetdef>
+    
     <property name="init.done" value="true"/>
   </target>
 
@@ -577,8 +584,7 @@
         <attribute name="Implementation-Version" value="${completeVersion}${svn-revision-suffix}"/>
         <attribute name="Implementation-Vendor" value="The Apache Software Foundation (http://xmlgraphics.apache.org/batik/)"/>
         <attribute name="Build-Id" value="${build.id}"/>
-        <attribute name="Main-Class" value="org.apache.batik.apps.rasterizer.Main"/>
-        <attribute name="Class-Path" value="batik-ext-${completeVersion}.jar batik-dom-${completeVersion}.jar batik-css-${completeVersion}.jar batik-svg-dom-${completeVersion}.jar batik-gvt-${completeVersion}.jar batik-parser-${completeVersion}.jar batik-script-${completeVersion}.jar batik-bridge-${completeVersion}.jar batik-anim-${completeVersion}.jar batik-transcoder-${completeVersion}.jar batik-awt-util-${completeVersion}.jar batik-codec-${completeVersion}.jar batik-util-${completeVersion}.jar batik-xml-${completeVersion}.jar xerces-2.5.0.jar xalan-2.6.0.jar xml-apis-1.3.04.jar xml-apis-ext-1.3.04.jar fop-0.94.jar batik-js.jar"/>
+        <attribute name="Main-Class" value="org.apache.batik.apps.rasterizer.DynamicMain"/>
       </manifest>
       <metainf dir="${basedir}" includes="LICENSE,NOTICE"/>
       <fileset dir="${dest}">
@@ -645,12 +651,11 @@
         <attribute name="Implementation-Version" value="${completeVersion}${svn-revision-suffix}"/>
         <attribute name="Implementation-Vendor" value="The Apache Software Foundation (http://xmlgraphics.apache.org/batik/)"/>
         <attribute name="Build-Id" value="${build.id}"/>
-        <attribute name="Main-Class" value="org.apache.batik.apps.svgbrowser.Main"/>
-        <attribute name="Class-Path" value="batik-ext-${completeVersion}.jar batik-dom-${completeVersion}.jar batik-css-${completeVersion}.jar batik-svg-dom-${completeVersion}.jar batik-gvt-${completeVersion}.jar batik-parser-${completeVersion}.jar batik-script-${completeVersion}.jar batik-bridge-${completeVersion}.jar batik-swing-${completeVersion}.jar batik-anim-${completeVersion}.jar batik-transcoder-${completeVersion}.jar batik-gui-util-${completeVersion}.jar batik-awt-util-${completeVersion}.jar batik-codec-${completeVersion}.jar batik-util-${completeVersion}.jar batik-xml-${completeVersion}.jar xerces-2.5.0.jar xalan-2.6.0.jar xml-apis-1.3.04.jar xml-apis-ext-1.3.04.jar batik-js.jar"/>
       </manifest>
       <metainf dir="${basedir}" includes="LICENSE,NOTICE"/>
       <fileset dir="${dest}">
         <include name="${package-prefix}/apps/svgbrowser/**/*.class"/>
+        <include name="${package-prefix}/util/AppStarterUtil*.class"/>
       </fileset>
       <fileset dir="${resources}" excludes="**/.svn/">
         <include name="${package-prefix}/apps/svgbrowser/**/resources/**"/>
@@ -819,8 +824,7 @@
 
     <echo message="debug ${debug}, optimize ${optimize}, deprecation ${deprecation}"/>
 
-    <javac srcdir="${testsrc}" destdir="${dest}"  deprecation="${deprecation}" 
-           debug="${debug}" optimize="${optimize}" encoding="UTF-8">
+    <javac srcdir="${testsrc}" destdir="${dest}" encoding="UTF-8">
       <classpath>
         <pathelement location="${dest}"/>
         <path refid="libs-classpath"/>
@@ -843,8 +847,7 @@
 
     <echo message="debug ${debug}, optimize ${optimize}, deprecation ${deprecation}"/>
 
-    <javac srcdir="${samples}/tests/resources/java/sources" destdir="${samples}/tests/resources/java/classes"  deprecation="${deprecation}" 
-           debug="${debug}" optimize="${optimize}" encoding="UTF-8">
+    <javac srcdir="${samples}/tests/resources/java/sources" destdir="${samples}/tests/resources/java/classes" encoding="UTF-8">
       <classpath>
         <pathelement location="${dest}"/>
         <pathelement location="${samples}/tests/resources/java/classes"/>
@@ -853,8 +856,7 @@
       </classpath>
     </javac>
 
-    <javac srcdir="${testresources}" destdir="${testresources}/classes"  deprecation="${deprecation}" 
-           debug="${debug}" optimize="${optimize}" encoding="UTF-8">
+    <javac srcdir="${testresources}" destdir="${testresources}/classes" encoding="UTF-8">
       <classpath>
         <pathelement location="${dest}"/>
         <pathelement location="${testresources}/classes"/>
@@ -989,8 +991,7 @@
   </target>
 
   <target name="compile" depends="init, compile-prepare" unless="compile.done">
-    <javac destdir="${dest}" deprecation="${deprecation}" 
-           debug="${debug}" optimize="${optimize}" encoding="UTF-8">
+    <javac destdir="${dest}" encoding="UTF-8">
       <src path="${src}"/>
       <classpath refid="libs-classpath"/>
       <exclude name="**/*.html"/>
@@ -1637,6 +1638,7 @@
       <metainf dir="${basedir}" includes="LICENSE,NOTICE"/>
       <fileset dir="${dest}">
         <include name="${package-prefix}/apps/svgbrowser/**/*.class"/>
+        <include name="${package-prefix}/util/AppStarterUtil*.class"/>
       </fileset>
       <fileset dir="${resources}" excludes="**/.svn/">
         <include name="${package-prefix}/apps/svgbrowser/**/resources/**"/>
@@ -1687,6 +1689,7 @@
       <metainf dir="${basedir}" includes="LICENSE,NOTICE"/>
       <fileset dir="${dest}">
         <include name="${package-prefix}/apps/rasterizer/**/*.class"/>
+        <include name="${package-prefix}/util/AppStarterUtil*.class"/>
       </fileset>
       <fileset dir="${resources}" excludes="**/.svn/">
         <include name="${package-prefix}/apps/rasterizer/**/resources/**"/>
diff --git a/sources/batik-browser.mf b/sources/batik-browser.mf
index a878f15..47fe19c 100644
--- a/sources/batik-browser.mf
+++ b/sources/batik-browser.mf
@@ -1,23 +1,2 @@
 Manifest-Version: 1.0
-Main-Class: org.apache.batik.apps.svgbrowser.Main
-Class-Path: lib/batik-ext.jar \
-            lib/batik-dom.jar \
-            lib/batik-css.jar \
-            lib/batik-svg-dom.jar \
-            lib/batik-gvt.jar \
-            lib/batik-parser.jar \
-            lib/batik-script.jar \
-            lib/batik-bridge.jar \
-            lib/batik-swing.jar \
-            lib/batik-anim.jar \
-            lib/batik-transcoder.jar \
-            lib/batik-gui-util.jar \
-            lib/batik-awt-util.jar \
-            lib/batik-codec.jar \
-            lib/batik-util.jar \
-            lib/batik-xml.jar \
-            lib/xerces_2_5_0.jar \
-            lib/xalan-2.6.0.jar \
-            lib/xml-apis.jar \
-            lib/xml-apis-ext.jar \
-            lib/js.jar
+Main-Class: org.apache.batik.apps.svgbrowser.MainDynamic
diff --git a/sources/batik-rasterizer.mf b/sources/batik-rasterizer.mf
index 018bd39..6cadc05 100644
--- a/sources/batik-rasterizer.mf
+++ b/sources/batik-rasterizer.mf
@@ -1,22 +1,2 @@
 Manifest-Version: 1.0
-Main-Class: org.apache.batik.apps.rasterizer.Main
-Class-Path: lib/batik-ext.jar \
-            lib/batik-dom.jar \
-            lib/batik-css.jar \
-            lib/batik-svg-dom.jar \
-            lib/batik-gvt.jar \
-            lib/batik-parser.jar \
-            lib/batik-script.jar \
-            lib/batik-bridge.jar \
-            lib/batik-anim.jar \
-            lib/batik-transcoder.jar \
-            lib/batik-awt-util.jar \
-            lib/batik-codec.jar \
-            lib/batik-util.jar \
-            lib/batik-xml.jar \
-            lib/xerces_2_5_0.jar \
-            lib/xalan-2.6.0.jar \
-            lib/xml-apis.jar \
-            lib/xml-apis-ext.jar \
-            lib/pdf-transcoder.jar \
-            lib/js.jar
+Main-Class: org.apache.batik.apps.rasterizer.MainDynamic
diff --git a/sources/org/apache/batik/apps/rasterizer/MainDynamic.java b/sources/org/apache/batik/apps/rasterizer/MainDynamic.java
new file mode 100644
index 0000000..6dc20e1
--- /dev/null
+++ b/sources/org/apache/batik/apps/rasterizer/MainDynamic.java
@@ -0,0 +1,36 @@
+/*
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+package org.apache.batik.apps.rasterizer;
+
+import org.apache.batik.util.AppStarterUtil;
+
+/**
+ * Main class with dynamic classpath setup for "java -jar" startup.
+ */
+public class MainDynamic {
+
+    /**
+     * Main application method.
+     * @param args the command-line arguments
+     */
+    public static void main(String[] args) {
+        AppStarterUtil.startApp(MainDynamic.class, args);
+    }
+
+}
diff --git a/sources/org/apache/batik/apps/svgbrowser/MainDynamic.java b/sources/org/apache/batik/apps/svgbrowser/MainDynamic.java
new file mode 100644
index 0000000..ece6282
--- /dev/null
+++ b/sources/org/apache/batik/apps/svgbrowser/MainDynamic.java
@@ -0,0 +1,36 @@
+/*
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+package org.apache.batik.apps.svgbrowser;
+
+import org.apache.batik.util.AppStarterUtil;
+
+/**
+ * Main class with dynamic classpath setup for "java -jar" startup.
+ */
+public class MainDynamic {
+
+    /**
+     * Main application method.
+     * @param args the command-line arguments
+     */
+    public static void main(String[] args) {
+        AppStarterUtil.startApp(MainDynamic.class, args);
+    }
+
+}
diff --git a/sources/org/apache/batik/util/AppStarterUtil.java b/sources/org/apache/batik/util/AppStarterUtil.java
new file mode 100644
index 0000000..9944858
--- /dev/null
+++ b/sources/org/apache/batik/util/AppStarterUtil.java
@@ -0,0 +1,151 @@
+/*
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+package org.apache.batik.util;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.lang.reflect.Method;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.List;
+
+import org.apache.batik.apps.svgbrowser.Main;
+
+/**
+ * Utility class for starting applications with a dynamic classpath setup for "java -jar".
+ * This avoids having to hard-code the manifest's "Class-Path" entry. Instead, the library
+ * JARs are automatically picked up from the "./lib" directory, or if that's not found, the
+ * current directory.
+ */
+public class AppStarterUtil {
+
+    private static final Class<?> STRING_ARRAY_CLASS = new String[0].getClass();
+
+    /**
+     * Starts the application derived from the "MainDynamic" class.
+     * @param starterClass the "MainDynamic" class
+     * @param args the command-line arguments
+     */
+    public static void startApp(Class<?> starterClass, String[] args) {
+        String className = starterClass.getName();
+        String mainClassName = className.substring(0, className.lastIndexOf("Dynamic"));
+        startApp(mainClassName, args);
+    }
+    /**
+     * Starts the application given the main class name.
+     * @param mainClassName the main class name
+     * @param args the command-line arguments
+     */
+    public static void startApp(String mainClassName, String[] args) {
+        try {
+            Class<?> mainClazz;
+            try {
+                //If the following class is not available, we need to dynamically build
+                //the classpath. "-jar" was used.
+                Class.forName("org.apache.batik.bridge.Bridge");
+                mainClazz = Class.forName(mainClassName);
+            } catch (ClassNotFoundException cnfe) {
+                URL[] urls = getJARList();
+                ClassLoader loader = new BatikFirstClassLoader(urls,
+                        AppStarterUtil.class.getClassLoader());
+                mainClazz = Class.forName(mainClassName, true, loader);
+            }
+            Method mainMethod = mainClazz.getMethod("main", STRING_ARRAY_CLASS);
+            mainMethod.invoke(null, new Object[] {args});
+        } catch (Exception e) {
+            System.err.println("Unable to start " + Main.class.getName() + ":");
+            e.printStackTrace();
+            System.exit(-1);
+        }
+    }
+
+    /**
+     * Determines the dynamic class path.
+     * @return the array of JAR files for the class path
+     * @throws MalformedURLException if there is a problem constructing URLs
+     */
+    private static URL[] getJARList() throws MalformedURLException {
+        File baseDir = new File(".");
+        List<URL> jars = new java.util.ArrayList<URL>();
+
+        //Get JARs from the "normal" class path...
+        String cp = System.getProperty("java.class.path");
+        String[] cpEntries = cp.split(";");
+        for (String entry : cpEntries) {
+            File f = new File(baseDir, entry);
+            jars.add(f.toURI().toURL());
+        }
+
+        //...and add JARs from the lib (or base) directory.
+        File[] files;
+        FileFilter filter = new FileFilter() {
+            public boolean accept(File pathname) {
+                return pathname.getName().endsWith(".jar");
+            }
+        };
+        File libDir = new File(baseDir, "lib");
+        if (!libDir.exists()) {
+            libDir = baseDir;
+        }
+        files = libDir.listFiles(filter);
+        if (files != null) {
+            for (int i = 0, size = files.length; i < size; i++) {
+                jars.add(files[i].toURI().toURL());
+            }
+        }
+        URL[] urls = jars.toArray(new URL[jars.size()]);
+        return urls;
+    }
+
+    /**
+     * A special {@link URLClassLoader} subclass that loads Batik classes before before looking up
+     * classes in the parent class loader.
+     */
+    private static class BatikFirstClassLoader extends URLClassLoader {
+
+        public BatikFirstClassLoader(URL[] urls, ClassLoader parent) {
+            super(urls, parent);
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        protected synchronized Class<?> loadClass(String name, boolean resolve)
+                throws ClassNotFoundException {
+            if (!name.startsWith("org.apache.batik.")) {
+                return super.loadClass(name, resolve);
+            }
+            //Load all Batik-related classes before consulting the parent class loader
+            try {
+                Class<?> clazz = findLoadedClass(name);
+                if (clazz == null) {
+                    clazz = super.findClass(name);
+                }
+                if (resolve) {
+                    resolveClass(clazz);
+                }
+                return clazz;
+            } catch (ClassNotFoundException cnfe) {
+                return super.loadClass(name, resolve);
+            }
+        }
+
+    }
+
+}