Create a gist now

Instantly share code, notes, and snippets.

package com.octodecillion.util;
import java.io.IOException;
import java.io.Reader;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/**
* Detect duplicate properties when loading Properties from stream.
* <p>
* This version uses <a href="https://github.com/cglib/cglib/wiki">CGLIB</a> Dynamic Proxy support.
*
* @author jbetancourt
* @since Nov 18, 2015
*/
public class DuplicatePropertyDetectorWithCGLIB {
/**
* Detect duplicate keys in Properties resource.
* <p>
* @see Properties#load(Reader)
*
* @param reader The reader is <b>NOT</b> closed.
* @return Map Map where map key is duplicated key and list is values of those keys
* @throws IOException reading the stream
* @throws RuntimeException for any issue with proxying
*/
public Map<String, List<String>> load(Reader reader) throws IOException {
if(reader==null){ throw new NullPointerException("reader cannot be null");}
final Map<String, List<String>> dupeResults = new HashMap<>();
final String put_method_name = "put";
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Properties.class);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object object, Method method,
Object[] args, MethodProxy proxy) throws Throwable {
if(method.getDeclaringClass() != Object.class && isPut(method.getName())) {
String key = (String) args[0],value = (String) args[1];
if (((Properties) object).containsKey(key)) {
List<String> list = new ArrayList<>();
if (dupeResults.containsKey(key)) {
list = dupeResults.get(key);
} else {
dupeResults.put(key, list);
}
list.add(value);
}
}
return proxy.invokeSuper(object, args);
}
private boolean isPut(String name) {
return name.equals(put_method_name);
}
});
Properties props = (Properties) enhancer.create();
props.load(reader);
return dupeResults;
}
}
package com.octodecillion.util;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Map;
import org.junit.Assert;
import org.junit.Test;
/**
* @author jbetancourt
*
*/
public class DuplicatePropertyDetectorWithCGLIBTest {
private static final String DATA1_PROPERTIES = "/Data1.properties";
/**
* @throws IOException
*
*/
@Test
public void testLoad() throws IOException {
InputStream is = this.getClass().getResourceAsStream(DATA1_PROPERTIES);
Assert.assertNotNull(is);
DuplicatePropertyDetectorWithCGLIB detector = new DuplicatePropertyDetectorWithCGLIB();
Map<String, List<String>> map = detector.load(new InputStreamReader(is));
Assert.assertEquals(1, map.size());
Assert.assertTrue(map.containsKey("three"));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment