[jboss-cvs] jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/ui ...

Christian Bauer christian at hibernate.org
Wed Sep 26 05:36:18 EDT 2007


  User: cbauer  
  Date: 07/09/26 05:36:18

  Modified:    examples/wiki/src/main/org/jboss/seam/wiki/core/ui  
                        SeamTextValidator.java UIWikiFormattedText.java
  Log:
  New handling for Seam Text errors, no more STDERR garbage
  
  Revision  Changes    Path
  1.2       +62 -35    jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/SeamTextValidator.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: SeamTextValidator.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/SeamTextValidator.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -b -r1.1 -r1.2
  --- SeamTextValidator.java	24 Sep 2007 08:23:20 -0000	1.1
  +++ SeamTextValidator.java	26 Sep 2007 09:36:17 -0000	1.2
  @@ -14,19 +14,31 @@
   import org.jboss.seam.text.SeamTextLexer;
   import org.jboss.seam.text.SeamTextParser;
   
  -import antlr.ANTLRException;
   import antlr.RecognitionException;
  +import antlr.TokenStreamException;
   
   /**
    * Seam Text validator
  - * @author matthew.drees
    *
  + * Use as a JSF validator on an input control that allows entering Seam Text markup.
  + * <p>
  + * The Seam Text parser has a disabled default error handler, catch exceptions as appropriate if you display
  + * Seam Text
  + * (see <a href="http://www.doc.ic.ac.uk/lab/secondyear/Antlr/err.html">http://www.doc.ic.ac.uk/lab/secondyear/Antlr/err.html</a>)
  + * and call the static convenience method <tt>SeamTextValidator.getErrorMessage(originalText, recognitionException)</tt> if you
  + * want to display or log a nice error message.
  + *
  + * @author matthew.drees
  + * @author Christian Bauer
    */
   @Validator
   @Name("seamTextValidator")
   public class SeamTextValidator implements javax.faces.validator.Validator, Serializable {
   	private static final long serialVersionUID = 1L;
   
  +    private static final int NUMBER_OF_CONTEXT_CHARS_AFTER = 10;
  +    private static final int NUMBER_OF_CONTEXT_CHARS_BEFORE = 10;
  +
   	String firstError;
   
   	/**
  @@ -39,30 +51,45 @@
   			return;
   		}
   
  -		if (!(value instanceof String)){
  +        if (!(value instanceof String)) {
   			throw new IllegalArgumentException("Value is not a string: " + value);
   		}
   		String text = (String) value;
           Reader r = new StringReader(text);
           SeamTextLexer lexer = new SeamTextLexer(r);
  -        SeamTextParser parser = new SeamTextParser(lexer) {
  -
  -			@Override
  -			public void reportError(RecognitionException re) {
  -				if (firstError == null) {
  -					firstError = re.getMessage();
  -				}
  -			}
  -        };
  +        SeamTextParser parser = new SeamTextParser(lexer);
           try {
   			parser.startRule();
   		}
  -        catch (ANTLRException re) {
  -			throw new RuntimeException("Can't parse text", re);
  +        // Error handling for ANTLR lexer/parser errors, see http://www.doc.ic.ac.uk/lab/secondyear/Antlr/err.html
  +        catch (TokenStreamException tse) {
  +            // Problem with the token input stream
  +            throw new RuntimeException(tse);
   		}
  +        catch (RecognitionException re) {
  +            // A parser error, just log and swallow
  +            if (firstError == null) {
  +                firstError = getErrorMessage(text, re);
  +            }
  +        }
  +
           if (firstError != null) {
  -        	firstError = firstError.replace("\uFFFF", "[END OF TEXT]");
  -        	throw new ValidatorException(new FacesMessage("Invalid text: " + firstError));
  +            throw new ValidatorException(new FacesMessage("Invalid markup: " + firstError));
  +        }
           }
  +
  +    /**
  +     * Extracts the error from the <tt>RecognitionException</tt> and generates a message with some helpful context.
  +     *
  +     * @param originalText the original Seam Text markup as fed into the parser
  +     * @param re an ANTLR <tt>RecognitionException</tt> thrown by the parser
  +     * @return an error message with some helpful context about where the error occured
  +     */
  +    public static String getErrorMessage(String originalText, RecognitionException re) {
  +        int beginIndex = Math.max(re.getColumn() - 1 - NUMBER_OF_CONTEXT_CHARS_BEFORE, 0);
  +        int endIndex = Math.min(re.getColumn() + NUMBER_OF_CONTEXT_CHARS_AFTER, originalText.length());
  +        String msg = re.getMessage() + " at '" + (beginIndex == 0 ? "" : "...")
  +                     + originalText.substring(beginIndex, endIndex) + (endIndex == originalText.length() ? "" : "...") + "'";
  +        return msg.replace("\n", " ").replace("\r", " ").replace("\uFFFF", "[END OF TEXT]");
   	}
   }
  
  
  
  1.29      +25 -1     jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/UIWikiFormattedText.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: UIWikiFormattedText.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/UIWikiFormattedText.java,v
  retrieving revision 1.28
  retrieving revision 1.29
  diff -u -b -r1.28 -r1.29
  --- UIWikiFormattedText.java	24 Sep 2007 08:23:20 -0000	1.28
  +++ UIWikiFormattedText.java	26 Sep 2007 09:36:17 -0000	1.29
  @@ -17,6 +17,8 @@
   import javax.faces.context.ResponseWriter;
   
   import org.jboss.seam.Component;
  +import org.jboss.seam.log.Log;
  +import org.jboss.seam.log.Logging;
   import org.jboss.seam.ui.util.JSF;
   import org.jboss.seam.contexts.Contexts;
   import org.jboss.seam.core.Conversation;
  @@ -28,9 +30,21 @@
   import org.jboss.seam.wiki.core.model.Document;
   import org.jboss.seam.wiki.core.model.Node;
   import org.jboss.seam.wiki.util.WikiUtil;
  +import antlr.RecognitionException;
  +import antlr.ANTLRException;
   
  +/**
  + * Uses WikiTextParser and WikiLinkResolver to render Seam Text markup with wiki links.
  + *
  + * Any lexer/parser error results in WARN level log message, you can disable this in your logging
  + * configuration by raising the log level for this class to ERROR.
  + *
  + * @author Christian Bauer
  + */
   public class UIWikiFormattedText extends UIOutput {
   
  +    Log log = Logging.getLog(UIWikiFormattedText.class);
  +
       public static final String ATTR_LINK_STYLE_CLASS                = "linkStyleClass";
       public static final String ATTR_BROKEN_LINK_STYLE_CLASS         = "brokenLinkStyleClass";
       public static final String ATTR_ATTACHMENT_LINK_STYLE_CLASS     = "attachmentLinkStyleClass";
  @@ -200,8 +214,18 @@
           Boolean updateResolvedLinks =
                   getAttributes().get(ATTR_UPDATE_RESOLVED_LINKS) == null
                   || Boolean.valueOf((String) getAttributes().get(ATTR_UPDATE_RESOLVED_LINKS));
  +        try {
  +
           parser.parse(updateResolvedLinks);
   
  +        } catch (RecognitionException rex) {
  +            // Log a nice message for any lexer/parser errors, users can disable this if they want to
  +            log.warn( SeamTextValidator.getErrorMessage((String) getValue(), rex) );
  +        } catch (ANTLRException ex) {
  +            // All other errors are fatal;
  +            throw new RuntimeException(ex);
  +        }
  +
           facesContext.getResponseWriter().write(parser.toString());
   
       }
  
  
  



More information about the jboss-cvs-commits mailing list