You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pc...@apache.org on 2006/06/28 21:34:40 UTC

svn commit: r417856 [11/22] - in /incubator/openjpa/trunk/openjpa-lib: java/ main/ main/java/ main/java/org/apache/openjpa/lib/ant/ main/java/org/apache/openjpa/lib/conf/ main/java/org/apache/openjpa/lib/jdbc/ main/java/org/apache/openjpa/lib/log/ main...

Modified: incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/FileMetaDataIterator.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/FileMetaDataIterator.java?rev=417856&r1=415364&r2=417856&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/FileMetaDataIterator.java (original)
+++ incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/FileMetaDataIterator.java Wed Jun 28 12:34:33 2006
@@ -15,161 +15,138 @@
  */
 package org.apache.openjpa.lib.meta;
 
+import org.apache.openjpa.lib.util.*;
 
 import java.io.*;
-import java.util.*;
 
-import org.apache.openjpa.lib.util.*;
+import java.util.*;
 
 
 /**
- *	<p>Iterator over a file, or over all metadata resources below a given 
- *	directory.</p>
+ *  <p>Iterator over a file, or over all metadata resources below a given
+ *  directory.</p>
  *
- *	@author		Abe White
- *	@nojavadoc
- */
-public class FileMetaDataIterator
-	implements MetaDataIterator
-{
-	private static final long SCAN_LIMIT = 100000;
-
-	private static final Localizer _loc = Localizer.forPackage
-		(FileMetaDataIterator.class);
-
-	private final Iterator	_itr;
-	private File			_file = null;
-
-
-	/**
-	 *	Constructor; supply metadata file.
-	 */
-	public FileMetaDataIterator (File file)
-	{
-		_itr = Collections.singleton (file).iterator ();
-	}
-
-
-	/**
-	 *	Constructor; supply root of directory tree to search and optional 
-	 *	file filter.
-	 */
-	public FileMetaDataIterator (File dir, MetaDataFilter filter)
-		throws IOException
-	{
-		if (dir == null)
-			_itr = null;
-		else
-		{
-			Collection metas = new ArrayList ();
-			FileResource rsrc = (filter == null) ? null : new FileResource ();
-			scan (dir, filter, rsrc, metas, 0);
-			_itr = metas.iterator ();
-		}
-	}
-
-
-	/**
-	 *	Scan all files below the given one for metadata files, adding them
-	 *	to the given collection.
-	 */
-	private int scan (File file, MetaDataFilter filter, FileResource rsrc, 
-		Collection metas, int scanned)
-		throws IOException
-	{
-		if (scanned > SCAN_LIMIT)
-			throw new IllegalStateException (_loc.get ("too-many-files",
-				String.valueOf (SCAN_LIMIT)));
-		scanned++;
-
-		if (filter == null)
-			metas.add (file);
-		else
-		{
-			rsrc.setFile (file);
-			if (filter.matches (rsrc))
-				metas.add (file);
-			else
-			{
-				File[] files = file.listFiles ();
-				if (files != null)
-					for (int i = 0; i < files.length; i++)
-						scanned = scan (files[i], filter, rsrc, metas, scanned);
-			}
-		}
-		return scanned;
-	}
-
-
-	public boolean hasNext ()
-	{
-		return _itr != null && _itr.hasNext ();
-	}
-
-
-	public Object next ()
-		throws IOException
-	{
-		if (_itr == null)
-			throw new NoSuchElementException ();
-
-		_file = (File) _itr.next ();
-		return _file.getAbsoluteFile ().toURL ();
-	}
-
-	
-	public InputStream getInputStream ()
-		throws IOException
-	{
-		if (_file == null)
-			throw new IllegalStateException ();
-		return new FileInputStream (_file);
-	}
-
-
-	public File getFile ()
-	{
-		if (_file == null)
-			throw new IllegalStateException ();
-		return _file;
-	}
-
-
-	public void close ()
-	{
-	}
-
-
-	private static class FileResource
-		implements MetaDataFilter.Resource
-	{
-		private File _file = null;
-
-
-		public void setFile (File file)
-		{
-			_file = file;
-		}
-
-
-		public String getName ()
-		{
-			return _file.getName ();
-		}
-
-
-		public byte[] getContent ()
-			throws IOException
-		{
-			long len = _file.length ();
-			if (len <= 0)
-				return new byte[0];
-
-			byte[] content = new byte[(int) len];
-			FileInputStream fin = new FileInputStream (_file);
-			fin.read (content);
-			fin.close ();
-			return content;
-		}
-	}
+ *  @author Abe White
+ *  @nojavadoc */
+public class FileMetaDataIterator implements MetaDataIterator {
+    private static final long SCAN_LIMIT = 100000;
+    private static final Localizer _loc = Localizer.forPackage(FileMetaDataIterator.class);
+    private final Iterator _itr;
+    private File _file = null;
+
+    /**
+     *  Constructor; supply metadata file.
+     */
+    public FileMetaDataIterator(File file) {
+        _itr = Collections.singleton(file).iterator();
+    }
+
+    /**
+     *  Constructor; supply root of directory tree to search and optional
+     *  file filter.
+     */
+    public FileMetaDataIterator(File dir, MetaDataFilter filter)
+        throws IOException {
+        if (dir == null) {
+            _itr = null;
+        } else {
+            Collection metas = new ArrayList();
+            FileResource rsrc = (filter == null) ? null : new FileResource();
+            scan(dir, filter, rsrc, metas, 0);
+            _itr = metas.iterator();
+        }
+    }
+
+    /**
+     *  Scan all files below the given one for metadata files, adding them
+     *  to the given collection.
+     */
+    private int scan(File file, MetaDataFilter filter, FileResource rsrc,
+        Collection metas, int scanned) throws IOException {
+        if (scanned > SCAN_LIMIT) {
+            throw new IllegalStateException(_loc.get("too-many-files",
+                    String.valueOf(SCAN_LIMIT)));
+        }
+
+        scanned++;
+
+        if (filter == null) {
+            metas.add(file);
+        } else {
+            rsrc.setFile(file);
+
+            if (filter.matches(rsrc)) {
+                metas.add(file);
+            } else {
+                File[] files = file.listFiles();
+
+                if (files != null) {
+                    for (int i = 0; i < files.length; i++)
+                        scanned = scan(files[i], filter, rsrc, metas, scanned);
+                }
+            }
+        }
+
+        return scanned;
+    }
+
+    public boolean hasNext() {
+        return (_itr != null) && _itr.hasNext();
+    }
+
+    public Object next() throws IOException {
+        if (_itr == null) {
+            throw new NoSuchElementException();
+        }
+
+        _file = (File) _itr.next();
+
+        return _file.getAbsoluteFile().toURL();
+    }
+
+    public InputStream getInputStream() throws IOException {
+        if (_file == null) {
+            throw new IllegalStateException();
+        }
+
+        return new FileInputStream(_file);
+    }
+
+    public File getFile() {
+        if (_file == null) {
+            throw new IllegalStateException();
+        }
+
+        return _file;
+    }
+
+    public void close() {
+    }
+
+    private static class FileResource implements MetaDataFilter.Resource {
+        private File _file = null;
+
+        public void setFile(File file) {
+            _file = file;
+        }
+
+        public String getName() {
+            return _file.getName();
+        }
+
+        public byte[] getContent() throws IOException {
+            long len = _file.length();
+
+            if (len <= 0) {
+                return new byte[0];
+            }
+
+            byte[] content = new byte[(int) len];
+            FileInputStream fin = new FileInputStream(_file);
+            fin.read(content);
+            fin.close();
+
+            return content;
+        }
+    }
 }

Modified: incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/MetaDataFilter.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/MetaDataFilter.java?rev=417856&r1=415364&r2=417856&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/MetaDataFilter.java (original)
+++ incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/MetaDataFilter.java Wed Jun 28 12:34:33 2006
@@ -15,41 +15,33 @@
  */
 package org.apache.openjpa.lib.meta;
 
-
 import java.io.*;
 
 
 /**
- *	<p>Filters metadata resources.  Typically used to constrain the results
- *	of a {@link MetaDataIterator}.</p>
+ *  <p>Filters metadata resources.  Typically used to constrain the results
+ *  of a {@link MetaDataIterator}.</p>
  *
- *	@author		Abe White
- *	@nojavadoc
- */
-public interface MetaDataFilter
-{
-	/**
-	 *	Return whether the given resource passes the filter.
-	 */
-	public boolean matches (Resource rsrc)
-		throws IOException;
-
-
-	/**
-	 *	Information about a metadata resource.
-	 */
-	public static interface Resource
-	{
-		/**
-		 *	The name of the resource.
-	 	 */
-		public String getName ();
-
-
-		/**
-	 	 *	Resource content.
-		 */
-		public byte[] getContent ()
-			throws IOException;
-	}
+ *  @author Abe White
+ *  @nojavadoc */
+public interface MetaDataFilter {
+    /**
+     *  Return whether the given resource passes the filter.
+     */
+    public boolean matches(Resource rsrc) throws IOException;
+
+    /**
+     *  Information about a metadata resource.
+     */
+    public static interface Resource {
+        /**
+         *  The name of the resource.
+          */
+        public String getName();
+
+        /**
+          *  Resource content.
+         */
+        public byte[] getContent() throws IOException;
+    }
 }

Modified: incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/MetaDataIterator.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/MetaDataIterator.java?rev=417856&r1=415364&r2=417856&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/MetaDataIterator.java (original)
+++ incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/MetaDataIterator.java Wed Jun 28 12:34:33 2006
@@ -15,52 +15,43 @@
  */
 package org.apache.openjpa.lib.meta;
 
+import org.apache.openjpa.lib.util.*;
+import org.apache.openjpa.lib.util.Closeable; // also in java.io (in 1.5)
 
 import java.io.*;
 
-import org.apache.openjpa.lib.util.Closeable; // also in java.io (in 1.5)
+import java.util.*;
 
 
 /**
- *	<p>Iterator over metadata resources.</p>
+ *  <p>Iterator over metadata resources.</p>
  *
- *	@author		Abe White
+ *  @author Abe White
  */
-public interface MetaDataIterator
-	extends Closeable
-{
-	/**
-	 *	Return whether there is another resource to iterate over.
-	 */
-	public boolean hasNext ()
-		throws IOException;
-
-
-	/**
-	 *	Return the next metadata resource.
-	 */
-	public Object next ()
-		throws IOException;
-
-	
-	/**
-	 *	Return the last-iterated metadata resource content as a stream.
- 	 */
-	public InputStream getInputStream ()
-		throws IOException;
-
-
-	/**
-	 *	Return the last-iterated metadata resource content as a file, or null
-	 *	if not an extant file.
- 	 */
-	public File getFile ()
-		throws IOException;
-
-
-	/**
-	 *	Close the resources used by this iterator.
-	 */
-	public void close ();
+public interface MetaDataIterator extends Closeable {
+    /**
+     *  Return whether there is another resource to iterate over.
+     */
+    public boolean hasNext() throws IOException;
+
+    /**
+     *  Return the next metadata resource.
+     */
+    public Object next() throws IOException;
+
+    /**
+     *  Return the last-iterated metadata resource content as a stream.
+      */
+    public InputStream getInputStream() throws IOException;
+
+    /**
+     *  Return the last-iterated metadata resource content as a file, or null
+     *  if not an extant file.
+      */
+    public File getFile() throws IOException;
+
+    /**
+     *  Close the resources used by this iterator.
+     */
+    public void close();
 }
-

Modified: incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/MetaDataIteratorChain.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/MetaDataIteratorChain.java?rev=417856&r1=415364&r2=417856&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/MetaDataIteratorChain.java (original)
+++ incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/MetaDataIteratorChain.java Wed Jun 28 12:34:33 2006
@@ -15,110 +15,107 @@
  */
 package org.apache.openjpa.lib.meta;
 
+import org.apache.commons.collections.iterators.*;
 
 import java.io.*;
+
 import java.util.*;
 
 
 /**
- *	<p>Metadata iterator that combines several iterators.</p>
+ *  <p>Metadata iterator that combines several iterators.</p>
  *
- *	@author		Abe White
- *	@nojavadoc
- */
-public class MetaDataIteratorChain
-	implements MetaDataIterator
-{
-	private List 				_itrs	= null;
-	private int	 				_cur	= -1;
-	private MetaDataIterator	_itr	= null;
-
-
-	/**
-	 *	Default constructor.
-	 */
-	public MetaDataIteratorChain ()
-	{
-	}
-
-
-	/**
-	 *	Combine two iterators.
-	 */
-	public MetaDataIteratorChain (MetaDataIterator itr1, MetaDataIterator itr2)
-	{
-		_itrs = new ArrayList (2);
-		_itrs.add (itr1);
-		_itrs.add (itr2);
-	}
-
-
-	/**
-	 *	Add an iterator to the chain.
-	 */
-	public void addIterator (MetaDataIterator itr)
-	{
-		if (_cur != -1)
-			throw new IllegalStateException ();
-		if (_itrs == null)
-			_itrs = new ArrayList (4);
-		_itrs.add (itr);
-	}
-
-
-	public boolean hasNext ()
-		throws IOException
-	{
-		if (_itrs == null)
-			return false;
-		if (_cur == -1)
-			_cur = 0;
-
-		MetaDataIterator itr;
-		for (; _cur < _itrs.size (); _cur++)
-		{
-			itr = (MetaDataIterator) _itrs.get (_cur);
-			if (itr.hasNext ())
-			{
-				_itr = itr;
-				return true;
-			}
-		}
-		_itr = null;
-		return false;
-	}
-
-
-	public Object next ()
-		throws IOException
-	{
-		if (!hasNext ())
-			throw new NoSuchElementException ();
-		return _itr.next ();
-	}
-
-
-	public InputStream getInputStream ()
-		throws IOException
-	{
-		if (_itr == null)
-			throw new IllegalStateException ();
-		return _itr.getInputStream ();
-	}
-
-
-	public File getFile ()
-		throws IOException
-	{
-		if (_itr == null)
-			throw new IllegalStateException ();
-		return _itr.getFile ();
-	}
-
-
-	public void close ()
-	{
-		for (Iterator itr = _itrs.iterator (); itr.hasNext ();)
-			((MetaDataIterator) itr.next ()).close ();
-	}
+ *  @author Abe White
+ *  @nojavadoc */
+public class MetaDataIteratorChain implements MetaDataIterator {
+    private List _itrs = null;
+    private int _cur = -1;
+    private MetaDataIterator _itr = null;
+
+    /**
+     *  Default constructor.
+     */
+    public MetaDataIteratorChain() {
+    }
+
+    /**
+     *  Combine two iterators.
+     */
+    public MetaDataIteratorChain(MetaDataIterator itr1, MetaDataIterator itr2) {
+        _itrs = new ArrayList(2);
+        _itrs.add(itr1);
+        _itrs.add(itr2);
+    }
+
+    /**
+     *  Add an iterator to the chain.
+     */
+    public void addIterator(MetaDataIterator itr) {
+        if (_cur != -1) {
+            throw new IllegalStateException();
+        }
+
+        if (_itrs == null) {
+            _itrs = new ArrayList(4);
+        }
+
+        _itrs.add(itr);
+    }
+
+    public boolean hasNext() throws IOException {
+        if (_itrs == null) {
+            return false;
+        }
+
+        if (_cur == -1) {
+            _cur = 0;
+        }
+
+        MetaDataIterator itr;
+
+        for (; _cur < _itrs.size(); _cur++) {
+            itr = (MetaDataIterator) _itrs.get(_cur);
+
+            if (itr.hasNext()) {
+                _itr = itr;
+
+                return true;
+            }
+        }
+
+        _itr = null;
+
+        return false;
+    }
+
+    public Object next() throws IOException {
+        if (!hasNext()) {
+            throw new NoSuchElementException();
+        }
+
+        return _itr.next();
+    }
+
+    public InputStream getInputStream() throws IOException {
+        if (_itr == null) {
+            throw new IllegalStateException();
+        }
+
+        return _itr.getInputStream();
+    }
+
+    public File getFile() throws IOException {
+        if (_itr == null) {
+            throw new IllegalStateException();
+        }
+
+        return _itr.getFile();
+    }
+
+    public void close() {
+        if (_itrs != null) {
+            for (Iterator itr = _itrs.iterator(); itr.hasNext();)
+                ((MetaDataIterator) itr.next()).close();
+        }
+    }
 }

Modified: incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/MetaDataParser.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/MetaDataParser.java?rev=417856&r1=415364&r2=417856&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/MetaDataParser.java (original)
+++ incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/MetaDataParser.java Wed Jun 28 12:34:33 2006
@@ -15,84 +15,70 @@
  */
 package org.apache.openjpa.lib.meta;
 
-
 import java.io.*;
+
 import java.net.*;
+
 import java.util.*;
 
 
 /**
- *	<p>Interface for metadata parsers.</p>
+ *  <p>Interface for metadata parsers.</p>
  *
- *	@author		Abe White
- *	@nojavadoc
- */
-public interface MetaDataParser
-{
-	/**
-	 *	The classloader to use to resolve resources, or null for impl-defined
-	 *	default.
-	 */
-	public void setClassLoader (ClassLoader loader);
-
-
-	/**
-	 *	Return the results from the last parse.
-	 */
-	public List getResults ();
-	
-
-	/**
-	 *	Parse the given resource.
-	 */
-	public void parse (String rsrc)
-		throws IOException;
-
-
-	/**
-	 *	Parse the given resource.
-	 */
-	public void parse (URL url)
-		throws IOException;
-
-
-	/**
-	 *	Parse the given file, which may be a directory, in which case it
-	 *	will be scanned recursively for metadata files.
-	 */
-	public void parse (File file)
-		throws IOException;
-
-
-	/**
-	 *	Parse all possible metadata locations for the given class, going 
-	 *	top-down or bottom-up.  If the class is null, only top-level locations 
-	 *	will be parsed.
-	 */
-	public void parse (Class cls, boolean topDown)
-		throws IOException;
-
-
-	/**
-	 *	Parse the metadata in the given reader.
- 	 *
-	 *	@param	content		reader containing the metadata to parse
-	 *	@param	sourceName	the name of the source being parsed, for use
-	 *						in error messages
-	 */	
-	public void parse (Reader content, String sourceName)
-		throws IOException;
-
-
-	/**
-	 *	Parse the metadata supplied by the given iterator.
-	 */
-	public void parse (MetaDataIterator itr)
-		throws IOException;
-
-
-	/**
-	 *	Clears the cache of parsed resource names.
-	 */
-	public void clear ();
+ *  @author Abe White
+ *  @nojavadoc */
+public interface MetaDataParser {
+    /**
+     *  The classloader to use to resolve resources, or null for impl-defined
+     *  default.
+     */
+    public void setClassLoader(ClassLoader loader);
+
+    /**
+     *  Return the results from the last parse.
+     */
+    public List getResults();
+
+    /**
+     *  Parse the given resource.
+     */
+    public void parse(String rsrc) throws IOException;
+
+    /**
+     *  Parse the given resource.
+     */
+    public void parse(URL url) throws IOException;
+
+    /**
+     *  Parse the given file, which may be a directory, in which case it
+     *  will be scanned recursively for metadata files.
+     */
+    public void parse(File file) throws IOException;
+
+    /**
+     *  Parse all possible metadata locations for the given class, going
+     *  top-down or bottom-up.  If the class is null, only top-level locations
+     *  will be parsed.
+     */
+    public void parse(Class cls, boolean topDown) throws IOException;
+
+    /**
+     *  Parse the metadata in the given reader.
+      *
+     *  @param content                reader containing the metadata to parse
+     *  @param sourceName        the name of the source being parsed, for use
+     *                                          in error messages
+     */
+    public void parse(Reader content, String sourceName)
+        throws IOException;
+
+    /**
+     *  Parse the metadata supplied by the given iterator.
+     */
+    public void parse(MetaDataIterator itr) throws IOException;
+
+    /**
+     *  Clears the cache of parsed resource names.
+     */
+    public void clear();
 }

Modified: incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/MetaDataSerializer.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/MetaDataSerializer.java?rev=417856&r1=415364&r2=417856&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/MetaDataSerializer.java (original)
+++ incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/MetaDataSerializer.java Wed Jun 28 12:34:33 2006
@@ -15,70 +15,62 @@
  */
 package org.apache.openjpa.lib.meta;
 
+import org.apache.openjpa.lib.log.*;
 
 import java.io.*;
+
 import java.util.*;
 
 
 /**
- *	<p>Interface for meta data serializers.</p>
+ *  <p>Interface for meta data serializers.</p>
  *
- *	@author		Abe White
- *	@nojavadoc
- */
-public interface MetaDataSerializer
-{
-	public static final int COMPACT	= 0;
-	public static final int PRETTY	= 1;
-	public static final int APPEND	= 2;
-	public static final int VERBOSE	= 4;
-
-
-	/**
-	 *	Serialize the current set of objects to the files from which they were
-	 *	parsed.  Any objects for which a source file cannot be determined will
-  	 *	not be included in the output.  
-	 *
- 	 *	@param	flags	bit flags specifying the output flags; e.g. 
-	 *					{@link PRETTY #PRETTY}
-	 */
-	public void serialize (int flags)
-		throws IOException;
-
-
-	/** 
-	 *	Serialize the current set of objects to the files from which they were
-	 *	parsed.  The objects must implement the {@link SourceTracker}
-	 *	interface.
-	 *
-	 *  @param  output  if null, then serialize directly to the file system;
-	 *  				othwerwise, populate the specified {@link Map} with
-	 *  				keys that are the {@link File} instances, and
-	 *  				values that are the {@link String} contents of
-	 *  				the metadata
- 	 *	@param	flags	bit flags specifying the output flags; e.g. 
-	 *					{@link PRETTY #PRETTY}
-	 */
-	public void serialize (Map output, int flags)
-		throws IOException;
-
-
-	/**
-	 *	Serialize the current set of objects to the given file.
-	 *
- 	 *	@param	flags	bit flags specifying the output flags; e.g. 
-	 *					{@link PRETTY #PRETTY} | {@link APPEND #APPEND}
-	 */
-	public void serialize (File file, int flags)
-		throws IOException;
-
-
-	/**
-	 *	Serialize the current set of objects to the given stream.
-	 *
- 	 *	@param	flags	bit flags specifying the output flags; e.g. 
-	 *					{@link PRETTY #PRETTY}
-	 */
-	public void serialize (Writer out, int flags)
-		throws IOException;
+ *  @author Abe White
+ *  @nojavadoc */
+public interface MetaDataSerializer {
+    public static final int COMPACT = 0;
+    public static final int PRETTY = 1;
+    public static final int APPEND = 2;
+    public static final int VERBOSE = 4;
+
+    /**
+     *  Serialize the current set of objects to the files from which they were
+     *  parsed.  Any objects for which a source file cannot be determined will
+       *  not be included in the output.
+     *
+      *  @param flags        bit flags specifying the output flags; e.g.
+     *                                  {@link PRETTY #PRETTY}
+     */
+    public void serialize(int flags) throws IOException;
+
+    /**
+     *  Serialize the current set of objects to the files from which they were
+     *  parsed.  The objects must implement the {@link SourceTracker}
+     *  interface.
+     *
+     *  @param output  if null, then serialize directly to the file system;
+     *                                  othwerwise, populate the specified {@link Map} with
+     *                                  keys that are the {@link File} instances, and
+     *                                  values that are the {@link String} contents of
+     *                                  the metadata
+      *  @param flags        bit flags specifying the output flags; e.g.
+     *                                  {@link PRETTY #PRETTY}
+     */
+    public void serialize(Map output, int flags) throws IOException;
+
+    /**
+     *  Serialize the current set of objects to the given file.
+     *
+      *  @param flags        bit flags specifying the output flags; e.g.
+     *                                  {@link PRETTY #PRETTY} | {@link APPEND #APPEND}
+     */
+    public void serialize(File file, int flags) throws IOException;
+
+    /**
+     *  Serialize the current set of objects to the given stream.
+     *
+      *  @param flags        bit flags specifying the output flags; e.g.
+     *                                  {@link PRETTY #PRETTY}
+     */
+    public void serialize(Writer out, int flags) throws IOException;
 }

Modified: incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/ResourceMetaDataIterator.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/ResourceMetaDataIterator.java?rev=417856&r1=415364&r2=417856&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/ResourceMetaDataIterator.java (original)
+++ incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/ResourceMetaDataIterator.java Wed Jun 28 12:34:33 2006
@@ -15,98 +15,88 @@
  */
 package org.apache.openjpa.lib.meta;
 
+import org.apache.commons.collections.iterators.*;
+
+import org.apache.openjpa.lib.util.*;
 
 import java.io.*;
+
 import java.net.*;
-import java.util.*;
 
-import org.apache.openjpa.lib.util.*;
+import java.util.*;
 
 
 /**
- *	<p>Iterator over a given metadata resource.</p>
+ *  <p>Iterator over a given metadata resource.</p>
  *
- *	@author		Abe White
- *	@nojavadoc
- */
-public class ResourceMetaDataIterator
-	implements MetaDataIterator
-{
-	private List	_urls	= null;
-	private int		_url	= -1;
-
-
-	/**
-	 *	Constructor; supply the resource to parse.
-	 */
-	public ResourceMetaDataIterator (String rsrc)
-		throws IOException
-	{
-		this (rsrc, null);
-	}
-
-
-	/**
-	 *	Constructor; supply the resource to parse.
-	 */
-	public ResourceMetaDataIterator (String rsrc, ClassLoader loader)
-		throws IOException
-	{
-		if (loader == null)
-		{
-			MultiClassLoader multi = new MultiClassLoader ();
-			multi.addClassLoader (multi.SYSTEM_LOADER);
-			multi.addClassLoader (multi.THREAD_LOADER);
-			multi.addClassLoader (getClass ().getClassLoader ());
-			loader = multi;
-		}
-
-		Enumeration e = loader.getResources (rsrc);
-		while (e.hasMoreElements ())
-		{
-			if (_urls == null)
-				_urls = new ArrayList (3);
-			_urls.add (e.nextElement ());
-		}
-	}
-
-
-	public boolean hasNext ()
-	{
-		return _urls != null && _url + 1 < _urls.size ();
-	}
-
-
-	public Object next ()
-	{
-		if (!hasNext ())
-			throw new NoSuchElementException ();
-		return _urls.get (++_url);
-	}
-
-	
-	public InputStream getInputStream ()
-		throws IOException
-	{
-		if (_url == -1 || _url >= _urls.size ())
-			throw new IllegalStateException ();
-		return ((URL) _urls.get (_url)).openStream ();
-	}
-
-
-	public File getFile ()
-		throws IOException
-	{
-		if (_url == -1 || _url >= _urls.size ())
-			throw new IllegalStateException ();
-		File file = new File (URLDecoder.decode (((URL) _urls.get (_url)).
-			getFile ()));
-		return (file.exists ()) ? file : null;
-	}
-
-
-	public void close ()
-	{
-	}
-}
+ *  @author Abe White
+ *  @nojavadoc */
+public class ResourceMetaDataIterator implements MetaDataIterator {
+    private List _urls = null;
+    private int _url = -1;
+
+    /**
+     *  Constructor; supply the resource to parse.
+     */
+    public ResourceMetaDataIterator(String rsrc) throws IOException {
+        this(rsrc, null);
+    }
+
+    /**
+     *  Constructor; supply the resource to parse.
+     */
+    public ResourceMetaDataIterator(String rsrc, ClassLoader loader)
+        throws IOException {
+        if (loader == null) {
+            MultiClassLoader multi = new MultiClassLoader();
+            multi.addClassLoader(multi.SYSTEM_LOADER);
+            multi.addClassLoader(multi.THREAD_LOADER);
+            multi.addClassLoader(getClass().getClassLoader());
+            loader = multi;
+        }
+
+        Enumeration e = loader.getResources(rsrc);
+
+        while (e.hasMoreElements()) {
+            if (_urls == null) {
+                _urls = new ArrayList(3);
+            }
+
+            _urls.add(e.nextElement());
+        }
+    }
+
+    public boolean hasNext() {
+        return (_urls != null) && ((_url + 1) < _urls.size());
+    }
+
+    public Object next() {
+        if (!hasNext()) {
+            throw new NoSuchElementException();
+        }
+
+        return _urls.get(++_url);
+    }
+
+    public InputStream getInputStream() throws IOException {
+        if ((_url == -1) || (_url >= _urls.size())) {
+            throw new IllegalStateException();
+        }
+
+        return ((URL) _urls.get(_url)).openStream();
+    }
+
+    public File getFile() throws IOException {
+        if ((_url == -1) || (_url >= _urls.size())) {
+            throw new IllegalStateException();
+        }
+
+        File file = new File(URLDecoder.decode(
+                    ((URL) _urls.get(_url)).getFile()));
 
+        return (file.exists()) ? file : null;
+    }
+
+    public void close() {
+    }
+}

Modified: incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/SourceTracker.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/SourceTracker.java?rev=417856&r1=415364&r2=417856&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/SourceTracker.java (original)
+++ incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/SourceTracker.java Wed Jun 28 12:34:33 2006
@@ -15,46 +15,40 @@
  */
 package org.apache.openjpa.lib.meta;
 
-
 import java.io.*;
 
 
 /**
- *	<p>Interface that can optionally be implemented by metadata
- *	to include the source file from which the metadata was originally
- *	parsed.</p>
+ *  <p>Interface that can optionally be implemented by metadata
+ *  to include the source file from which the metadata was originally
+ *  parsed.</p>
  *
- *	@author		Abe White
+ *  @author Abe White
  */
-public interface SourceTracker
-{
-	public static final int SRC_OTHER		= 0;
-	public static final int SRC_ANNOTATIONS	= 1;
-	public static final int SRC_XML			= 2;
-
-
-	/**
-	 *	Return the file from which this instance was parsed.
-	 */
-	public File getSourceFile ();
-
-
-	/**
-	 *	Return the domain-dependent scope of this instance within its file.  
-	 */
-	public Object getSourceScope ();
-
-
-	/**
-	 *	Return the type of source.
-	 */
-	public int getSourceType ();
-
-
-	/**
-	 *	Return the domain-meaningful name of the resource that was loaded
-	 *	from this source. I.e., if we had loaded the source for a Java
-	 *	class, this would return the name of the class.
-	 */
-	public String getResourceName ();
+public interface SourceTracker {
+    public static final int SRC_OTHER = 0;
+    public static final int SRC_ANNOTATIONS = 1;
+    public static final int SRC_XML = 2;
+
+    /**
+     *  Return the file from which this instance was parsed.
+     */
+    public File getSourceFile();
+
+    /**
+     *  Return the domain-dependent scope of this instance within its file.
+     */
+    public Object getSourceScope();
+
+    /**
+     *  Return the type of source.
+     */
+    public int getSourceType();
+
+    /**
+     *  Return the domain-meaningful name of the resource that was loaded
+     *  from this source. I.e., if we had loaded the source for a Java
+     *  class, this would return the name of the class.
+     */
+    public String getResourceName();
 }

Modified: incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/SourceTrackers.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/SourceTrackers.java?rev=417856&r1=415364&r2=417856&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/SourceTrackers.java (original)
+++ incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/SourceTrackers.java Wed Jun 28 12:34:33 2006
@@ -15,46 +15,44 @@
  */
 package org.apache.openjpa.lib.meta;
 
-
 import org.apache.openjpa.lib.util.*;
 
 
 /**
- *	Utility class for performing common operations on {@link SourceTracker}s.
+ *  Utility class for performing common operations on {@link SourceTracker}s.
  *
- *	@since 3.3.1
+ *  @since 3.3.1
  */
-public class SourceTrackers
-{
-	private static final Localizer _loc =
-		Localizer.forPackage (SourceTrackers.class);
-
-	private static final String SEP = System.getProperty ("line.separator");
-
-
-	/**
-	 *	Create a message appropriate for display to the user describing
-	 *	the location(s) that <code>trackers</code> were loaded from.
-	 *
-	 *	@param trackers	the source-trackers for which location info should
-	 * 					be provided.
-	 */
-	public static String getSourceLocationMessage (SourceTracker[] trackers)
-	{
-		StringBuffer buf = new StringBuffer (20 * (trackers.length + 1));
-		buf.append (_loc.get ("source-trackers-location-header")).append (SEP);
-		String sourceFilePath;
-		for (int i = 0; i < trackers.length; i++)
-		{
-			sourceFilePath = (trackers[i].getSourceFile () == null ?
-				_loc.get ("source-tracker-file-unknown") : 
-				trackers[i].getSourceFile ().getAbsolutePath ());
-			buf.append ("  ").append (_loc.get (
-				"source-trackers-location-line-item",
-				trackers[i].getResourceName (), sourceFilePath));
-			if (i < trackers.length - 1)
-				buf.append (SEP);
-		}
-		return buf.toString ();
-	}
+public class SourceTrackers {
+    private static final Localizer _loc = Localizer.forPackage(SourceTrackers.class);
+    private static final String SEP = System.getProperty("line.separator");
+
+    /**
+     *  Create a message appropriate for display to the user describing
+     *  the location(s) that <code>trackers</code> were loaded from.
+     *
+     *  @param trackers        the source-trackers for which location info should
+     *                                  be provided.
+     */
+    public static String getSourceLocationMessage(SourceTracker[] trackers) {
+        StringBuffer buf = new StringBuffer(20 * (trackers.length + 1));
+        buf.append(_loc.get("source-trackers-location-header")).append(SEP);
+
+        String sourceFilePath;
+
+        for (int i = 0; i < trackers.length; i++) {
+            sourceFilePath = ((trackers[i].getSourceFile() == null)
+                ? _loc.get("source-tracker-file-unknown")
+                : trackers[i].getSourceFile().getAbsolutePath());
+            buf.append("  ")
+               .append(_loc.get("source-trackers-location-line-item",
+                    trackers[i].getResourceName(), sourceFilePath));
+
+            if (i < (trackers.length - 1)) {
+                buf.append(SEP);
+            }
+        }
+
+        return buf.toString();
+    }
 }

Modified: incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/SuffixMetaDataFilter.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/SuffixMetaDataFilter.java?rev=417856&r1=415364&r2=417856&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/SuffixMetaDataFilter.java (original)
+++ incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/SuffixMetaDataFilter.java Wed Jun 28 12:34:33 2006
@@ -17,29 +17,23 @@
 
 
 /**
- *	<p>Filters metadata iteration based on resource name suffix.</p>
+ *  <p>Filters metadata iteration based on resource name suffix.</p>
  *
- *	@author	Abe White
- *	@nojavadoc
- */
-public class SuffixMetaDataFilter
-	implements MetaDataFilter
-{
-	private final String _suffix;
+ *  @author Abe White
+ *  @nojavadoc */
+public class SuffixMetaDataFilter implements MetaDataFilter {
+    private final String _suffix;
 
+    /**
+     *  Constructor; supply suffix to match against.
+     */
+    public SuffixMetaDataFilter(String suffix) {
+        _suffix = suffix;
+    }
 
-	/**
-	 *	Constructor; supply suffix to match against.
-	 */
-	public SuffixMetaDataFilter (String suffix)
-	{
-		_suffix = suffix;
-	}
+    public boolean matches(Resource rsrc) {
+        String name = rsrc.getName();
 
-
-	public boolean matches (Resource rsrc)
-	{
-		String name = rsrc.getName ();
-		return name != null && name.endsWith (_suffix);
-	}
+        return (name != null) && name.endsWith(_suffix);
+    }
 }

Modified: incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/URLMetaDataIterator.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/URLMetaDataIterator.java?rev=417856&r1=415364&r2=417856&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/URLMetaDataIterator.java (original)
+++ incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/URLMetaDataIterator.java Wed Jun 28 12:34:33 2006
@@ -15,74 +15,67 @@
  */
 package org.apache.openjpa.lib.meta;
 
-
 import java.io.*;
+
 import java.net.*;
 
 
 /**
- *	<p>Iterator over the metadata resource represented by a URL.</p>
+ *  <p>Iterator over the metadata resource represented by a URL.</p>
  *
- *	@author		Abe White
- *	@nojavadoc
- */
-public class URLMetaDataIterator
-	implements MetaDataIterator
-{
-	private final URL 	_url;
-	private boolean		_iterated = false;
-
-
-	/**
-	 *	Constructor; supply resource URL.
-	 */
-	public URLMetaDataIterator (URL url)
-	{
-		_url = url;
-	}
-
-
-	public boolean hasNext ()
-	{
-		return _url != null && !_iterated;
-	}
-
-
-	public Object next ()
-		throws IOException
-	{
-		if (!hasNext ())
-			throw new IllegalStateException ();
-
-		_iterated = true;
-		return _url;
-	}
-
-	
-	public InputStream getInputStream ()
-		throws IOException
-	{
-		if (!_iterated)
-			throw new IllegalStateException ();
-		if (_url == null)
-			return null;
-		return _url.openStream ();
-	}
-
-
-	public File getFile ()
-	{
-		if (!_iterated)
-			throw new IllegalStateException ();
-		if (_url == null)
-			return null;
-		File file = new File (URLDecoder.decode (_url.getPath ()));
-		return (file.exists ()) ? file : null;
-	}
-
-
-	public void close ()
-	{
-	}
-}
+ *  @author Abe White
+ *  @nojavadoc */
+public class URLMetaDataIterator implements MetaDataIterator {
+    private final URL _url;
+    private boolean _iterated = false;
+
+    /**
+     *  Constructor; supply resource URL.
+     */
+    public URLMetaDataIterator(URL url) {
+        _url = url;
+    }
+
+    public boolean hasNext() {
+        return (_url != null) && !_iterated;
+    }
+
+    public Object next() throws IOException {
+        if (!hasNext()) {
+            throw new IllegalStateException();
+        }
+
+        _iterated = true;
+
+        return _url;
+    }
+
+    public InputStream getInputStream() throws IOException {
+        if (!_iterated) {
+            throw new IllegalStateException();
+        }
+
+        if (_url == null) {
+            return null;
+        }
+
+        return _url.openStream();
+    }
+
+    public File getFile() {
+        if (!_iterated) {
+            throw new IllegalStateException();
+        }
+
+        if (_url == null) {
+            return null;
+        }
 
+        File file = new File(URLDecoder.decode(_url.getPath()));
+
+        return (file.exists()) ? file : null;
+    }
+
+    public void close() {
+    }
+}

Modified: incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/XMLMetaDataParser.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/XMLMetaDataParser.java?rev=417856&r1=415364&r2=417856&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/XMLMetaDataParser.java (original)
+++ incubator/openjpa/trunk/openjpa-lib/main/java/org/apache/openjpa/lib/meta/XMLMetaDataParser.java Wed Jun 28 12:34:33 2006
@@ -15,766 +15,727 @@
  */
 package org.apache.openjpa.lib.meta;
 
+import org.apache.openjpa.lib.log.*;
+import org.apache.openjpa.lib.util.*;
+import org.apache.openjpa.lib.xml.*;
+
+import org.xml.sax.*;
+import org.xml.sax.ext.*;
+import org.xml.sax.helpers.*;
 
-import java.util.*;
 import java.io.*;
+
 import java.net.*;
-import javax.xml.parsers.*;
 
-import org.xml.sax.helpers.*;
-import org.xml.sax.ext.*;
-import org.xml.sax.*;
+import java.util.*;
 
-import org.apache.openjpa.lib.log.*;
-import org.apache.openjpa.lib.util.*;
-import org.apache.openjpa.lib.xml.*;
+import javax.xml.parsers.*;
 
 
 /**
- *	<p>Custom SAX parser used by the system to quickly parse metadata files.
- *	Subclasses should handle the processing of the content.</p>
+ *  <p>Custom SAX parser used by the system to quickly parse metadata files.
+ *  Subclasses should handle the processing of the content.</p>
  *
- *	@author		Abe White
- *	@nojavadoc
- */
-public abstract class XMLMetaDataParser
-	extends DefaultHandler
-	implements LexicalHandler, MetaDataParser
-{
-	private static final Localizer _loc = Localizer.forPackage
-		(XMLMetaDataParser.class);
-
-	// map of classloaders to sets of parsed locations, so that we don't parse
-	// the same resource multiple times for the same class
-	private Map _parsed = null;
-
-	private Log			_log			= null;
-	private boolean		_validating 	= true;
-	private boolean		_systemId		= true;
-	private boolean		_caching		= true;
-	private boolean		_parseText		= true;
-	private boolean		_parseComments	= true;
-	private String		_suffix			= null;
-	private ClassLoader	_loader			= null;
-	private ClassLoader	_curLoader		= null;
-
-	// state for current parse
-	private final Collection	_curResults	= new LinkedList ();
-	private List				_results	= null;
-	private String 				_sourceName	= null;
-	protected File				_sourceFile	= null;
-	private StringBuffer 		_text		= null;
-	private List				_comments	= null;
-	private Location			_location	= new Location ();
-	private LexicalHandler		_lh			= null;
-	private int					_depth		= -1;
-	private int					_ignore		= Integer.MAX_VALUE;
-
-
-	/**
-	 *	Whether to parse element text.
-	 */
-	public boolean getParseText ()
-	{
-		return _parseText;
-	}
-
-
-	/**
-	 *	Whether to parse element text.
-	 */
-	public void setParseText (boolean text)
-	{
-		_parseText = text;
-	}
-
-
-	/**
-	 *	Whether to parse element comments.
-	 */
-	public boolean getParseComments ()
-	{
-		return _parseComments;
-	}
-
-
-	/**
-	 *	Whether to parse element comments.
-	 */
-	public void setParseComments (boolean comments)
-	{
-		_parseComments = comments;
-	}
-
-
-	/**
-	 *	The XML document location.
-	 */
-	public Location getLocation ()
-	{
-		return _location;
-	}
-
-
-	/**
-	 *	The lexical handler that should be registered with the SAX parser used
-	 *	by this class. Since the <code>org.xml.sax.ext</code> package is not
-	 *	a required part of SAX2, this handler might not be used by the parser.
-	 */
-	public LexicalHandler getLexicalHandler ()
-	{
-		return _lh;
-	}
-
-
-	/**
-	 *	The lexical handler that should be registered with the SAX parser used
-	 *	by this class. Since the <code>org.xml.sax.ext</code> package is not
-	 *	a required part of SAX2, this handler might not be used by the parser.
-	 */
-	public void setLexicalHandler (LexicalHandler lh)
-	{
-		_lh = lh;
-	}
-
-
-	/**
-	 *	The XML document location.
-	 */
-	public void setLocation (Location location)
-	{
-		_location = location;
-	}
-
-
-	/**
-	 *	Whether to use the source name as the XML system id.
-	 */
-	public boolean getSourceIsSystemId ()
-	{
-		return _systemId;
-	}
-
-
-	/**
-	 *	Whether to use the source name as the XML system id.
-	 */
-	public void setSourceIsSystemId (boolean systemId)
-	{
-		_systemId = systemId;
-	}
-
-
-	/**
-	 *	Whether this is a validating parser.
-	 */
-	public boolean isValidating ()
-	{
-		return _validating;
-	}
-
-
-	/**
-	 *	Whether this is a validating parser.
-	 */
-	public void setValidating (boolean validating)
-	{
-		_validating = validating;
-	}
-
-
-	/**
-	 *	Expected suffix for metadata resources, or null if unknown.
- 	 */
-	public String getSuffix ()
-	{
-		return _suffix;
-	}
-
-
-	/**
-	 *	Expected suffix for metadata resources, or null if unknown.
- 	 */
-	public void setSuffix (String suffix)
-	{
-		_suffix = suffix;
-	}
-
-
-	/**
-	 *	Whether parsed resource names are cached to avoid duplicate parsing.
-	 */
-	public boolean isCaching ()
-	{
-		return _caching;
-	}
-
-
-	/**
-	 *	Whether parsed resource names are cached to avoid duplicate parsing.
-	 */
-	public void setCaching (boolean caching)
-	{
-		_caching = caching;
-		if (!caching)
-			clear ();
-	}
-
-
-	/**
-	 *	The log to write to.
-	 */
-	public Log getLog ()
-	{
-		return _log;
-	}
-
-
-	/**
-	 *	The log to write to.
-	 */
-	public void setLog (Log log)
-	{
-		_log = log;
-	}
-
-
-	/**
-	 *	Classloader to use for class name resolution.
-	 */
-	public ClassLoader getClassLoader ()
-	{
-		return _loader;
-	}
-
-
-	/**
-	 *	Classloader to use for class name resolution.
-	 */
-	public void setClassLoader (ClassLoader loader)
-	{
-		_loader = loader;
-	}
-
-
-	public List getResults ()
-	{
-		if (_results == null)
-			return Collections.EMPTY_LIST;
-		return _results;
-	}
-
-
-	public void parse (String rsrc)
-		throws IOException
-	{
-		if (rsrc != null)
-			parse (new ResourceMetaDataIterator (rsrc, _loader));
-	}
-
-
-	public void parse (URL url)
-		throws IOException
-	{
-		if (url != null)
-			parse (new URLMetaDataIterator (url));
-	}
-
-
-	public void parse (File file)
-		throws IOException
-	{
-		if (file == null)
-			return;
-		if (!file.isDirectory ())
-			parse (new FileMetaDataIterator (file));
-		else
-		{
-			String suff = (_suffix == null) ? "" : _suffix;
-			parse (new FileMetaDataIterator (file, 
-				new SuffixMetaDataFilter (suff)));
-		}
-	}
-
-
-	public void parse (Class cls, boolean topDown)
-		throws IOException
-	{
-		String suff = (_suffix == null) ? "" : _suffix;
-		parse (new ClassMetaDataIterator (cls, suff, topDown), !topDown);
-	}
-
-
-	public void parse (Reader xml, String sourceName)
-		throws IOException
-	{
-		if (xml != null && (sourceName == null || !parsed (sourceName)))
-			parseNewResource (xml, sourceName);
-	}
-
-
-	public void parse (MetaDataIterator itr)
-		throws IOException
-	{
-		parse (itr, false);
-	}
-
-
-	/**
-	 *	Parse the resources returned by the given iterator, optionally stopping
-	 *	when the first valid resource is found.
-	 */	
-	private void parse (MetaDataIterator itr, boolean stopFirst)
-		throws IOException
-	{
-		if (itr == null)
-			return;
-		try
-		{
-			String sourceName;
-			while (itr.hasNext ())
-			{
-				sourceName = itr.next ().toString ();
-				if (parsed (sourceName))
-				{
-					if (stopFirst)
-						break;
-					continue;
-				}
-				
-				// individual files of the resource might already be parsed
-				_sourceFile = itr.getFile ();
-				parseNewResource (new InputStreamReader (itr.getInputStream ()),
-					sourceName);
-				if (stopFirst)
-					break;
-			}
-		}
-		finally
-		{
-			itr.close ();
-		}
-	}
-
-
-	/**
-	 *	Parse a previously-unseen source.  All parsing methods delegate
-	 *	to this one.
-	 */
-	protected void parseNewResource (Reader xml, String sourceName)
-		throws IOException
-	{
-		if (_log != null && _log.isInfoEnabled ())
-			_log.info (_loc.get ("start-parse", sourceName));
-
-		// parse the metadata with a SAX parser
-		try
-		{
-			_sourceName = sourceName;
-			SAXParser parser = XMLFactory.getSAXParser (_validating, true);
-			Object schema = null;
-			if (_validating)
-			{
-				schema = getSchemaSource ();
-				if (schema == null)
-					xml = new DocTypeReader (xml, getDocType ());
-			}
-
-			if (_parseComments || _lh != null)
-				parser.setProperty
-					("http://xml.org/sax/properties/lexical-handler", this);
-
-			if (schema != null)
-			{
-				parser.setProperty 
-					("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
-					"http://www.w3.org/2001/XMLSchema");
-				parser.setProperty
-					("http://java.sun.com/xml/jaxp/properties/schemaSource",
-					schema);
-			}
-			
-			InputSource is = new InputSource (xml);
-			if (_systemId && sourceName != null)
-				is.setSystemId (sourceName);
-			parser.parse (is, this);
-			finish ();
-		}
-		catch (SAXException se)
-		{
-			IOException ioe = new IOException (se.toString ());
-			JavaVersions.initCause (ioe, se);
-			throw ioe;
-		}
-		finally
-		{
-			reset ();
-		}
-	}
-
-
-	/**
-	 *	Return true if the given source is parsed.  Otherwise, record that
-	 *	it will be parsed.
-	 */
-	protected boolean parsed (String src)
-	{
-		if (!_caching)
-			return false;
-		if (_parsed == null)
-			_parsed = new HashMap ();
-
-		ClassLoader loader = currentClassLoader ();
-		boolean added;
-		synchronized (_parsed)
-		{
-			Set set = (Set) _parsed.get (loader);
-			if (set == null)
-			{
-				set = new HashSet ();
-				_parsed.put (loader, set);
-			}
-			added = set.add (src);
-		}
-		if (!added && _log != null && _log.isTraceEnabled ())
-			_log.trace (_loc.get ("already-parsed", src));
-		return !added;
-	}
-
-
-	public void clear ()
-	{
-		if (_log != null && _log.isTraceEnabled ())
-			_log.trace (_loc.get ("clear-parser", this));
-		if (_parsed != null)
-			_parsed.clear ();
-	}
-
-
-	public void error (SAXParseException se)
-		throws SAXException
-	{
-		throw getException (se.toString ());
-	}
-
-
-	public void fatalError (SAXParseException se)
-		throws SAXException
-	{
-		throw getException (se.toString ());
-	}
-
-
-	public void setDocumentLocator (Locator locator)
-	{
-		_location.setLocator (locator);
-	}
-
-
-	public void startElement (String uri, String name, String qName,
-		Attributes attrs)
-		throws SAXException
-	{
-		_depth++;
-		if (_depth <= _ignore)
-			if (!startElement (qName, attrs))
-				ignoreContent (true);
-	}
-
-
-	public void endElement (String uri, String name, String qName)
-		throws SAXException
-	{
-		if (_depth < _ignore)
-			endElement (qName);
-		_text = null;
-		if (_comments != null)
-			_comments.clear ();
-		if (_depth == _ignore)
-			_ignore = Integer.MAX_VALUE;
-		_depth--;
-	}
-
-
-	public void characters (char[] ch, int start, int length)
-	{
-		if (_parseText && _depth <= _ignore)
-		{
-			if (_text == null)
-				_text = new StringBuffer ();
-			_text.append (ch, start, length);
-		}
-	}
-
-
-	public void comment (char[] ch, int start, int length)
-		throws SAXException
-	{
-		if (_parseComments && _depth <= _ignore)
-		{
-			if (_comments == null)
-				_comments = new ArrayList (3);
-			_comments.add (String.valueOf (ch, start, length));
-		}
-		if (_lh != null)
-			_lh.comment (ch, start, length);
-	}
-
-
-	public void startCDATA ()
-		throws SAXException
-	{
-		if (_lh != null)
-			_lh.startCDATA ();
-	}
-
-
-	public void endCDATA ()
-		throws SAXException
-	{
-		if (_lh != null)
-			_lh.endCDATA ();
-	}
-
-
-	public void startDTD (String name, String publicId, String systemId)
-		throws SAXException
-	{
-		if (_lh != null)
-			_lh.startDTD (name, publicId, systemId);
-	}
-
-
-	public void endDTD ()
-		throws SAXException
-	{
-		if (_lh != null)
-			_lh.endDTD ();
-	}
-
-
-	public void startEntity (String name)
-		throws SAXException
-	{
-		if (_lh != null)
-			_lh.startEntity (name);
-	}
-
-
-	public void endEntity (String name)
-		throws SAXException
-	{
-		if (_lh != null)
-			_lh.endEntity (name);
-	}
-
-
-	/**
-	 *	Override this method marking the start of some element.  If this method
-	 *	returns false, the content of the element and the end element event will
-	 *	be ignored.
-	 */
-	protected abstract boolean startElement (String name, Attributes attrs)
-		throws SAXException;
-
-
-	/**
-	 *	Override this method marking the end of some element.
-	 */
-	protected abstract void endElement (String name)
-		throws SAXException;
-
-
-	/**
-	 *	Add a result to be returned from the current parse.
-	 */
-	protected void addResult (Object result)
-	{
-		if (_log != null && _log.isTraceEnabled ())
-			_log.trace (_loc.get ("add-result", result));
-		_curResults.add (result);
-	}
-
-
-	/**
-	 *	Override this method to finish up after a parse; this is only
-	 *	called if no errors are encountered during parsing.  Subclasses should
-	 *	call <code>super.finish ()</code> to resolve superclass state.
-	 */
-	protected void finish ()
-	{
-		if (_log != null && _log.isTraceEnabled ())
-			_log.trace (_loc.get ("end-parse", getSourceName ()));
-		_results = new ArrayList (_curResults);
-	}
-
-
-	/**
-	 *	Override this method to clear any state and ready the parser for
-	 *	a new document.  Subclasses should call
-	 *	<code>super.reset ()</code> to clear superclass state.
-	 */
-	protected void reset ()
-	{
-		_curResults.clear ();
-		_curLoader = null;
-		_sourceName = null;
-		_sourceFile = null;
-		_depth = -1;
-		_ignore = Integer.MAX_VALUE;
-		if (_comments != null)
-			_comments.clear ();
-	}
-
-
-	/**
-	 *	Implement to return the XML schema source for the document.  Returns
-	 *	null by default.  May return:
-	 *	<ul>
-	 *	<li><code>String</code> pointing to schema URI.</li>
-	 *	<li><code>InputStream</code> containing schema contents.</li> 
-	 *	<li><code>InputSource</code> containing schema contents.</li> 
-	 *	<li><code>File</code> containing schema contents.</li> 
-	 *	<li>Array of any of the above elements.</li>
-	 *	</ul>
-	 */
-	protected Object getSchemaSource ()
-		throws IOException
-	{
-		return null;
-	}
-
-
-	/**
-	 *	Override this method to return any <code>DOCTYPE</code> declaration
-	 *	that should be dynamically included in xml documents that will be
-	 *	validated.  Returns null by default.
-	 */
-	protected Reader getDocType ()
-		throws IOException
-	{
-		return null;
-	}
-
-
-	/**
-	 *	Return the name of the source file being parsed.
-	 */
-	protected String getSourceName ()
-	{
-		return _sourceName;
-	}
-
-
-	/**
-	 *	Return the file of the source being parsed.
- 	 */
-	protected File getSourceFile ()
-	{
-		return _sourceFile;
-	}
-
-
-	/**
-	 *	Add current comments to the given entity.  By default, assumes entity
-	 *	is {@link Commentable}.
-	 */
-	protected void addComments (Object obj)
-	{
-		String[] comments = currentComments ();
-		if (comments.length > 0 && obj instanceof Commentable)
-			((Commentable) obj).setComments (comments);
-	}
-
-
-	/**
-	 *	Array of comments for the current node, or empty array if none.
-	 */
-	protected String[] currentComments ()
-	{
-		if (_comments == null || _comments.isEmpty ())
-			return Commentable.EMPTY_COMMENTS;
-		return (String[]) _comments.toArray (new String[_comments.size ()]);
-	}
-
-
-	/**
-	 *	Return the text value within the current node.
-	 */
-	protected String currentText ()
-	{
-		if (_text == null)
-			return "";
-		return _text.toString ().trim ();
-	}
-
-
-	/**
-	 *	Return the current location within the source file.
-	 */
-	protected String currentLocation ()
-	{
-		return " [" + _loc.get ("loc-prefix") + _location.getLocation () + "]";
-	}
-
-
-	/**
-	 *	Return the parse depth.  Within the root element, the depth is 0,
-	 *	within the first nested element, it is 1, and so forth.
-	 */
-	protected int currentDepth ()
-	{
-		return _depth;
-	}
-
-
-	/**
-	 *	Return the class loader to use when resolving resources and loading
-	 *	classes.
-	 */
-	protected ClassLoader currentClassLoader ()
-	{
-		if (_loader != null)
-			return _loader;
-		if (_curLoader == null)
-			_curLoader = Thread.currentThread ().getContextClassLoader ();
-		return _curLoader;
-	}
-
-
-	/**
-	 *	Ignore all content below the current element.
-	 *
-	 *	@param	ignoreEnd	whether to ignore the end element event
-	 */
-	protected void ignoreContent (boolean ignoreEnd)
-	{
-		_ignore = _depth;
-		if (!ignoreEnd)
-			_ignore++;
-	}
-
-
-	/**
-	 *	Returns a SAXException with the source file name and the given error
-	 *	message.
-	 */
-	protected SAXException getException (String msg)
-	{
-		return new SAXException (getSourceName () + currentLocation () +
-			": " + msg);
-	}
-
-
-	/**
-	 *	Returns a SAXException with the source file name and the given error
-	 *	message.
-	 */
-	protected SAXException getException (String msg, Throwable cause)
-	{
-		if (cause != null && _log != null && _log.isTraceEnabled ())
-			_log.trace (cause);
-		return new SAXException (getSourceName () + currentLocation () +
-			": " + msg + " [" + cause + "]");
-	}
+ *  @author Abe White
+ *  @nojavadoc */
+public abstract class XMLMetaDataParser extends DefaultHandler
+    implements LexicalHandler, MetaDataParser {
+    private static final Localizer _loc = Localizer.forPackage(XMLMetaDataParser.class);
+    private static boolean _schemaBug;
+
+    static {
+        try {
+            // check for Xerces version 2.0.2 to see if we need to disable 
+            // schema validation, which works around the bug reported at:
+            // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4708859
+            _schemaBug = "Xerces-J 2.0.2".equals(Class.forName(
+                        "org.apache.xerces.impl.Version").getField("fVersion")
+                                                      .get(null));
+        } catch (Throwable t) {
+            // Xerces might not be available
+            _schemaBug = false;
+        }
+    }
+
+    // map of classloaders to sets of parsed locations, so that we don't parse
+    // the same resource multiple times for the same class
+    private Map _parsed = null;
+    private Log _log = null;
+    private boolean _validating = true;
+    private boolean _systemId = true;
+    private boolean _caching = true;
+    private boolean _parseText = true;
+    private boolean _parseComments = true;
+    private String _suffix = null;
+    private ClassLoader _loader = null;
+    private ClassLoader _curLoader = null;
+
+    // state for current parse
+    private final Collection _curResults = new LinkedList();
+    private List _results = null;
+    private String _sourceName = null;
+    protected File _sourceFile = null;
+    private StringBuffer _text = null;
+    private List _comments = null;
+    private Location _location = new Location();
+    private LexicalHandler _lh = null;
+    private int _depth = -1;
+    private int _ignore = Integer.MAX_VALUE;
+
+    /**
+     *  Whether to parse element text.
+     */
+    public boolean getParseText() {
+        return _parseText;
+    }
+
+    /**
+     *  Whether to parse element text.
+     */
+    public void setParseText(boolean text) {
+        _parseText = text;
+    }
+
+    /**
+     *  Whether to parse element comments.
+     */
+    public boolean getParseComments() {
+        return _parseComments;
+    }
+
+    /**
+     *  Whether to parse element comments.
+     */
+    public void setParseComments(boolean comments) {
+        _parseComments = comments;
+    }
+
+    /**
+     *  The XML document location.
+     */
+    public Location getLocation() {
+        return _location;
+    }
+
+    /**
+     *  The lexical handler that should be registered with the SAX parser used
+     *  by this class. Since the <code>org.xml.sax.ext</code> package is not
+     *  a required part of SAX2, this handler might not be used by the parser.
+     */
+    public LexicalHandler getLexicalHandler() {
+        return _lh;
+    }
+
+    /**
+     *  The lexical handler that should be registered with the SAX parser used
+     *  by this class. Since the <code>org.xml.sax.ext</code> package is not
+     *  a required part of SAX2, this handler might not be used by the parser.
+     */
+    public void setLexicalHandler(LexicalHandler lh) {
+        _lh = lh;
+    }
+
+    /**
+     *  The XML document location.
+     */
+    public void setLocation(Location location) {
+        _location = location;
+    }
+
+    /**
+     *  Whether to use the source name as the XML system id.
+     */
+    public boolean getSourceIsSystemId() {
+        return _systemId;
+    }
+
+    /**
+     *  Whether to use the source name as the XML system id.
+     */
+    public void setSourceIsSystemId(boolean systemId) {
+        _systemId = systemId;
+    }
+
+    /**
+     *  Whether this is a validating parser.
+     */
+    public boolean isValidating() {
+        return _validating;
+    }
+
+    /**
+     *  Whether this is a validating parser.
+     */
+    public void setValidating(boolean validating) {
+        _validating = validating;
+    }
+
+    /**
+     *  Expected suffix for metadata resources, or null if unknown.
+      */
+    public String getSuffix() {
+        return _suffix;
+    }
+
+    /**
+     *  Expected suffix for metadata resources, or null if unknown.
+      */
+    public void setSuffix(String suffix) {
+        _suffix = suffix;
+    }
+
+    /**
+     *  Whether parsed resource names are cached to avoid duplicate parsing.
+     */
+    public boolean isCaching() {
+        return _caching;
+    }
+
+    /**
+     *  Whether parsed resource names are cached to avoid duplicate parsing.
+     */
+    public void setCaching(boolean caching) {
+        _caching = caching;
+
+        if (!caching) {
+            clear();
+        }
+    }
+
+    /**
+     *  The log to write to.
+     */
+    public Log getLog() {
+        return _log;
+    }
+
+    /**
+     *  The log to write to.
+     */
+    public void setLog(Log log) {
+        _log = log;
+    }
+
+    /**
+     *  Classloader to use for class name resolution.
+     */
+    public ClassLoader getClassLoader() {
+        return _loader;
+    }
+
+    /**
+     *  Classloader to use for class name resolution.
+     */
+    public void setClassLoader(ClassLoader loader) {
+        _loader = loader;
+    }
+
+    public List getResults() {
+        if (_results == null) {
+            return Collections.EMPTY_LIST;
+        }
+
+        return _results;
+    }
+
+    public void parse(String rsrc) throws IOException {
+        if (rsrc != null) {
+            parse(new ResourceMetaDataIterator(rsrc, _loader));
+        }
+    }
+
+    public void parse(URL url) throws IOException {
+        if (url != null) {
+            parse(new URLMetaDataIterator(url));
+        }
+    }
+
+    public void parse(File file) throws IOException {
+        if (file == null) {
+            return;
+        }
+
+        if (!file.isDirectory()) {
+            parse(new FileMetaDataIterator(file));
+        } else {
+            String suff = (_suffix == null) ? "" : _suffix;
+            parse(new FileMetaDataIterator(file, new SuffixMetaDataFilter(suff)));
+        }
+    }
+
+    public void parse(Class cls, boolean topDown) throws IOException {
+        String suff = (_suffix == null) ? "" : _suffix;
+        parse(new ClassMetaDataIterator(cls, suff, topDown), !topDown);
+    }
+
+    public void parse(Reader xml, String sourceName) throws IOException {
+        if ((xml != null) && ((sourceName == null) || !parsed(sourceName))) {
+            parseNewResource(xml, sourceName);
+        }
+    }
+
+    public void parse(MetaDataIterator itr) throws IOException {
+        parse(itr, false);
+    }
+
+    /**
+     *  Parse the resources returned by the given iterator, optionally stopping
+     *  when the first valid resource is found.
+     */
+    private void parse(MetaDataIterator itr, boolean stopFirst)
+        throws IOException {
+        if (itr == null) {
+            return;
+        }
+
+        try {
+            String sourceName;
+
+            while (itr.hasNext()) {
+                sourceName = itr.next().toString();
+
+                if (parsed(sourceName)) {
+                    if (stopFirst) {
+                        break;
+                    }
+
+                    continue;
+                }
+
+                // individual files of the resource might already be parsed
+                _sourceFile = itr.getFile();
+                parseNewResource(new InputStreamReader(itr.getInputStream()),
+                    sourceName);
+
+                if (stopFirst) {
+                    break;
+                }
+            }
+        } finally {
+            itr.close();
+        }
+    }
+
+    /**
+     *  Parse a previously-unseen source.  All parsing methods delegate
+     *  to this one.
+     */
+    protected void parseNewResource(Reader xml, String sourceName)
+        throws IOException {
+        if ((_log != null) && _log.isInfoEnabled()) {
+            _log.info(_loc.get("start-parse", sourceName));
+        }
+
+        // even if we want to validate, specify that it won't happen
+        // if we have neither a DocType not a Schema
+        Object schemaSource = getSchemaSource();
+
+        if ((schemaSource != null) && _schemaBug) {
+            if ((_log != null) && _log.isInfoEnabled()) {
+                _log.info(_loc.get("parser-schema-bug"));
+            }
+
+            schemaSource = null;
+        }
+
+        boolean validating = _validating &&
+            ((getDocType() != null) || (schemaSource != null));
+
+        // parse the metadata with a SAX parser
+        try {
+            _sourceName = sourceName;
+
+            SAXParser parser = XMLFactory.getSAXParser(validating, true);
+            Object schema = null;
+
+            if (validating) {
+                schema = schemaSource;
+
+                if ((schema == null) && (getDocType() != null)) {
+                    xml = new DocTypeReader(xml, getDocType());
+                }
+            }
+
+            if (_parseComments || (_lh != null)) {
+                parser.setProperty("http://xml.org/sax/properties/lexical-handler",
+                    this);
+            }
+
+            if (schema != null) {
+                parser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
+                    "http://www.w3.org/2001/XMLSchema");
+                parser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaSource",
+                    schema);
+            }
+
+            InputSource is = new InputSource(xml);
+
+            if (_systemId && (sourceName != null)) {
+                is.setSystemId(sourceName);
+            }
+
+            parser.parse(is, this);
+            finish();
+        } catch (SAXException se) {
+            IOException ioe = new IOException(se.toString());
+            JavaVersions.initCause(ioe, se);
+            throw ioe;
+        } finally {
+            reset();
+        }
+    }
+
+    /**
+     *  Return true if the given source is parsed.  Otherwise, record that
+     *  it will be parsed.
+     */
+    protected boolean parsed(String src) {
+        if (!_caching) {
+            return false;
+        }
+
+        if (_parsed == null) {
+            _parsed = new HashMap();
+        }
+
+        ClassLoader loader = currentClassLoader();
+        Set set = (Set) _parsed.get(loader);
+
+        if (set == null) {
+            set = new HashSet();
+            _parsed.put(loader, set);
+        }
+
+        boolean added = set.add(src);
+
+        if (!added && (_log != null) && _log.isTraceEnabled()) {
+            _log.trace(_loc.get("already-parsed", src));
+        }
+
+        return !added;
+    }
+
+    /**
+     *  Whether we previously parsed the given file.
+     */
+    private boolean parsed(File file, String cur) throws IOException {
+        if (file == null) {
+            return false;
+        }
+
+        String src = file.getCanonicalFile().toURL().toString();
+
+        if (src.equals(cur)) {
+            return false;
+        }
+
+        return parsed(src);
+    }
+
+    public void clear() {
+        if ((_log != null) && _log.isTraceEnabled()) {
+            _log.trace(_loc.get("clear-parser", this));
+        }
+
+        if (_parsed != null) {
+            _parsed.clear();
+        }
+    }
+
+    public void error(SAXParseException se) throws SAXException {
+        throw getException(se.toString());
+    }
+
+    public void fatalError(SAXParseException se) throws SAXException {
+        throw getException(se.toString());
+    }
+
+    public void setDocumentLocator(Locator locator) {
+        _location.setLocator(locator);
+    }
+
+    public void startElement(String uri, String name, String qName,
+        Attributes attrs) throws SAXException {
+        _depth++;
+
+        if (_depth <= _ignore) {
+            if (!startElement(qName, attrs)) {
+                ignoreContent(true);
+            }
+        }
+    }
+
+    public void endElement(String uri, String name, String qName)
+        throws SAXException {
+        if (_depth < _ignore) {
+            endElement(qName);
+        }
+
+        _text = null;
+
+        if (_comments != null) {
+            _comments.clear();
+        }
+
+        if (_depth == _ignore) {
+            _ignore = Integer.MAX_VALUE;
+        }
+
+        _depth--;
+    }
+
+    public void characters(char[] ch, int start, int length) {
+        if (_parseText && (_depth <= _ignore)) {
+            if (_text == null) {
+                _text = new StringBuffer();
+            }
+
+            _text.append(ch, start, length);
+        }
+    }
+
+    public void comment(char[] ch, int start, int length)
+        throws SAXException {
+        if (_parseComments && (_depth <= _ignore)) {
+            if (_comments == null) {
+                _comments = new ArrayList(3);
+            }
+
+            _comments.add(String.valueOf(ch, start, length));
+        }
+
+        if (_lh != null) {
+            _lh.comment(ch, start, length);
+        }
+    }
+
+    public void startCDATA() throws SAXException {
+        if (_lh != null) {
+            _lh.startCDATA();
+        }
+    }
+
+    public void endCDATA() throws SAXException {
+        if (_lh != null) {
+            _lh.endCDATA();
+        }
+    }
+
+    public void startDTD(String name, String publicId, String systemId)
+        throws SAXException {
+        if (_lh != null) {
+            _lh.startDTD(name, publicId, systemId);
+        }
+    }
+
+    public void endDTD() throws SAXException {
+        if (_lh != null) {
+            _lh.endDTD();
+        }
+    }
+
+    public void startEntity(String name) throws SAXException {
+        if (_lh != null) {
+            _lh.startEntity(name);
+        }
+    }
+
+    public void endEntity(String name) throws SAXException {
+        if (_lh != null) {
+            _lh.endEntity(name);
+        }
+    }
+
+    /**
+     *  Override this method marking the start of some element.  If this method
+     *  returns false, the content of the element and the end element event will
+     *  be ignored.
+     */
+    protected abstract boolean startElement(String name, Attributes attrs)
+        throws SAXException;
+
+    /**
+     *  Override this method marking the end of some element.
+     */
+    protected abstract void endElement(String name) throws SAXException;
+
+    /**
+     *  Add a result to be returned from the current parse.
+     */
+    protected void addResult(Object result) {
+        if ((_log != null) && _log.isTraceEnabled()) {
+            _log.trace(_loc.get("add-result", result));
+        }
+
+        _curResults.add(result);
+    }
+
+    /**
+     *  Override this method to finish up after a parse; this is only
+     *  called if no errors are encountered during parsing.  Subclasses should
+     *  call <code>super.finish ()</code> to resolve superclass state.
+     */
+    protected void finish() {
+        if ((_log != null) && _log.isTraceEnabled()) {
+            _log.trace(_loc.get("end-parse", getSourceName()));
+        }
+
+        _results = new ArrayList(_curResults);
+    }
+
+    /**
+     *  Override this method to clear any state and ready the parser for
+     *  a new document.  Subclasses should call
+     *  <code>super.reset ()</code> to clear superclass state.
+     */
+    protected void reset() {
+        _curResults.clear();
+        _curLoader = null;
+        _sourceName = null;
+        _sourceFile = null;
+        _depth = -1;
+        _ignore = Integer.MAX_VALUE;
+
+        if (_comments != null) {
+            _comments.clear();
+        }
+    }
+
+    /**
+     *  Implement to return the XML schema source for the document.  Returns
+     *  null by default.  May return:
+     *  <ul>
+     *  <li><code>String</code> pointing to schema URI.</li>
+     *  <li><code>InputStream</code> containing schema contents.</li>
+     *  <li><code>InputSource</code> containing schema contents.</li>
+     *  <li><code>File</code> containing schema contents.</li>
+     *  <li>Array of any of the above elements.</li>
+     *  </ul>
+     */
+    protected Object getSchemaSource() throws IOException {
+        return null;
+    }
+
+    /**
+     *  Override this method to return any <code>DOCTYPE</code> declaration
+     *  that should be dynamically included in xml documents that will be
+     *  validated.  Returns null by default.
+     */
+    protected Reader getDocType() throws IOException {
+        return null;
+    }
+
+    /**
+     *  Return the name of the source file being parsed.
+     */
+    protected String getSourceName() {
+        return _sourceName;
+    }
+
+    /**
+     *  Return the file of the source being parsed.
+      */
+    protected File getSourceFile() {
+        return _sourceFile;
+    }
+
+    /**
+     *  Add current comments to the given entity.  By default, assumes entity
+     *  is {@link Commentable}.
+     */
+    protected void addComments(Object obj) {
+        String[] comments = currentComments();
+
+        if ((comments.length > 0) && obj instanceof Commentable) {
+            ((Commentable) obj).setComments(comments);
+        }
+    }
+
+    /**
+     *  Array of comments for the current node, or empty array if none.
+     */
+    protected String[] currentComments() {
+        if ((_comments == null) || _comments.isEmpty()) {
+            return Commentable.EMPTY_COMMENTS;
+        }
+
+        return (String[]) _comments.toArray(new String[_comments.size()]);
+    }
+
+    /**
+     *  Return the text value within the current node.
+     */
+    protected String currentText() {
+        if (_text == null) {
+            return "";
+        }
+
+        return _text.toString().trim();
+    }
+
+    /**
+     *  Return the current location within the source file.
+     */
+    protected String currentLocation() {
+        return " [" + _loc.get("loc-prefix") + _location.getLocation() + "]";
+    }
+
+    /**
+     *  Return the parse depth.  Within the root element, the depth is 0,
+     *  within the first nested element, it is 1, and so forth.
+     */
+    protected int currentDepth() {
+        return _depth;
+    }
+
+    /**
+     *  Return the class loader to use when resolving resources and loading
+     *  classes.
+     */
+    protected ClassLoader currentClassLoader() {
+        if (_loader != null) {
+            return _loader;
+        }
+
+        if (_curLoader == null) {
+            _curLoader = Thread.currentThread().getContextClassLoader();
+        }
+
+        return _curLoader;
+    }
+
+    /**
+     *  Ignore all content below the current element.
+     *
+     *  @param ignoreEnd        whether to ignore the end element event
+     */
+    protected void ignoreContent(boolean ignoreEnd) {
+        _ignore = _depth;
+
+        if (!ignoreEnd) {
+            _ignore++;
+        }
+    }
+
+    /**
+     *  Returns a SAXException with the source file name and the given error
+     *  message.
+     */
+    protected SAXException getException(String msg) {
+        return new SAXException(getSourceName() + currentLocation() + ": " +
+            msg);
+    }
+
+    /**
+     *  Returns a SAXException with the source file name and the given error
+     *  message.
+     */
+    protected SAXException getException(String msg, Throwable cause) {
+        if ((cause != null) && (_log != null) && _log.isTraceEnabled()) {
+            _log.trace(cause);
+        }
+
+        return new SAXException(getSourceName() + currentLocation() + ": " +
+            msg + " [" + cause + "]");
+    }
 }