001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.proxy2.serialization;
018
019import static org.junit.Assert.assertEquals;
020import static org.junit.Assert.assertTrue;
021
022import java.io.Serializable;
023
024import org.apache.commons.lang3.SerializationException;
025import org.apache.commons.lang3.SerializationUtils;
026import org.apache.commons.proxy2.ProxyFactory;
027import org.apache.commons.proxy2.interceptor.InterceptorUtils;
028import org.apache.commons.proxy2.interceptor.SwitchInterceptor;
029import org.apache.commons.proxy2.interceptor.matcher.invocation.DeclaredByMatcher;
030import org.apache.commons.proxy2.AbstractProxyFactoryAgnosticTest;
031import org.junit.After;
032import org.junit.Before;
033import org.junit.Test;
034
035public class SerializationProxyTest extends AbstractProxyFactoryAgnosticTest
036{
037    public static class NonSerializableStringWrapper
038    {
039        private final String value;
040
041        NonSerializableStringWrapper(String value)
042        {
043            this.value = value;
044        }
045
046        public String getValue()
047        {
048            return value;
049        }
050    }
051
052    public interface Provider
053    {
054        NonSerializableStringWrapper getObject();
055    }
056
057    private static final ThreadLocal<ProxyFactory> PROXY_FACTORY = new ThreadLocal<ProxyFactory>();
058
059    private static SwitchInterceptor implementProvider(String value)
060    {
061        return new SwitchInterceptor().when(new DeclaredByMatcher(Provider.class)).then(
062                InterceptorUtils.constant(new NonSerializableStringWrapper(value)));
063    }
064
065    private static Provider serializableProvider(final String value)
066    {
067        return PROXY_FACTORY.get().createInterceptorProxy(
068                null,
069                implementProvider(value).when(new DeclaredByMatcher(WriteReplace.class)).then(
070                        InterceptorUtils.constant(new ReadResolve()
071                        {
072                            private static final long serialVersionUID = 1L;
073
074                            @Override
075                            public Object readResolve()
076                            {
077                                return serializableProvider(value);
078                            }
079                        })), Provider.class, WriteReplace.class);
080    }
081
082    @Before
083    public void captureProxyFactory()
084    {
085        PROXY_FACTORY.set(proxyFactory);
086    }
087
088    @After
089    public void clearProxyFactory()
090    {
091        PROXY_FACTORY.remove();
092    }
093
094    @Test(expected = SerializationException.class)
095    public void testNaive()
096    {
097        final Provider proxy = proxyFactory.createInterceptorProxy(null, implementProvider("foo"), Provider.class,
098                Serializable.class);
099        assertEquals("foo", proxy.getObject().getValue());
100        assertTrue(Serializable.class.isInstance(proxy));
101        SerializationUtils.roundtrip((Serializable) proxy);
102    }
103
104    @Test
105    public void testSerializationProxy()
106    {
107        final Provider proxy = serializableProvider("foo");
108        assertEquals("foo", proxy.getObject().getValue());
109        assertTrue(Serializable.class.isInstance(proxy));
110        final Provider proxy2 = (Provider) SerializationUtils.roundtrip((Serializable) proxy);
111        assertEquals("foo", proxy2.getObject().getValue());
112    }
113}