Source to accompany blog post, http://octodecillion.com/blog/java-properties-dupe-key-detect-using-cglib/
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