1

I'm working with a Struts2 program that constructs an email message using an email template file and replaces certain placeholder strings in the template with user input retrieved through a form field. The JavaMail project is being used to form the email.

Here's what that looks like:

InputStream in = getClass().getResourceAsStream("emailTemplate.html");
Scanner scanner = new Scanner( in );
String content = "";
while( scanner.hasNextLine() ) {
    content += parseLine( scanner.nextLine() );
}

// ...

email.setHtmlContent( content );

The parseLine method looks like this:

String emailReqNum = //internal code to return number from form;
String emailCompDate = //internal code to return date from form;
String emailComment = //internal code to return comment from form;
String emailStatus = //internal code to return status from form;
String emailServer = //internal code to return server from form;

line = line.replaceAll( "\\[REQUEST NUMBER\\]", emailReqNum );
line = line.replaceAll( "\\[ESTIMATED COMPLETION DATE\\]", emailCompDate );
line = line.replaceAll( "\\[COMMENT\\]", emailComment );
line = line.replaceAll( "\\[STATUS\\]", emailStatus );
line = line.replaceAll( "\\[SERVER\\]", emailServer );

And this is what part of the email template looks like:

<table>
<tr><td><b>Request Number:</b></td><td>[REQUEST NUMBER]</td></tr>
<tr><td><b>Est. Completion Date:</b></td><td>[ESTIMATED COMPLETION DATE]</td></tr>
<tr><td><b>Comment:</b></td><td>[COMMENT]</td></tr>
<tr><td><b>Status:</b></td><td>[STATUS]</td></tr>
</table>

The problem is that whenever a user enters a special RegEx character (\ ^ $ . | ? * + ( ) [ ] { }) in the comment field, it breaks the replaceAll methods:

Exception in thread "main" java.lang.IllegalArgumentException: Illegal group reference
at java.util.regex.Matcher.appendReplacement(Matcher.java:725)
at java.util.regex.Matcher.replaceAll(Matcher.java:825)
at java.lang.String.replaceAll(String.java:1572)

I've tried replacing each of the offending special characters with an escaped version, but that didn't seem to work, and looks ugly as sin:

String filtered = emailComment;
filtered.replaceAll("\\","\\\\");
filtered.replaceAll("\\^","\\\\^");
filtered.replaceAll("\\$","\\\\$");
filtered.replaceAll("\\.","\\\\.");
filtered.replaceAll("\\|","\\\\|");
filtered.replaceAll("\\?","\\\\?");
filtered.replaceAll("\\*","\\\\*");
filtered.replaceAll("\\+","\\\\+");
filtered.replaceAll("\\(","\\\\(");
filtered.replaceAll("\\)","\\\\)");
filtered.replaceAll("\\[","\\\\[");
filtered.replaceAll("\\]","\\\\]");
filtered.replaceAll("\\{","\\\\{");
filtered.replaceAll("\\}","\\\\}");

I fooled around a bit with loops, too.

What I'm ultimately trying to do is go through the user-entered comments, find any special characters, and possibly change them so that the replaceAll method calls in parseLine (above) work successfully to replace the comment in the email's contents. Any ideas?

Thanks!

EDIT:

I guess it makes sense that HTML can't be effectively parsed with RegEx. Maybe I can make the email content plaintext, but I'm not certain that's what my company wants.

J.D. Mallen
  • 4,339
  • 3
  • 22
  • 33
  • 1
    http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 – sanz Sep 24 '14 at 18:31
  • Heh, whoa, that's uh... Well, I wish I had known that. Thanks! I guess that's a bit of a relief, but the challenge remains in trying to form an email with custom content based on unique strings. – J.D. Mallen Sep 24 '14 at 18:35
  • You going to be swimming upstream. You can do it but you will run into bugs if you don't control the input. – sanz Sep 24 '14 at 18:48
  • 2
    Have you considered using some template engine (e.g. FreeMarker). See this: http://stackoverflow.com/q/13623220/1700321. – Aleksandr M Sep 24 '14 at 19:32

1 Answers1

0

It's not pretty, but what I ended up doing was using StringBuilder in the parseline method to form the HTML, while incorporating the user variables.

I may later incorporate FreeMarker as it's already included with the Struts2 core, but since the email message is so simple (and isn't likely to change in style or content anytime soon), this will suffice for now.

Thanks for the suggestions.

J.D. Mallen
  • 4,339
  • 3
  • 22
  • 33