Last active
November 20, 2015 01:21
-
-
Save josefbetancourt/9116f8a684b91bedcd60 to your computer and use it in GitHub Desktop.
Source to accompany blog post, http://octodecillion.com/blog/properties-dupe-detect-javassist/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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