org.springframework.aop.aspectj.ProceedTests.java Source code

Java tutorial

Introduction

Here is the source code for org.springframework.aop.aspectj.ProceedTests.java

Source

/*
 * Copyright 2002-2012 the original author or authors.
 *
 * 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 org.springframework.aop.aspectj;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.junit.Before;
import org.junit.Test;

import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.Ordered;

import static org.junit.Assert.*;

/**
 * Test for SPR-3522. Arguments changed on a call to proceed should be
 * visible to advice further down the invocation chain.
 *
 * @author Adrian Colyer
 * @author Chris Beams
 */
public final class ProceedTests {

    private SimpleBean testBean;

    private ProceedTestingAspect firstTestAspect;

    private ProceedTestingAspect secondTestAspect;

    @Before
    public void setUp() {
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(getClass().getSimpleName() + ".xml",
                getClass());
        testBean = (SimpleBean) ctx.getBean("testBean");
        firstTestAspect = (ProceedTestingAspect) ctx.getBean("firstTestAspect");
        secondTestAspect = (ProceedTestingAspect) ctx.getBean("secondTestAspect");
    }

    @Test
    public void testSimpleProceedWithChangedArgs() {
        this.testBean.setName("abc");
        assertEquals("Name changed in around advice", "ABC", this.testBean.getName());
    }

    @Test
    public void testGetArgsIsDefensive() {
        this.testBean.setAge(5);
        assertEquals("getArgs is defensive", 5, this.testBean.getAge());
    }

    @Test
    public void testProceedWithArgsInSameAspect() {
        this.testBean.setMyFloat(1.0F);
        assertTrue("value changed in around advice", this.testBean.getMyFloat() > 1.9F);
        assertTrue("changed value visible to next advice in chain",
                this.firstTestAspect.getLastBeforeFloatValue() > 1.9F);
    }

    @Test
    public void testProceedWithArgsAcrossAspects() {
        this.testBean.setSex("male");
        assertEquals("value changed in around advice", "MALE", this.testBean.getSex());
        assertEquals("changed value visible to next before advice in chain", "MALE",
                this.secondTestAspect.getLastBeforeStringValue());
        assertEquals("changed value visible to next around advice in chain", "MALE",
                this.secondTestAspect.getLastAroundStringValue());
    }

}

interface SimpleBean {

    void setName(String name);

    String getName();

    void setAge(int age);

    int getAge();

    void setMyFloat(float f);

    float getMyFloat();

    void setSex(String sex);

    String getSex();
}

class SimpleBeanImpl implements SimpleBean {

    private int age;
    private float aFloat;
    private String name;
    private String sex;

    @Override
    public int getAge() {
        return age;
    }

    @Override
    public float getMyFloat() {
        return aFloat;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public String getSex() {
        return sex;
    }

    @Override
    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public void setMyFloat(float f) {
        this.aFloat = f;
    }

    @Override
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void setSex(String sex) {
        this.sex = sex;
    }
}

class ProceedTestingAspect implements Ordered {

    private String lastBeforeStringValue;
    private String lastAroundStringValue;
    private float lastBeforeFloatValue;
    private int order;

    public void setOrder(int order) {
        this.order = order;
    }

    @Override
    public int getOrder() {
        return this.order;
    }

    public Object capitalize(ProceedingJoinPoint pjp, String value) throws Throwable {
        return pjp.proceed(new Object[] { value.toUpperCase() });
    }

    public Object doubleOrQuits(ProceedingJoinPoint pjp) throws Throwable {
        int value = ((Integer) pjp.getArgs()[0]).intValue();
        pjp.getArgs()[0] = new Integer(value * 2);
        return pjp.proceed();
    }

    public Object addOne(ProceedingJoinPoint pjp, Float value) throws Throwable {
        float fv = value.floatValue();
        return pjp.proceed(new Object[] { new Float(fv + 1.0F) });
    }

    public void captureStringArgument(JoinPoint tjp, String arg) {
        if (!tjp.getArgs()[0].equals(arg)) {
            throw new IllegalStateException(
                    "argument is '" + arg + "', " + "but args array has '" + tjp.getArgs()[0] + "'");
        }
        this.lastBeforeStringValue = arg;
    }

    public Object captureStringArgumentInAround(ProceedingJoinPoint pjp, String arg) throws Throwable {
        if (!pjp.getArgs()[0].equals(arg)) {
            throw new IllegalStateException(
                    "argument is '" + arg + "', " + "but args array has '" + pjp.getArgs()[0] + "'");
        }
        this.lastAroundStringValue = arg;
        return pjp.proceed();
    }

    public void captureFloatArgument(JoinPoint tjp, float arg) {
        float tjpArg = ((Float) tjp.getArgs()[0]).floatValue();
        if (Math.abs(tjpArg - arg) > 0.000001) {
            throw new IllegalStateException("argument is '" + arg + "', " + "but args array has '" + tjpArg + "'");
        }
        this.lastBeforeFloatValue = arg;
    }

    public String getLastBeforeStringValue() {
        return this.lastBeforeStringValue;
    }

    public String getLastAroundStringValue() {
        return this.lastAroundStringValue;
    }

    public float getLastBeforeFloatValue() {
        return this.lastBeforeFloatValue;
    }
}