Source to accompany blog post, http://octodecillion.com/blog/properties-dupe-detect-javassist/
package com.octodecillion.util; | |
import java.io.IOException; | |
import java.io.Reader; | |
import java.lang.reflect.InvocationTargetException; | |
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 javassist.util.proxy.MethodFilter; | |
import javassist.util.proxy.MethodHandler; | |
import javassist.util.proxy.ProxyFactory; | |
/** | |
* Detect duplicate properties when loading Properties from stream. | |
* <p> | |
* This version uses <a href="https://jboss-javassist.github.io/javassist/">Javassist</a> Dynamic Proxy support. | |
* | |
* @author jbetancourt | |
* @since Nov 18, 2015 | |
*/ | |
public class DuplicatePropertyDetectorWithJavassist { | |
/** | |
* 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"; | |
try { | |
ProxyFactory factory = new ProxyFactory(); | |
factory.setSuperclass(Properties.class); | |
factory.setFilter(new MethodFilter() { | |
@Override | |
public boolean isHandled(Method m) { | |
return m.getName().equals(put_method_name); | |
} | |
}); | |
((Properties) factory.create(new Class<?>[0], new Object[0], | |
new MethodHandler() { | |
@Override | |
public Object invoke(Object self, Method thisMethod, | |
Method proceed, Object[] args) throws Throwable { | |
String key = (String) args[0],value = (String) args[1]; | |
if (((Properties) self).containsKey(key)) { | |
List<String> list = new ArrayList<>(); | |
if (dupeResults.containsKey(key)) { | |
list = dupeResults.get(key); | |
} else { | |
dupeResults.put(key, list); | |
} | |
list.add(value); | |
} | |
return proceed.invoke(self, args); | |
} | |
})).load(reader); | |
} catch (NoSuchMethodException | IllegalArgumentException | |
| InstantiationException | IllegalAccessException | |
| InvocationTargetException e) { | |
throw new RuntimeException(e); | |
} | |
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; | |
/** | |
* Test {@link DuplicatePropertyDetectorWithJavassist}. | |
* <p> | |
* | |
* @author Josef Betancourt (A17878) | |
* @since Nov 18, 2015 | |
* | |
*/ | |
public class DuplicatePropertyDetectorWithJavassistTest { | |
private static final String DATA1_PROPERTIES = "/Data1.properties"; | |
/** | |
* @throws IOException | |
* @throws Exception | |
*/ | |
@Test | |
public void testLoadFile() throws IOException, Exception { | |
InputStream is = this.getClass().getResourceAsStream(DATA1_PROPERTIES); | |
Assert.assertNotNull(is); | |
DuplicatePropertyDetectorWithJavassist detector = new DuplicatePropertyDetectorWithJavassist(); | |
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