Login | Register
My pages Projects Community openCollabNet

Discussions > cvs > CVS update: /tada-sax/src/se/tada/util/sax/

tada-sax
Discussion topic

Back to topic list

CVS update: /tada-sax/src/se/tada/util/sax/

Reply

Author thhal
Full name Thomas Hallgren
Date 2005-03-03 07:20:53 PST
Message User: thhal
Date: 05/03/03 07:20:53

Modified:
 /tada-sax/src/se/tada/util/sax/
  TopHandler.java, ChildHandler.java

Log:
 Made the handlers namespace aware
 Improved the cache so that it handles nested elements gracefully

File Changes:

Directory: /tada-sax/src/se/tada/util/sax/
====================​====================​==

File [changed]: TopHandler.java
Url: http://tada-sax.tigr​is.org/source/browse​/tada-sax/src/se/tad​a/util/sax/TopHandle​r.java?r1=1.3&r2​=1.4
Delta lines: +55 -0
--------------------
--- TopHandler.java 26 Jan 2005 17:10:51 -0000 1.3
+++ TopHandler.java 3 Mar 2005 15:20:53 -0000 1.4
@@ -6,6 +6,8 @@
  */
 package se.tada.util.sax;
 
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.Stack;
 
 import org.xml.sax.Attributes;
@@ -30,6 +32,7 @@
     private XMLReader m_reader;
 
     private final Stack m_handlerStack = new Stack();
