Java Properties dupe key detect using CGLIB

In a prior post I used Javassist for Dynamic Proxying of Properties class’s load method. This allowed detection of duplicate keys in a Properties file.

In this post I use the Class Generation Library (CGLIB).

Listing 1, Source available at Gist

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())) {
                    System.out.println("Putting: " + args[0]);
                    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;
    }
}

Links

Similar Posts:

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

Leave a Reply

Your email address will not be published. Required fields are marked *