View Javadoc

1   package org.kuali.spring.util;
2   
3   import java.util.ArrayList;
4   import java.util.Collections;
5   import java.util.List;
6   import java.util.Properties;
7   import java.util.regex.Matcher;
8   import java.util.regex.Pattern;
9   
10  import org.slf4j.Logger;
11  import org.slf4j.LoggerFactory;
12  
13  public class PropertyLogger {
14  	final Logger logger = LoggerFactory.getLogger(PropertyLogger.class);
15  
16  	// Matches any string containing "password" (case insensitive)
17  	public static final String DEFAULT_MASK_EXPRESSION = ".*((?i)password).*";
18  	public static final String DEFAULT_MASKED_VALUE = "******";
19  	public static final boolean DEFAULT_IS_MASK_PROPERTY_VALUES = true;
20  	public static final boolean DEFAULT_IS_FLATTEN_PROPERTY_VALUES = false;
21  	public static final boolean DEFAULT_IS_TRIM_PROPERTY_VALUES = false;
22  	public static final boolean DEFAULT_IS_LOG_IN_SORTED_ORDER = true;
23  	// Space
24  	public static final String DEFAULT_REPLACEMENT_STRING = " ";
25  	// Carriage return
26  	public static final String CR = "\r";
27  	// Line feed
28  	public static final String LF = "\n";
29  
30  	// If true, log entries from a Properties object sorted by key
31  	boolean logInSortedOrder = DEFAULT_IS_LOG_IN_SORTED_ORDER;
32  	// If true, replace \n and \r when logging values
33  	boolean flattenPropertyValues = DEFAULT_IS_FLATTEN_PROPERTY_VALUES;
34  	// The value to replace linefeeds with
35  	String linefeedReplacement = DEFAULT_REPLACEMENT_STRING;
36  	// The value to replace carriage returns with
37  	String carriageReturnReplacement = DEFAULT_REPLACEMENT_STRING;
38  	// If true, call trim() on property values before logging them
39  	boolean trimPropertyValues = DEFAULT_IS_TRIM_PROPERTY_VALUES;
40  	// If true, mask values for keys that match any of the maskExpressions
41  	boolean maskPropertyValues = DEFAULT_IS_MASK_PROPERTY_VALUES;
42  	// Regular expressions to compare property keys against
43  	String[] maskExpressions;
44  	// The value to log in place of the actual value if we need to mask it
45  	String maskValue = DEFAULT_MASKED_VALUE;
46  	// Compiled representation of the regular expression
47  	Pattern[] patterns;
48  
49  	public PropertyLogger() {
50  		super();
51  		setMaskExpression(DEFAULT_MASK_EXPRESSION);
52  	}
53  
54  	/**
55  	 * This setter invokes setMaskExpressions() - plural
56  	 * 
57  	 * @param maskExpression
58  	 */
59  	public void setMaskExpression(String maskExpression) {
60  		setMaskExpressions(new String[] { maskExpression });
61  	}
62  
63  	/**
64  	 * This setter invokes Pattern.compile() for each maskExpression
65  	 * 
66  	 * @param maskExpressions
67  	 */
68  	public void setMaskExpressions(String[] maskExpressions) {
69  		this.maskExpressions = maskExpressions;
70  		this.patterns = new Pattern[maskExpressions.length];
71  		for (int i = 0; i < patterns.length; i++) {
72  			patterns[i] = Pattern.compile(maskExpressions[i]);
73  		}
74  	}
75  
76  	public String getLogEntry(String key, String value) {
77  		return key + "=" + getLogValue(key, value);
78  	}
79  
80  	protected boolean isEmpty(String s) {
81  		if (s == null) {
82  			return true;
83  		}
84  		if (s.trim().length() == 0) {
85  			return true;
86  		}
87  		return false;
88  	}
89  
90  	public String getLogEntry(Properties properties) {
91  		if (properties == null || properties.size() == 0) {
92  			return "No properties to log";
93  		}
94  		StringBuilder sb = new StringBuilder();
95  		List<String> keys = new ArrayList<String>(properties.stringPropertyNames());
96  		if (isLogInSortedOrder()) {
97  			Collections.sort(keys);
98  		}
99  		for (String key : keys) {
100 			String value = properties.getProperty(key);
101 			sb.append(getLogEntry(key, value) + "\n");
102 		}
103 		return sb.toString();
104 	}
105 
106 	protected boolean isMatch(Pattern[] patterns, String key) {
107 		for (Pattern pattern : patterns) {
108 			Matcher matcher = pattern.matcher(key);
109 			if (matcher.matches()) {
110 				return true;
111 			}
112 		}
113 		return false;
114 	}
115 
116 	public String getLogValue(String key, String value) {
117 		if (isFlattenPropertyValues()) {
118 			value = value.replace(LF, getLinefeedReplacement());
119 			value = value.replace(CR, getCarriageReturnReplacement());
120 		}
121 		if (isTrimPropertyValues()) {
122 			value = value.trim();
123 		}
124 		if (!isMaskPropertyValues()) {
125 			return value;
126 		}
127 		boolean match = isMatch(getPatterns(), key);
128 		if (match) {
129 			return getMaskValue();
130 		} else {
131 			return value;
132 		}
133 	}
134 
135 	public boolean isFlattenPropertyValues() {
136 		return flattenPropertyValues;
137 	}
138 
139 	public void setFlattenPropertyValues(boolean flattenPropertyValues) {
140 		this.flattenPropertyValues = flattenPropertyValues;
141 	}
142 
143 	public boolean isMaskPropertyValues() {
144 		return maskPropertyValues;
145 	}
146 
147 	public void setMaskPropertyValues(boolean maskPropertyValues) {
148 		this.maskPropertyValues = maskPropertyValues;
149 	}
150 
151 	public String getMaskValue() {
152 		return maskValue;
153 	}
154 
155 	public void setMaskValue(String maskValue) {
156 		this.maskValue = maskValue;
157 	}
158 
159 	public String getLinefeedReplacement() {
160 		return linefeedReplacement;
161 	}
162 
163 	public void setLinefeedReplacement(String linefeedReplacement) {
164 		this.linefeedReplacement = linefeedReplacement;
165 	}
166 
167 	public String getCarriageReturnReplacement() {
168 		return carriageReturnReplacement;
169 	}
170 
171 	public void setCarriageReturnReplacement(String carriageReturnReplacement) {
172 		this.carriageReturnReplacement = carriageReturnReplacement;
173 	}
174 
175 	public boolean isTrimPropertyValues() {
176 		return trimPropertyValues;
177 	}
178 
179 	public void setTrimPropertyValues(boolean trimPropertyValues) {
180 		this.trimPropertyValues = trimPropertyValues;
181 	}
182 
183 	public String[] getMaskExpressions() {
184 		return maskExpressions;
185 	}
186 
187 	public Pattern[] getPatterns() {
188 		return patterns;
189 	}
190 
191 	public boolean isLogInSortedOrder() {
192 		return logInSortedOrder;
193 	}
194 
195 	public void setLogInSortedOrder(boolean logInSortedOrder) {
196 		this.logInSortedOrder = logInSortedOrder;
197 	}
198 
199 }