+ private final ArrayList m_handlerCache = new ArrayList();
 
     /**
      * Create a <code>TopHandl​er</code> and assing a <code>XMLReade​r</code>
@@ -45,6 +48,16 @@
     }
 
     /**
+ * Obtains the current handler from the reader and
+ * returns it.
+ * @return The handler that is current
+ */
+ public AbstractHandler getCurrentHandler()
+ {
+ return (AbstractHandler)m_r​eader.getContentHand​ler();
+ }
+
+ /**
      * Push a filter that will sit between the XMLReader and this handler.
      *
      * @param filter The filter.
@@ -121,6 +134,24 @@
     }
 
     /**
+ * Instruct this parser to use namespaces.
+ */
+ public final void setNamespaceAware(boolean flag)
+ {
+ try
+ {
+ m_reader.setFeature("http://xml.org/sax/f​eatures/namespaces", flag);
+ }
+ catch(SAXException e)
+ {
+ // All XMLReaders are required to support the namespace
+ // feature, so this should be regarded as fatal.
+ //
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
      * Returns the XMLReader currently associated with this instance. This is
      * either the reader that was passed to the constructor or a filter that was
      * added using {@link #pushFilter(XMLFilterImpl)}.
@@ -175,5 +206,29 @@
     protected final String getTAG()
     {
         return "root";
+ }
+
+ /**
+ * Assign <code>this</code> as the top handler for the given
+ * <code>child</code>
+ */
+ protected final void assignTopHandler(ChildHandler child)
+ {
+ child.setTopHandler(this);
+ }
+
+ /**
+ * Return the handler cache for the current nesting level
+ */
+ protected final HashMap getHandlerCache()
+ {
+ int depth = m_handlerStack.size();
+ int cacheSize = m_handlerCache.size();
+ while(cacheSize <= depth)
+ {
+ m_handlerCache.add(new HashMap());
+ ++cacheSize;
+ }
+ return (HashMap)m_handlerCa​che.get(depth);
     }
 }

File [changed]: ChildHandler.java
Url: http://tada-sax.tigr​is.org/source/browse​/tada-sax/src/se/tad​a/util/sax/ChildHand​ler.java?r1=1.1&​r2=1.2
Delta lines: +77 -15
---------------------
--- ChildHandler.java 25 Jan 2005 19:20:47 -0000 1.1
+++ ChildHandler.java 3 Mar 2005 15:20:53 -0000 1.2
@@ -32,16 +32,16 @@
  */
 public abstract class ChildHandler extends AbstractHandler
 {
- private final HashMap m_createdHandlers = new HashMap();
+ private final NSKey m_nsKeyTemplate = new NSKey();
     private TopHandler m_topHandler;
 
     /**
      * Push a handler that corresponds to the <code>qName</code>, cached
      * or created, on the handler stack so that it becomes the current
      * <code>ContentH​andler</code> of the <code>TopHandl​er</code>.
- * @param uri The Namespace URI, ignored.
- * @param localName The local name, ignored.
- * @param qName The qualified name used as key for the new handler.
+ * @param uri The Namespace URI.
+ * @param localName The local name.
+ * @param qName The qualified name.
      * @param attributes The attributes that will be sent to the
      * {@link #handleAttributes(Attributes)} method of the new handler.
      * @exception org.xml.sax.SAXException Any SAX exception, possibly
@@ -50,7 +50,11 @@
     public void startElement(String uri, String localName, String qName, Attributes attrs)
     throws SAXException
     {
- this.pushHandler(thi​s.getHandler(qName),​ attrs);
+ if(localName.length() == 0)
+ localName = qName;
+ if(uri.length() == 0)
+ uri = null;
+ this.pushHandler(thi​s.getHandler(uri, localName), attrs);
     }
 
     /**
@@ -67,22 +71,40 @@
 
     /**
      * Obtain a new or cached handler that corresponds to the
- * <code>qName</code>.
- * @param <code>qName</code> The qualified tag name of the
+ * <code>uri</code> and <code>localNam​e</code>.
+ * @param <code>uri</code> The namespace URI or <code>null</code>
+ * if no namespace processing is performed.
+ * @param <code>localNam​e</code> The local tag name of the
      * element for which a handler should be obtained.
      * @return The handler that corresponds to <code>qName</code>.
      * @throws UnrecognizedElementException when no handler
      * could be found or created.
      */
- protected ChildHandler getHandler(String qName)
+ protected ChildHandler getHandler(String uri, String localName)
     throws UnrecognizedElementException
     {
- ChildHandler ch = (ChildHandler)m_crea​tedHandlers.get(qNam​e);
+ ChildHandler ch;
+ HashMap handlerCache = this.getTopHandler()​.getHandlerCache();
+ if(uri == null)
+ {
+ ch = (ChildHandler)handle​rCache.get(localName​);
         if(ch == null)
         {
- ch = this.createHandler(qName);
+ ch = this.createHandler(uri, localName);
             ch.setTopHandler(m_topHandler);
- m_createdHandlers.put(qName, ch);
+ handlerCache.put(localName, ch);
+ }
+ }
+ else
+ {
+ m_nsKeyTemplate.init(uri, localName);
+ ch = (ChildHandler)handle​rCache.get(m_nsKeyTe​mplate);
+ if(ch == null)
+ {
+ ch = this.createHandler(uri, localName);
+ ch.setTopHandler(m_topHandler);
+ handlerCache.put(m_n​sKeyTemplate.clone()​, ch);
+ }
         }
         return ch;
     }
@@ -96,10 +118,11 @@
      * to <code>qName</code>.
      * @throws UnrecognizedElementException unless overridden.
      */
- protected ChildHandler createHandler(String qName)
+ protected ChildHandler createHandler(String uri, String localName)
     throws UnrecognizedElementException
     {
- throw new UnrecognizedElementE​xception(this.getTAG​(), qName, this.getDocumentLocator());
+ throw new UnrecognizedElementException(
+ this.getTAG(), localName, this.getDocumentLocator());
     }
 
     /**
@@ -193,4 +216,43 @@
     {
         m_topHandler = topHandler;
     }
+
+ private static class NSKey implements Cloneable
+ {
+ private String m_uri;
+ private String m_localName;
+ private int m_hash;
+
+ void init(String uri, String localName)
+ {
+ m_uri = uri;
+ m_localName = localName;
+ m_hash = (m_uri.hashCode() << 3) ^ m_localName.hashCode();
+ }
+
+ public Object clone()
+ {
+ try
+ {
+ return super.clone();
+ }
+ catch(CloneNotSuppor​tedException e)
+ {
+ return null;
+ }
+ }
+
+ public boolean equals(Object obj)
+ {
+ if(!(obj instanceof NSKey))
+ return false;
+ NSKey other = (NSKey)obj;
+ return other.m_uri.equals(m_uri) && other.m_localName.eq​uals(m_localName);
+ }
+
+ public int hashCode()
+ {
+ return m_hash;
+ }
+ }
 }




--------------------​--------------------​--------------------​---------
To unsubscribe, e-mail: cvs-unsubscribe@tada​-sax.tigris.org
For additional commands, e-mail: cvs-help at tada-sax dot tigris dot org

« Previous message in topic | 1 of 1 | Next message in topic »

Messages

Show all messages in topic

CVS update: /tada-sax/src/se/tada/util/sax/ thhal Thomas Hallgren 2005-03-03 07:20:53 PST
Messages per page: