You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ak...@apache.org on 2004/04/01 07:02:03 UTC
svn commit: rev 9834 - in incubator/directory/snickers/trunk/ber: . src/java/org/apache/snickers/ber src/java/org/apache/snickers/ber/digester
Author: akarasulu
Date: Wed Mar 31 21:02:01 2004
New Revision: 9834
Modified:
incubator/directory/snickers/trunk/ber/project.xml
incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/IntStack.java
incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/digester/BERDigester.java
Log:
adding more to digester
Modified: incubator/directory/snickers/trunk/ber/project.xml
==============================================================================
--- incubator/directory/snickers/trunk/ber/project.xml (original)
+++ incubator/directory/snickers/trunk/ber/project.xml Wed Mar 31 21:02:01 2004
@@ -33,6 +33,13 @@
</dependency>
<dependency>
+ <groupId>commons-collections</groupId>
+ <artifactId>commons-collections</artifactId>
+ <version>3.0</version>
+ <url>http://jakarta.apache.org/commons/collections</url>
+ </dependency>
+
+ <dependency>
<groupId>commons-primitives</groupId>
<artifactId>commons-primitives</artifactId>
<version>1.1-dev</version>
Modified: incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/IntStack.java
==============================================================================
--- incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/IntStack.java (original)
+++ incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/IntStack.java Wed Mar 31 21:02:01 2004
@@ -157,4 +157,13 @@
{
return list.size() ;
}
+
+
+ /**
+ * Empties the contents of the stack.
+ */
+ public void clear()
+ {
+ list.clear() ;
+ }
}
Modified: incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/digester/BERDigester.java
==============================================================================
--- incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/digester/BERDigester.java (original)
+++ incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/digester/BERDigester.java Wed Mar 31 21:02:01 2004
@@ -17,9 +17,12 @@
package org.apache.snickers.ber.digester ;
-import java.nio.ByteBuffer;
-import java.util.List;
-import java.util.Stack ;
+import java.nio.ByteBuffer ;
+
+import java.util.HashSet;
+import java.util.List ;
+import java.util.Iterator ;
+import java.util.EmptyStackException ;
import org.apache.snickers.ber.Tuple ;
import org.apache.snickers.ber.IntStack ;
@@ -29,6 +32,8 @@
import org.apache.commons.codec.stateful.StatefulDecoder ;
+import org.apache.commons.collections.ArrayStack ;
+
/**
* A special BER TLV event digester. This class was inspired by the XML
@@ -43,14 +48,31 @@
/** the underlying decoder used by this digester */
private BERDecoder decoder ;
/** the object stack where rules push and pop ASN.1 POJO stubs */
- private Stack objectStack ;
+ private ArrayStack objectStack ;
/** the tag stack used to store the nesting pattern */
private IntStack tagStack ;
/** the rules base used by this digester */
private Rules rules ;
/** the currently matched rules */
private List matched ;
-
+ /**
+ * The class loader to use for instantiating application objects.
+ * If not specified, the context class loader, or the class loader
+ * used to load Digester itself, is used, based on the value of the
+ * <code>useContextClassLoader</code> variable.
+ */
+ private ClassLoader classLoader = null ;
+ /**
+ * Do we want to use the Context ClassLoader when loading classes
+ * for instantiating new objects. Default is <code>false</code>.
+ */
+ private boolean useContextClassLoader = false ;
+ /**
+ * The "root" element of the stack (in other words, the last object
+ * that was popped.
+ */
+ private Object root = null ;
+
/**
* Creates a BER TLV event digester.
@@ -58,7 +80,7 @@
public BERDigester()
{
this.rules = new RulesBase() ;
- this.objectStack = new Stack() ;
+ this.objectStack = new ArrayStack() ;
this.decoder = new BERDecoder() ;
this.decoder.setCallback( this ) ;
}
@@ -126,6 +148,7 @@
public void addRule( int[] pattern, Rule rule )
{
rules.add( pattern, rule ) ;
+ rule.setDigester( this ) ;
}
@@ -146,6 +169,8 @@
*/
public void clear()
{
+ root = null ;
+ tagStack.clear() ;
objectStack.clear() ;
}
@@ -162,13 +187,22 @@
/**
- * Return the top object on the stack without removing it.
+ * Return the top object on the stack without removing it. If there are
+ * no objects on the stack, return <code>null</code>.
*
- * @return the object on the top of the stack
+ * @return the top object
*/
- public Object peek()
+ public Object peek()
{
- return objectStack.peek() ;
+ try
+ {
+ return ( objectStack.peek() ) ;
+ }
+ catch ( EmptyStackException e )
+ {
+ //log.warn("Empty stack (returning null)") ;
+ return ( null ) ;
+ }
}
@@ -181,7 +215,15 @@
*/
public Object peek( int n )
{
- return objectStack.get( objectStack.size() - n - 1 ) ;
+ try
+ {
+ return ( objectStack.peek() ) ;
+ }
+ catch ( EmptyStackException e )
+ {
+ //log.warn("Empty stack (returning null)") ;
+ return ( null ) ;
+ }
}
@@ -192,7 +234,15 @@
*/
public Object pop()
{
- return objectStack.pop() ;
+ try
+ {
+ return ( objectStack.pop() ) ;
+ }
+ catch ( EmptyStackException e )
+ {
+ // log.warn("Empty stack (returning null)") ;
+ return ( null ) ;
+ }
}
@@ -203,9 +253,27 @@
*/
public void push( Object object )
{
+ if ( objectStack.size() == 0 )
+ {
+ root = object ;
+ }
+
objectStack.push( object ) ;
}
+
+ /**
+ * This method allows you to access the root object that has been
+ * created after decoding.
+ *
+ * @return the root object that has been created after decoding or null if
+ * the digester has not decoded any PDUs yet.
+ */
+ public Object getRoot()
+ {
+ return this.root ;
+ }
+
/**
* Set the Rules implementation object containing our rules collection
@@ -216,6 +284,7 @@
public void setRules( Rules rules )
{
this.rules = rules ;
+ this.rules.setDigester( this ) ;
}
@@ -232,25 +301,85 @@
}
+ /**
+ * Return the class loader to be used for instantiating application objects
+ * when required. This is determined based upon the following rules:
+ * <ul>
+ * <li>The class loader set by <code>setClassLoader()</code>, if any</li>
+ * <li>The thread context class loader, if it exists and the
+ * <code>useContextClassLoader</code> property is set to true</li>
+ * <li>The class loader used to load the Digester class itself.
+ * </ul>
+ */
+ public ClassLoader getClassLoader()
+ {
+ if ( classLoader != null )
+ {
+ return ( classLoader ) ;
+ }
+
+ if ( useContextClassLoader)
+ {
+ ClassLoader classLoader =
+ Thread.currentThread().getContextClassLoader() ;
+ if ( classLoader != null )
+ {
+ return ( classLoader ) ;
+ }
+ }
+
+ return ( getClass().getClassLoader() ) ;
+ }
+
+
+ /**
+ * Set the class loader to be used for instantiating application objects
+ * when required.
+ *
+ * @param classLoader The new class loader to use, or <code>null</code>
+ * to revert to the standard rules
+ */
+ public void setClassLoader( ClassLoader classLoader )
+ {
+ this.classLoader = classLoader ;
+ }
+
+
+ /**
+ * Return the boolean as to whether the context classloader should be used.
+ */
+ public boolean getUseContextClassLoader()
+ {
+ return useContextClassLoader ;
+ }
+
+
+ /**
+ * Determine whether to use the Context ClassLoader (the one found by
+ * calling <code>Thread.currentThread().getContextClassLoader()</code>)
+ * to resolve/load classes that are defined in various rules. If not
+ * using Context ClassLoader, then the class-loading defaults to
+ * using the calling-class' ClassLoader.
+ *
+ * @param use determines whether to use Context ClassLoader.
+ */
+ public void setUseContextClassLoader( boolean use )
+ {
+ useContextClassLoader = use ;
+ }
+
+
/*
Methods of interest from the original digester class:
- java.lang.ClassLoader getClassLoader()
- Return the class loader to be used for instantiating application objects when required.
- boolean getUseContextClassLoader()
- Return the boolean as to whether the context classloader should be used.
- void setClassLoader(java.lang.ClassLoader classLoader)
- Set the class loader to be used for instantiating application objects when required.
- void setUseContextClassLoader(boolean use)
- Determine whether to use the Context ClassLoader (the one found by calling Thread.currentThread().getContextClassLoader()) to resolve/load classes that are defined in various rules.
-
java.lang.String getMatch()
Return the current rule match path
java.lang.Object peekParams()
Return the top object on the parameters stack without removing it.
java.lang.Object peekParams(int n)
- Return the n'th object down the parameters stack, where 0 is the top element and [getCount()-1] is the bottom element.
+ Return the n'th object down the parameters stack, where 0 is the top
+ element and [getCount()-1] is the bottom element.
java.lang.Object popParams()
Pop the top object off of the parameters stack, and return it.
void pushParams(java.lang.Object object)
@@ -265,24 +394,163 @@
void fireTagEvent( int id, boolean isPrimitive, TypeClass typeClass )
{
- // do nothing for now
+ pop() ;
+
+ // Fire "tag" events for all relevant rules
+ Iterator rules = matched.iterator() ;
+
+ while ( rules.hasNext() )
+ {
+ Rule rule = ( Rule ) rules.next() ;
+
+ try
+ {
+ rule.tag( id, isPrimitive, typeClass ) ;
+ }
+ catch ( Exception e )
+ {
+ // log.error( "Tag event threw exception", e ) ;
+ // throw createSAXException(e);
+ }
+ catch ( Error e )
+ {
+ // log.error( "Tag event threw error", e ) ;
+ throw e ;
+ }
+ }
}
void fireLengthEvent( int length )
{
- // do nothing for now
+ pop() ;
+
+ // Fire "length" events for all relavent rules
+ Iterator rules = matched.iterator() ;
+
+ while ( rules.hasNext() )
+ {
+ Rule rule = ( Rule ) rules.next() ;
+
+ try
+ {
+ rule.length( length ) ;
+ }
+ catch ( Exception e )
+ {
+ // log.error( "Length event threw exception", e ) ;
+ // throw createSAXException(e);
+ }
+ catch ( Error e )
+ {
+ // log.error( "Length event threw error", e ) ;
+ throw e ;
+ }
+ }
}
void fireValueEvent( ByteBuffer buf )
{
- // do nothing for now
+ pop() ;
+
+ // Fire "value" events for all relavent rules
+ Iterator rules = matched.iterator() ;
+
+ while ( rules.hasNext() )
+ {
+ Rule rule = ( Rule ) rules.next() ;
+
+ try
+ {
+ rule.value( buf ) ;
+ }
+ catch ( Exception e )
+ {
+ // log.error( "Value event threw exception", e ) ;
+ // throw createSAXException(e);
+ }
+ catch ( Error e )
+ {
+ // log.error( "Value event threw error", e ) ;
+ throw e ;
+ }
+ }
}
void fireFinishEvent()
{
- // do nothing for now
+ pop() ;
+
+
+ HashSet seen = null ;
+
+ // Fire "finish" events for all relevant rules in reverse order
+ if ( matched != null )
+ {
+ seen = new HashSet() ;
+
+ for ( int i = 0; i < matched.size(); i++ )
+ {
+ int j = ( matched.size() - i ) - 1 ;
+
+ try
+ {
+ Rule rule = ( Rule ) matched.get( j ) ;
+
+ /*
+ if (debug) {
+ log.debug(" Fire end() for " + rule);
+ }
+ */
+
+ rule.finish() ;
+ seen.add( rule ) ;
+ }
+ catch ( Exception e )
+ {
+ //log.error("End event threw exception", e);
+ //throw createSAXException(e);
+ }
+ catch ( Error e )
+ {
+ //log.error("End event threw error", e);
+ throw e ;
+ }
+ }
+ }
+
+
+ if ( tagStack.empty() )
+ {
+ // Fire "finish" events for all defined rules
+ Iterator rules = getRules().rules().iterator() ;
+
+ while ( rules.hasNext() )
+ {
+ Rule rule = ( Rule ) rules.next() ;
+
+ if ( seen != null && seen.contains( rule ) )
+ {
+ continue ;
+ }
+
+ try
+ {
+ rule.finish() ;
+ }
+ catch ( Exception e )
+ {
+ // log.error( "Finish event threw exception", e ) ;
+ // throw createSAXException(e);
+ }
+ catch ( Error e )
+ {
+ // log.error( "Finish event threw error", e ) ;
+ throw e ;
+ }
+ }
+ }
}
}