001: /*
002: * Copyright (C) 2006 Methodhead Software LLC. All rights reserved.
003: *
004: * This file is part of TransferCM.
005: *
006: * TransferCM is free software; you can redistribute it and/or modify it under the
007: * terms of the GNU General Public License as published by the Free Software
008: * Foundation; either version 2 of the License, or (at your option) any later
009: * version.
010: *
011: * TransferCM is distributed in the hope that it will be useful, but WITHOUT ANY
012: * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
013: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
014: * details.
015: *
016: * You should have received a copy of the GNU General Public License along with
017: * TransferCM; if not, write to the Free Software Foundation, Inc., 51 Franklin St,
018: * Fifth Floor, Boston, MA 02110-1301 USA
019: */
020:
021: package com.methodhead.util;
022:
023: import java.util.Map;
024: import java.util.HashMap;
025: import java.util.Iterator;
026: import java.util.regex.Pattern;
027: import java.util.regex.Matcher;
028:
029: import org.apache.commons.beanutils.DynaClass;
030: import org.apache.commons.beanutils.DynaProperty;
031: import org.apache.commons.beanutils.BasicDynaClass;
032: import org.apache.commons.beanutils.BeanUtils;
033: import org.apache.commons.lang.exception.ExceptionUtils;
034: import org.apache.commons.lang.StringUtils;
035: import java.lang.reflect.InvocationTargetException;
036: import java.security.MessageDigest;
037: import java.security.NoSuchAlgorithmException;
038: import org.apache.commons.codec.binary.Base64;
039:
040: public class MhfStringUtils {
041:
042: // constructors /////////////////////////////////////////////////////////////
043:
044: // constants ////////////////////////////////////////////////////////////////
045:
046: // classes //////////////////////////////////////////////////////////////////
047:
048: // methods //////////////////////////////////////////////////////////////////
049:
050: /**
051: * Utility method to extract the properties of <tt>o</tt> as a map.
052: */
053: protected static Map extractProperties(Object o) {
054:
055: //
056: // convert the readable properties of o into a map of strings
057: //
058: Map fields = new HashMap();
059:
060: try {
061: Map properties = BeanUtils.describe(o);
062: for (Iterator iter = properties.keySet().iterator(); iter
063: .hasNext();) {
064: String key = iter.next().toString();
065: fields.put(key, BeanUtils.getProperty(o, key));
066: }
067: } catch (IllegalAccessException e) {
068: throw new RuntimeException(
069: "Unexpected IllegalAccessException while getting properties for "
070: + "object."
071: + ExceptionUtils.getStackTrace(e));
072: } catch (InvocationTargetException e) {
073: throw new RuntimeException(
074: "Unexpected InvocationTargetException while getting properties for "
075: + "object."
076: + ExceptionUtils.getStackTrace(e));
077: } catch (NoSuchMethodException e) {
078: throw new RuntimeException(
079: "Unexpected NoSuchMethodException while getting properties for "
080: + "object."
081: + ExceptionUtils.getStackTrace(e));
082: }
083:
084: return fields;
085: }
086:
087: /**
088: * Utility method to merge the values in <tt>fields</tt> into <tt>text</tt>,
089: * returning the resulting message. The keys and values are treated as
090: * <tt>String</tt>s. If the template references a field that is not provided
091: * by <tt>fields</tt>, a <tt>RuntimeException</tt> is thrown.
092: */
093: public static String merge(String text, Map fields) {
094:
095: //
096: // verify fields provides all fields we'll need
097: //
098: Pattern pattern = Pattern.compile("\\{(\\w+)\\}",
099: Pattern.MULTILINE);
100: Matcher matcher = pattern.matcher(text);
101:
102: while (matcher.find()) {
103: if (!fields.containsKey(matcher.group(1)))
104: throw new RuntimeException(
105: "Values don't include field \""
106: + matcher.group(1)
107: + "\", required by mail template text.");
108: }
109:
110: //
111: // substitute the fields
112: //
113: String result = text;
114: for (Iterator iter = fields.keySet().iterator(); iter.hasNext();) {
115: String key = iter.next().toString();
116: result = StringUtils.replace(result, "{" + key + "}",
117: fields.get(key).toString());
118: }
119:
120: return result;
121: }
122:
123: /**
124: * Merges the properties of <tt>o</tt> into the template, returning the
125: * resulting message. The properties of are treated as <tt>String</tt>s.
126: * <tt>DynaBeans</tt> are supported. Keep in mind that inherent properties
127: * of objects (e.g., "class") are not omitted. If the template references a
128: * property that is not provided by <tt>o</tt>, a <tt>RuntimeException</tt>
129: * is thrown.
130: */
131: public static String merge(String text, Object o) {
132:
133: //
134: // merge as with a map
135: //
136: return merge(text, extractProperties(o));
137: }
138:
139: /**
140: * Encrypts <tt>s</tt> by MD5 hashing it and Base64 encoding the
141: * result.
142: */
143: public static String hashAndEncode(String s) {
144:
145: try {
146: MessageDigest md5 = MessageDigest.getInstance("MD5");
147: return new String(Base64.encodeBase64(md5.digest(s
148: .getBytes())));
149: } catch (NoSuchAlgorithmException e) {
150: throw new RuntimeException(
151: "Unexpected NoSuchAlgorithmException:\n"
152: + ExceptionUtils.getStackTrace(e));
153: }
154: }
155:
156: // properties ///////////////////////////////////////////////////////////////
157:
158: // attributes ///////////////////////////////////////////////////////////////
159: }
|