Package com.proofpoint.reporting.testing

Source Code of com.proofpoint.reporting.testing.TestingReportCollectionFactory$TestingInvocationHandler

/*
* Copyright 2014 Proofpoint, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.proofpoint.reporting.testing;

import com.google.common.base.Optional;
import com.google.common.base.Supplier;
import com.google.common.base.Ticker;
import com.google.common.collect.ClassToInstanceMap;
import com.google.common.collect.MutableClassToInstanceMap;
import com.proofpoint.reporting.ReportCollectionFactory;
import com.proofpoint.reporting.ReportExporter;

import javax.annotation.Nullable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import static com.google.common.base.Optional.fromNullable;
import static com.google.common.base.Preconditions.checkNotNull;
import static java.lang.reflect.Proxy.newProxyInstance;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;

public class TestingReportCollectionFactory
    extends ReportCollectionFactory
{
    private final NamedInstanceMap argumentVerifierMap = new NamedInstanceMap();
    private final NamedInstanceMap superMap = new NamedInstanceMap();

    public TestingReportCollectionFactory()
    {
        super(mock(ReportExporter.class), new Ticker()
        {
            @Override
            public long read()
            {
                return 0;
            }
        });
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T> T createReportCollection(Class<T> aClass)
    {
        checkNotNull(aClass, "class is null");

        T argumentVerifier = mock(aClass);
        argumentVerifierMap.put(null, aClass, argumentVerifier);

        T superCollection = super.createReportCollection(aClass);
        superMap.put(null, aClass, superCollection);

        return (T) newProxyInstance(
                aClass.getClassLoader(),
                new Class[]{aClass},
                new TestingInvocationHandler(argumentVerifier, superCollection));
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T> T createReportCollection(Class<T> aClass, String name)
    {
        checkNotNull(aClass, "class is null");
        checkNotNull(name, "name is null");

        T argumentVerifier = mock(aClass);
        argumentVerifierMap.put(name, aClass, argumentVerifier);

        T superCollection = super.createReportCollection(aClass);
        superMap.put(name, aClass, superCollection);

        return (T) newProxyInstance(
                aClass.getClassLoader(),
                new Class[]{aClass},
                new TestingInvocationHandler(argumentVerifier, superCollection));
    }

    public <T> T getArgumentVerifier(Class<T> aClass)
    {
        return argumentVerifierMap.get(null, aClass);
    }

    public <T> T getArgumentVerifier(Class<T> aClass, String name)
    {
        checkNotNull(name, "name is null");
        return argumentVerifierMap.get(name, aClass);
    }

    public <T> T getReportCollection(Class<T> aClass)
    {
        return superMap.get(null, aClass);
    }

    public <T> T getReportCollection(Class<T> aClass, String name)
    {
        checkNotNull(name, "name is null");
        return superMap.get(name, aClass);
    }

    @Override
    protected Supplier<Object> getReturnValueSupplier(Method method)
    {
        final Supplier<Object> superSupplier = super.getReturnValueSupplier(method);
        return new Supplier<Object>()
        {
            @Override
            public Object get()
            {
                return spy(superSupplier.get());
            }
        };
    }

    private static class TestingInvocationHandler<T>
            implements InvocationHandler
    {
        private final T argumentVerifier;
        private final T superCollection;

        public TestingInvocationHandler(T argumentVerifier, T superCollection)
        {
            this.argumentVerifier = argumentVerifier;
            this.superCollection = superCollection;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable
        {
            method.invoke(argumentVerifier, args);
            return method.invoke(superCollection, args);
        }
    }

    private static class NamedInstanceMap
    {
        private Map<Optional<String>, ClassToInstanceMap<Object>> nameMap = new HashMap<>();

        public synchronized <T> void put(@Nullable String name, Class<T> aClass, T value)
        {
            ClassToInstanceMap<Object> instanceMap = nameMap.get(fromNullable(name));
            if (instanceMap == null) {
                instanceMap = MutableClassToInstanceMap.create();
                nameMap.put(fromNullable(name), instanceMap);
            }
            if (instanceMap.putInstance(aClass, value) != null) {
                String message = "Duplicate ReportCollection for " + aClass.toString();
                if (name != null) {
                    message += " named " + name;
                }
                throw new Error(message);
            }
        }

        @SuppressWarnings("unchecked")
        public synchronized <T> T get(@Nullable String name, Class<T> aClass)
        {
            ClassToInstanceMap<Object> instanceMap = nameMap.get(fromNullable(name));
            if (instanceMap == null) {
                return null;
            }
            return (T) instanceMap.get(aClass);
        }
    }
}
TOP

Related Classes of com.proofpoint.reporting.testing.TestingReportCollectionFactory$TestingInvocationHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.