// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package com.netscape.cmscore.notification; import java.util.Enumeration; import java.util.Hashtable; import java.util.StringTokenizer; import java.util.Vector; import com.netscape.certsrv.apps.CMS; import com.netscape.certsrv.logging.ILogger; import com.netscape.certsrv.notification.IEmailFormProcessor; /** * formulates the final email. Escape character '\' is understood. * '$' is used preceeding a token name. A token name should not be a * substring of any other token name *

* * @author cfu * @version $Revision$, $Date$ */ public class EmailFormProcessor implements IEmailFormProcessor { protected final static String TOK_PREFIX = "$"; protected final static String TOK_ESC = "\\"; protected final static char TOK_END = ' '; protected final static String TOK_VALUE_UNKNOWN = "VALUE UNKNOWN"; protected final static String TOK_TOKEN_UNKNOWN = "UNKNOWN TOKEN:"; protected ILogger mLogger = CMS.getLogger(); // stores all the available token keys; added so that we can // parse strings to replace unresolvable token keys and replace // them by the words "VALUE UNKNOWN" protected static String[] token_keys = { TOKEN_ID, TOKEN_SERIAL_NUM, TOKEN_HTTP_HOST, TOKEN_HTTP_PORT, TOKEN_ISSUER_DN, TOKEN_SUBJECT_DN, TOKEN_REQUESTOR_EMAIL, TOKEN_CERT_TYPE, TOKEN_REQUEST_TYPE, TOKEN_STATUS, TOKEN_NOT_AFTER, TOKEN_NOT_BEFORE, TOKEN_SENDER_EMAIL, TOKEN_RECIPIENT_EMAIL, TOKEN_SUMMARY_ITEM_LIST, TOKEN_SUMMARY_TOTAL_NUM, TOKEN_SUMMARY_SUCCESS_NUM, TOKEN_SUMMARY_FAILURE_NUM, TOKEN_EXECUTION_TIME }; // stores the eventual content of the email Vector mContent = new Vector(); Hashtable mTok2vals = null; public EmailFormProcessor() { } /* * takes the form template, parse and replace all $tokens with the * right values. It handles escape character '\' * @param form The locale specific form template, * @param tok2vals a hashtable containing one to one mapping * from $tokens used by the admins in the form template to the real * values corresponding to the $tokens * @return mail content */ public String getEmailContent(String form, Hashtable tok2vals) { mTok2vals = tok2vals; if (form == null) { log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_NOTIFY_TEMPLATE_NULL")); return null; } if (mTok2vals == null) { log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_NOTIFY_TOKEN_NULL")); return null; } /** * first, take care of the escape characters '\' */ StringTokenizer es = new StringTokenizer(form, TOK_ESC); if (es.hasMoreTokens() && !form.startsWith(TOK_ESC)) { dollarProcess(es.nextToken()); } // rest of them start with '\' while (es.hasMoreTokens()) { String t = es.nextToken(); // put first character (escaped char) in mContent char c = t.charAt(0); Character ch = Character.valueOf(c); mContent.add(ch.toString()); // process the rest for $tokens String r = t.substring(1); dollarProcess(r); } return formContent(mContent); } private void dollarProcess(String sub) { StringTokenizer st = new StringTokenizer(sub, TOK_PREFIX); // if first token is not a $token, put in mContent as is if (st.hasMoreTokens() && !sub.startsWith(TOK_PREFIX)) { String a = st.nextToken(); mContent.add(a); } /* * all of the string tokens below begin with a '$' * match it one by one with the mTok2vals table */ while (st.hasMoreTokens()) { String t = st.nextToken(); /* * We don't know when a token ends. Compare with every * token in the table for the first match. Which means, a * token name should not be a substring of any token name */ boolean matched = false; String tok = null; for (Enumeration e = mTok2vals.keys(); e.hasMoreElements();) { // get key tok = e.nextElement(); // compare key with $token if (t.startsWith(tok)) { // match, put val in mContent Object o = mTok2vals.get(tok); if (o != null) { String s = (String) o; if (!s.equals("")) { mContent.add(s); } else { break; } } else { // no value, bail out break; } // now, put the rest of the non-token string in mContent if (t.length() != tok.length()) { mContent.add(t.substring(tok.length())); } matched = true; // replaced! bail out. break; } } if (!matched) { boolean keyFound = false; // no match, put the token back, as is // -- for bug 382162, don't remove the following line, in // case John changes his mind for the better // mContent.add(TOK_PREFIX+t); for (int i = 0; i < token_keys.length; i++) { if (t.startsWith(token_keys[i])) { // match, replace it with the TOK_VALUE_UNKNOWN mContent.add(TOK_VALUE_UNKNOWN); // now, put the rest of the non-token string // in mContent if (t.length() != token_keys[i].length()) { mContent.add(t.substring(token_keys[i].length())); } keyFound = true; break; } // keep looking } if (keyFound == false) { mContent.add(TOK_TOKEN_UNKNOWN + TOK_PREFIX + t); } } } } /** * takes a vector of strings and concatenate them */ public String formContent(Vector vec) { StringBuffer content = new StringBuffer(); Enumeration e = vec.elements(); // initialize content with first element if (e.hasMoreElements()) { content.append(e.nextElement()); } while (e.hasMoreElements()) { String v = e.nextElement(); content.append(v); } return content.toString(); } /** * logs an entry in the log file. */ public void log(int level, String msg) { if (mLogger == null) return; mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_OTHER, level, "EmailFormProcessor: " + msg); } }