You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by si...@apache.org on 2011/05/14 18:13:32 UTC
svn commit: r1103148 -
/commons/sandbox/digester3/trunk/src/main/java/org/apache/commons/digester3/binder/RulesBinder.java
Author: simonetripodi
Date: Sat May 14 16:13:31 2011
New Revision: 1103148
URL: http://svn.apache.org/viewvc?rev=1103148&view=rev
Log:
RulesBinder turned as a proper class instead of interface
Modified:
commons/sandbox/digester3/trunk/src/main/java/org/apache/commons/digester3/binder/RulesBinder.java
Modified: commons/sandbox/digester3/trunk/src/main/java/org/apache/commons/digester3/binder/RulesBinder.java
URL: http://svn.apache.org/viewvc/commons/sandbox/digester3/trunk/src/main/java/org/apache/commons/digester3/binder/RulesBinder.java?rev=1103148&r1=1103147&r2=1103148&view=diff
==============================================================================
--- commons/sandbox/digester3/trunk/src/main/java/org/apache/commons/digester3/binder/RulesBinder.java (original)
+++ commons/sandbox/digester3/trunk/src/main/java/org/apache/commons/digester3/binder/RulesBinder.java Sat May 14 16:13:31 2011
@@ -17,15 +17,67 @@
*/
package org.apache.commons.digester3.binder;
+import static java.lang.String.format;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Formatter;
+import java.util.List;
+
+import org.apache.commons.digester3.RuleSet;
+
/**
* The Digester EDSL.
*
* @since 3.0
*/
-public interface RulesBinder
+public final class RulesBinder
{
/**
+ * The default head when reporting an errors list.
+ */
+ private static final String HEADING = "Digester creation errors:%n%n";
+
+ /**
+ * Errors that can occur during binding time or rules creation.
+ */
+ private final List<ErrorMessage> errors = new ArrayList<ErrorMessage>();
+
+ /**
+ *
+ */
+ private final FromBinderRuleSet fromBinderRuleSet = new FromBinderRuleSet();
+
+ /**
+ *
+ */
+ private ClassLoader classLoader;
+
+ /**
+ *
+ *
+ * @param classLoader
+ */
+ void initialize( ClassLoader classLoader )
+ {
+ this.classLoader = classLoader;
+ fromBinderRuleSet.clear();
+ errors.clear();
+ }
+
+ /**
+ *
+ *
+ * @return
+ */
+ public ClassLoader getContextClassLoader()
+ {
+ return this.classLoader;
+ }
+
+ /**
* Records an error message which will be presented to the user at a later time. Unlike throwing an exception, this
* enable us to continue configuring the Digester and discover more errors. Uses
* {@link String#format(String, Object[])} to insert the arguments into the message.
@@ -33,7 +85,52 @@ public interface RulesBinder
* @param messagePattern The message string pattern
* @param arguments Arguments referenced by the format specifiers in the format string
*/
- void addError( String messagePattern, Object... arguments );
+ public void addError( String messagePattern, Object... arguments )
+ {
+ StackTraceElement[] stackTrace = new Exception().getStackTrace();
+ StackTraceElement element = null;
+
+ int stackIndex = stackTrace.length - 1;
+ while ( element == null && stackIndex > 0 ) // O(n) there's no better way
+ {
+ Class<?> moduleClass = null;
+ try
+ {
+ // check if the set ClassLoader resolves the Class in the StackTrace
+ moduleClass = Class.forName( stackTrace[stackIndex].getClassName(), false, this.classLoader );
+ }
+ catch ( ClassNotFoundException e )
+ {
+ try
+ {
+ // try otherwise with current ClassLoader
+ moduleClass =
+ Class.forName( stackTrace[stackIndex].getClassName(), false, this.getClass().getClassLoader() );
+ }
+ catch ( ClassNotFoundException e1 )
+ {
+ // Class in the StackTrace can't be found, don't write the file name:line number detail in the
+ // message
+ }
+ }
+
+ if ( moduleClass != null )
+ {
+ if ( RulesModule.class.isAssignableFrom( moduleClass ) )
+ {
+ element = stackTrace[stackIndex];
+ }
+ }
+
+ stackIndex--;
+ }
+
+ if ( element != null )
+ {
+ messagePattern = format( "%s (%s:%s)", messagePattern, element.getFileName(), element.getLineNumber() );
+ }
+ addError( new ErrorMessage( messagePattern, arguments ) );
+ }
/**
* Records an exception, the full details of which will be logged, and the message of which will be presented to the
@@ -42,14 +139,30 @@ public interface RulesBinder
*
* @param t The exception has to be recorded.
*/
- void addError( Throwable t );
+ public void addError( Throwable t )
+ {
+ String message = "An exception was caught and reported. Message: " + t.getMessage();
+ addError( new ErrorMessage( message, t ) );
+ }
+
+ /**
+ *
+ *
+ * @param errorMessage
+ */
+ private void addError(ErrorMessage errorMessage) {
+ this.errors.add(errorMessage);
+ }
/**
* Allows sub-modules inclusion while binding rules.
*
* @param rulesModule the sub-module has to be included.
*/
- void install( RulesModule rulesModule );
+ public void install( RulesModule rulesModule )
+ {
+ rulesModule.configure( this );
+ }
/**
* Allows to associate the given pattern to one or more Digester rules.
@@ -57,6 +170,70 @@ public interface RulesBinder
* @param pattern The pattern that this rule should match
* @return The Digester rules builder
*/
- LinkedRuleBuilder forPattern( String pattern );
+ public LinkedRuleBuilder forPattern( String pattern )
+ {
+ final String keyPattern;
+
+ if ( pattern == null || pattern.length() == 0 )
+ {
+ addError( "Null or empty pattern is not valid" );
+ keyPattern = null;
+ }
+ else
+ {
+ if ( pattern.endsWith( "/" ) )
+ {
+ // to help users who accidently add '/' to the end of their patterns
+ keyPattern = pattern.substring( 0, pattern.length() - 1 );
+ }
+ else
+ {
+ keyPattern = pattern;
+ }
+ }
+
+ return new LinkedRuleBuilder( this, fromBinderRuleSet, classLoader, keyPattern );
+ }
+
+ /**
+ *
+ * @return
+ */
+ RuleSet buildRuleSet()
+ {
+ if ( !this.errors.isEmpty() )
+ {
+ Formatter fmt = new Formatter().format( HEADING );
+ int index = 1;
+
+ for ( ErrorMessage errorMessage : this.errors )
+ {
+ fmt.format( "%s) %s%n", index++, errorMessage.getMessage() );
+
+ Throwable cause = errorMessage.getCause();
+ if ( cause != null )
+ {
+ StringWriter writer = new StringWriter();
+ cause.printStackTrace( new PrintWriter( writer ) );
+ fmt.format( "Caused by: %s", writer.getBuffer() );
+ }
+
+ fmt.format( "%n" );
+ }
+
+ if ( this.errors.size() == 1 )
+ {
+ fmt.format( "1 error" );
+ }
+ else
+ {
+ fmt.format( "%s errors", this.errors.size() );
+ }
+
+ throw new DigesterLoadingException( fmt.toString() );
+ }
+
+ return fromBinderRuleSet;
+ }
}