View Javadoc

1   /*
2   Copyright (c) 2005, CodeSmarts
3    All rights reserved.
4   
5   Redistribution and use in source and binary forms, with or without
6   modification, are permitted provided that the following conditions are
7   met:
8   	* 	Redistributions of source code must retain the above copyright
9   notice, this list of conditions and the following disclaimer.
10  	* 	Redistributions in binary form must reproduce the above
11  copyright notice, this list of conditions and the following disclaimer
12  in the documentation and/or other materials provided with the
13  distribution.
14  	* 	Neither the name of the CodeSmarts nor the names of its
15  contributors may be used to endorse or promote products derived from
16  this software without specific prior written permission.
17  
18  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
19  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
21  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
22  OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30  
31  package net.codesmarts.log4j;
32  
33  import java.security.*;
34  import java.util.Iterator;
35  import java.util.List;
36  
37  import org.apache.log4j.Logger;
38  import org.apache.log4j.spi.LocationInfo;
39  import org.apache.log4j.spi.LoggingEvent;
40  
41  /***
42   * Methods for creating semiunique hash values based on logging incidents
43   * @author Fred McCann
44   */
45  public class HashUtility {
46      private static Logger log = Logger.getLogger(HashUtility.class);
47      
48      public static final int LOCATION = 0;
49      public static final int CONTENT = 1;
50      public static final int THROWABLE = 2;
51      
52      /***
53       * Create hash values based on incidents
54       * @param eventList
55       * @return
56       */
57      protected static String hash(List eventList, int method) {
58          if (eventList==null || eventList.size()==0)
59              return null;
60          
61          StringBuffer buffer = new StringBuffer();
62          
63          Iterator i = eventList.iterator();
64          
65          while (i.hasNext()) {
66              LoggingEvent event = (LoggingEvent)i.next();
67              String[] throwd = event.getThrowableStrRep();
68              
69              switch (method) {
70              		case LOCATION:
71              		    LocationInfo info = event.getLocationInformation();
72              		    buffer.append(info.getClassName()+info.getMethodName()+event.getLevel().toString()); 
73              		    
74              		    if (throwd!=null && throwd.length>1)
75              		        for (int x=1; x<throwd.length; x++)
76              		            buffer.append(throwd[x]);            		    
77              		    break;
78              		case CONTENT:
79              		    buffer.append(event.getMessage()); 
80              		    break;            	
81              		case THROWABLE:
82              		    if (throwd!=null && throwd.length>1)
83              		        for (int x=1; x<throwd.length; x++)
84              		            buffer.append(throwd[x]);
85              		    else // Fall back on content if there is no throwable info
86              		        buffer.append(event.getMessage());
87              		    break;                    	
88  	        }
89          }
90          
91          return md5(buffer.toString());
92      }
93      
94      /***
95       * Returns the MD5 hash of a string
96       *
97       * @param plaintext The string to be encrypted
98       * @return the hash of the input string
99       */
100     private static String md5(String plaintext) {
101         return hash(plaintext,"MD5");
102     }
103 
104     /***
105      * Private function to turn md5 result to 32 hex-digit string
106      *
107      * @param hash byte array hash
108      * @return the string representation of that hash
109      */
110     private static String byteArrayToString(byte hash[]) {
111         StringBuffer buf = new StringBuffer(hash.length * 2);
112         int i;
113 
114         for (i = 0; i < hash.length; i++) {
115             if (((int) hash[i] & 0xff) < 0x10)
116                 buf.append("0");
117 
118             buf.append(Long.toString((int) hash[i] & 0xff, 16));
119         }
120 
121         return buf.toString().toUpperCase();
122     	}
123 
124     /***
125      * Converts a string into an array of bytes
126      *
127      * @param string The string to convert
128      * @return a string of bytes that represents the string
129      */
130     private static byte[] stringToByteArray(String string) {
131         return string.getBytes();
132     }
133 
134     /***
135      * Takes a string and returns its hash
136      *
137      * @param convert the input string, plaintext
138      * @param algorithm the algorithm to use to create the hash
139      * @return the string representation of the hash created by the input string
140      */
141     private static String hash(String convert, String algorithm) {
142         byte[] barray = stringToByteArray(convert);
143         String restring = "";
144         try {
145             MessageDigest md = MessageDigest.getInstance(algorithm);
146             md.update(barray);
147             byte[] result = md.digest();
148             restring = byteArrayToString(result);
149         }
150         catch (NoSuchAlgorithmException nsa) {
151             log.error("Can't find algorithm for "+algorithm+" hash.");
152         }
153 
154         return restring;
155     }
156 
157 }