001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.test;
016    
017    import org.junit.internal.runners.statements.ExpectException;
018    import org.junit.internal.runners.statements.FailOnTimeout;
019    import org.junit.internal.runners.statements.InvokeMethod;
020    import org.junit.internal.runners.statements.RunAfters;
021    import org.junit.internal.runners.statements.RunBefores;
022    import org.junit.rules.TestRule;
023    import org.junit.runner.Description;
024    import org.junit.runners.model.Statement;
025    
026    /**
027     * @author Shuyang Zhou
028     */
029    public class BaseTestRule<C, M> implements TestRule {
030    
031            @Override
032            public final Statement apply(
033                    Statement statement, final Description description) {
034    
035                    return new StatementWrapper(statement) {
036    
037                            @Override
038                            public void evaluate() throws Throwable {
039                                    String methodName = description.getMethodName();
040    
041                                    C c = null;
042                                    M m = null;
043    
044                                    if (methodName == null) {
045                                            c = beforeClass(description);
046                                    }
047                                    else {
048                                            setInstance(inspectTarget(statement));
049    
050                                            m = beforeMethod(description);
051                                    }
052    
053                                    try {
054                                            invokeStatement(statement, description);
055                                    }
056                                    finally {
057                                            if (methodName == null) {
058                                                    afterClass(description, c);
059                                            }
060                                            else {
061                                                    afterMethod(description, m);
062                                            }
063                                    }
064                            }
065    
066                    };
067            }
068    
069            public static abstract class StatementWrapper extends Statement {
070    
071                    public StatementWrapper(Statement statement) {
072                            this.statement = statement;
073                    }
074    
075                    public Statement getStatement() {
076                            return statement;
077                    }
078    
079                    protected final Statement statement;
080    
081            }
082    
083            protected void afterClass(Description description, C c) throws Throwable {
084            }
085    
086            protected void afterMethod(Description description, M m) throws Throwable {
087            }
088    
089            protected C beforeClass(Description description) throws Throwable {
090                    return null;
091            }
092    
093            protected M beforeMethod(Description description) throws Throwable {
094                    return null;
095            }
096    
097            protected Object inspectTarget(Statement statement) {
098                    while (statement instanceof StatementWrapper) {
099                            StatementWrapper statementWrapper = (StatementWrapper)statement;
100    
101                            statement = statementWrapper.getStatement();
102                    }
103    
104                    if ((statement instanceof InvokeMethod) ||
105                            (statement instanceof RunAfters) ||
106                            (statement instanceof RunBefores)) {
107    
108                            return ReflectionTestUtil.getFieldValue(statement, "target");
109                    }
110                    else if (statement instanceof ExpectException) {
111                            return inspectTarget(
112                                    ReflectionTestUtil.<Statement>getFieldValue(statement, "next"));
113                    }
114                    else if (statement instanceof FailOnTimeout) {
115                            return inspectTarget(
116                                    ReflectionTestUtil.<Statement>getFieldValue(
117                                            statement, "originalStatement"));
118                    }
119    
120                    throw new IllegalStateException("Unknow statement " + statement);
121            }
122    
123            protected void invokeStatement(Statement statement, Description description)
124                    throws Throwable {
125    
126                    statement.evaluate();
127            }
128    
129            protected void setInstance(Object instance) {
130            }
131    
132    }