/*
* Copyright (c) 2002-2012 Alibaba Group Holding Limited.
* All rights reserved.
*
* 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.alibaba.citrus.service.uribroker.uri;
import static com.alibaba.citrus.generictype.TypeInfoUtil.*;
import static com.alibaba.citrus.test.TestUtil.*;
import static com.alibaba.citrus.util.CollectionUtil.*;
import static org.easymock.EasyMock.*;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import java.util.List;
import java.util.Locale;
import javax.servlet.http.HttpServletRequest;
import com.alibaba.citrus.service.uribroker.interceptor.URIBrokerInterceptor;
import com.alibaba.citrus.springext.util.ProxyTargetFactory;
import com.alibaba.citrus.util.i18n.LocaleUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public abstract class AbstractURIBrokerFeaturesTests<B extends URIBroker> {
protected final Class<?> brokerClass = resolveParameter(getClass(), AbstractURIBrokerFeaturesTests.class, 0)
.getRawType();
protected HttpServletRequest request;
protected B broker;
protected URIBrokerInterceptor i1;
protected URIBrokerInterceptor i2;
protected URIBrokerInterceptor i3;
@Before
public void init() {
this.request = getMockRequest();
this.broker = newInstance();
this.i1 = createMock(URIBrokerInterceptor.class);
this.i2 = createMock(URIBrokerInterceptor.class);
this.i3 = createMock(URIBrokerInterceptor.class);
// init locale
LocaleUtil.setContext(Locale.CHINA, "UTF-8");
}
@After
public void resetLocale() {
LocaleUtil.resetContext();
}
protected void setupParentBroker(B parent) {
parent.setCharset("GBK");
parent.addInterceptor(i1);
parent.addInterceptor(i2);
}
protected void assertParentBroker(B broker) {
assertEquals("GBK", broker.getCharset());
assertEquals(2, broker.getInterceptors().size());
assertArrayEquals(new Object[] { i1, i2 }, broker.getInterceptors().toArray(new Object[2]));
}
protected void setupBroker(B broker) {
broker.setCharset("UTF-8");
broker.addInterceptor(i3);
}
protected void assertBroker(B broker) {
assertEquals("UTF-8", broker.getCharset());
assertEquals(3, broker.getInterceptors().size());
assertArrayEquals(new Object[] { i1, i2, i3 }, broker.getInterceptors().toArray(new Object[3]));
}
@Test
public void getRequest() {
assertNull(getFieldValue(broker, "request", HttpServletRequest.class));
broker.setRequest(request);
assertSame(request, getFieldValue(broker, "request", HttpServletRequest.class));
}
@Test
public void getRequestAware() {
assertEquals(false, broker.isRequestAware()); // not request aware by default
broker.setRequestAware(true);
assertEquals(true, broker.isRequestAware());
broker.setRequestAware(false);
assertEquals(false, broker.isRequestAware());
}
@Test
public void getParent() throws Exception {
URIBroker b0 = new GenericURIBroker();
URIBroker1 b1 = new URIBroker1();
URIBroker2 b2 = new URIBroker2();
// default is no parent
assertNull(b0.getParent());
// not a superclass - 也许可,但只有共同的父类部分数据被继承
b2.setParent(b1);
assertSame(b1, b2.getParent());
// same class
b2.setParent(new URIBroker2());
assertThat(b2.getParent(), instanceOf(URIBroker2.class));
// superclass
b2.setParent(b0);
assertSame(b0, b2.getParent());
// re-set parent
b2.setParent(b0);
assertSame(b0, b2.getParent());
// after init
assertNull(b1.getParent());
b1.init();
try {
b1.setParent(b0);
fail();
} catch (IllegalStateException e) {
assertThat(e, exception("already initialized"));
}
assertNotNull(b2.getParent());
b2.init();
try {
b2.setParent(b0);
fail();
} catch (IllegalStateException e) {
assertThat(e, exception("already initialized"));
}
}
@Test
public void getCharset() {
// default is null
assertEquals(null, broker.getCharset());
// set empty
broker.setCharset(null);
assertEquals(null, broker.getCharset());
broker.setCharset(" ");
assertEquals(null, broker.getCharset());
// set value
broker.setCharset(" GBK ");
assertEquals("GBK", broker.getCharset());
}
@Test
public void isAutoReset() {
// default is false
assertEquals(false, broker.isAutoReset());
// fork(true)
URIBroker b = broker.fork(true);
assertEquals(true, b.isAutoReset());
// fork(false)
b = broker.fork(false);
assertEquals(false, b.isAutoReset());
}
@Test
public void getInterceptors() {
// no interceptors by default
assertFalse(broker.hasInterceptors());
assertNull(getFieldValue(broker, "interceptors", null));
assertTrue(broker.getInterceptors().isEmpty()); // auto create
assertFalse(broker.hasInterceptors());
// add null
try {
broker.addInterceptor(null);
fail();
} catch (IllegalArgumentException e) {
assertThat(e, exception("interceptor"));
}
// add
URIBrokerInterceptor i1 = createMock(URIBrokerInterceptor.class);
URIBrokerInterceptor i2 = createMock(URIBrokerInterceptor.class);
broker.addInterceptor(i1);
broker.addInterceptor(i2);
assertTrue(broker.hasInterceptors());
assertEquals(2, broker.getInterceptors().size());
assertArrayEquals(new Object[] { i1, i2 }, broker.getInterceptors().toArray(new Object[2]));
// set
broker.setInterceptors(createInterceptorList(i2, i1));
assertTrue(broker.hasInterceptors());
assertEquals(2, broker.getInterceptors().size());
assertArrayEquals(new Object[] { i2, i1 }, broker.getInterceptors().toArray(new Object[2]));
// clear
broker.clearInterceptors();
assertFalse(broker.hasInterceptors());
assertTrue(broker.getInterceptors().isEmpty());
}
/** init broker,broker的内容为空。 */
@Test
public final void init_broker_nonOverride() {
B parent = newInstance();
setupParentBroker(parent);
broker.setParent(parent);
broker.init();
assertEquals(true, getFieldValue(broker, "initialized", null));
assertParentBroker(broker);
}
/** init broker,broker有内容。 */
@Test
public final void init_broker_override() {
B parent = newInstance();
setupParentBroker(parent);
setupBroker(broker);
broker.setParent(parent);
broker.init();
assertEquals(true, getFieldValue(broker, "initialized", null));
assertBroker(broker);
}
@Test
public final void reset_noParent() {
setupBroker(broker);
broker.init();
broker.reset();
assertAfterReset_noParent(broker);
}
@Test
public final void reset_withParent() {
B parent = newInstance();
setupParentBroker(parent);
setupBroker(broker);
broker.setParent(parent);
broker.init();
assertBroker(broker);
broker.reset();
assertParentBroker(broker); // 等同于parent
}
protected void assertAfterReset_noParent(B broker) {
assertNull(broker.getCharset());
assertFalse(broker.hasInterceptors());
}
@Test
public void newInstanceInternal() {
URIBroker3 broker = new URIBroker3();
String className = URIBroker3.class.getName();
// null
try {
broker.newInstanceInternal();
fail();
} catch (IllegalArgumentException e) {
assertThat(e, exception(className + ".newInstance() returns null"));
}
// same object
broker.instance = broker;
try {
broker.newInstanceInternal();
fail();
} catch (IllegalArgumentException e) {
assertThat(e, exception(className + ".newInstance() returns itself"));
}
// wrong type
broker.instance = new GenericURIBroker();
try {
broker.newInstanceInternal();
fail();
} catch (IllegalArgumentException e) {
assertThat(e,
exception(className + ".newInstance() returns wrong type: " + GenericURIBroker.class.getName()));
}
// right type
broker.instance = new URIBroker3();
assertSame(broker.instance, broker.newInstanceInternal());
}
@Test
@SuppressWarnings("unchecked")
public void fork() {
// parent, autoReset == false
B parent = newInstance();
parent.setRequestAware(false);
parent.setRequest(request);
setupParentBroker(parent);
assertFalse(parent.isAutoReset());
assertParentBroker(parent);
// broker, autoReset == true
broker = (B) parent.fork();
assertFalse(broker.isRequestAware()); // request和requestAware被复制
assertSame(request, getFieldValue(broker, "request", HttpServletRequest.class));
assertTrue(broker.isAutoReset());
assertSame(parent, broker.getParent()); // 因为parent.autoReset为false,所以可作为fork结果的parent
assertParentBroker(broker); // 此时broker和parent是内容相同的
setupBroker(broker);
assertBroker(broker); // 此时broker内容被添加
// newBroker = broker.fork(), autoReset == true
// 将在内部fork一个新的autoReset为false的parent
B newBroker = (B) broker.fork();
assertFalse(newBroker.isRequestAware()); // request和requestAware被复制
assertSame(request, getFieldValue(newBroker, "request", HttpServletRequest.class));
assertTrue(newBroker.isAutoReset());
assertNotSame(broker, newBroker.getParent()); // 因为broker.autoReset为true,所以必须fork以后才能作为新broker的parent
assertParentBroker(broker); // fork以后,broker被reset,如同render一样
assertBroker((B) newBroker.getParent()); // newBroker的直接parent的值,等同于reset之前的broker
assertFalse(newBroker.getParent().isAutoReset()); // newBroker的直接parent的autoReset==false
}
@Test
@SuppressWarnings("unchecked")
public void processInterceptors() {
replay(i1, i2, i3);
B parent = newInstance();
setupParentBroker(parent);
broker.setParent(parent);
setupBroker(broker);
broker.init();
assertFalse(broker.isAutoReset());
assertEquals(broker.render(), broker.render()); // 当autoreset=false时,render不会调用interceptors
verify(i1, i2, i3);
reset(i1, i2, i3);
// broker.reset以后,所有的interceptors将被重新调用
broker.reset();
setupBroker(broker);
broker = (B) broker.fork();
i1.perform(broker);
i2.perform(broker);
i3.perform(broker);
i1.perform(broker);
i2.perform(broker);
i3.perform(broker);
replay(i1, i2, i3);
assertTrue(broker.isAutoReset());
assertEquals(broker.render(), broker.render());
verify(i1, i2, i3);
}
@Test
@SuppressWarnings("unchecked")
public void toString_and_render() {
B parent = newInstance();
setupParentBroker(parent);
assertFalse(parent.isAutoReset());
broker = (B) parent.fork();
setupBroker(broker);
assertTrue(broker.isAutoReset());
// 对于autoReset=true的broker
assertBroker(broker);
broker.toString(); // toString不会reset
assertBroker(broker);
broker.render(); // render会reset
assertParentBroker(broker);
// 对于autoReset=false的broker
assertParentBroker(parent);
parent.toString(); // toString不会reset
assertParentBroker(parent);
parent.render(); // render也不会reset
assertParentBroker(parent);
}
protected final HttpServletRequest getMockRequest() {
RequestProxy request = createMock(RequestProxy.class);
expect(request.getObject()).andThrow(new IllegalStateException()).anyTimes();
expect(request.getScheme()).andThrow(new IllegalStateException()).anyTimes();
expect(request.getServerName()).andThrow(new IllegalStateException()).anyTimes();
expect(request.getServerPort()).andThrow(new IllegalStateException()).anyTimes();
expect(request.getContextPath()).andThrow(new IllegalStateException()).anyTimes();
expect(request.getServletPath()).andThrow(new IllegalStateException()).anyTimes();
replay(request);
return request;
}
protected final HttpServletRequest getMockRequest(String scheme, String serverName, int serverPort) {
return getMockRequest(scheme, serverName, serverPort, null, null, null);
}
protected final HttpServletRequest getMockRequest(String scheme, String serverName, int serverPort,
String contextPath, String servletPath, String pathInfo) {
HttpServletRequest request = getMockRequest_noReplay(scheme, serverName, serverPort, contextPath, servletPath,
pathInfo);
replay(request);
return request;
}
protected final HttpServletRequest getMockRequest_noReplay(String scheme, String serverName, int serverPort,
String contextPath, String servletPath, String pathInfo) {
HttpServletRequest request = createMock(HttpServletRequest.class);
expect(request.getScheme()).andReturn(scheme).anyTimes();
expect(request.getServerName()).andReturn(serverName).anyTimes();
expect(request.getServerPort()).andReturn(serverPort).anyTimes();
expect(request.getContextPath()).andReturn(contextPath).anyTimes();
expect(request.getServletPath()).andReturn(servletPath).anyTimes();
expect(request.getPathInfo()).andReturn(pathInfo).anyTimes();
return request;
}
@SuppressWarnings("unchecked")
protected final B newInstance() {
try {
return (B) brokerClass.newInstance();
} catch (Exception e) {
fail(e.toString());
return null;
}
}
public static interface RequestProxy extends HttpServletRequest, ProxyTargetFactory {
}
public static class URIBroker1 extends GenericURIBroker {
}
public static class URIBroker2 extends GenericURIBroker {
}
public static class URIBroker3 extends GenericURIBroker {
private URIBroker instance;
@Override
protected URIBroker newInstance() {
return instance;
}
}
protected final List<String> createStringList(String... strs) {
return createArrayList(strs);
}
protected final List<URIBrokerInterceptor> createInterceptorList(URIBrokerInterceptor... interceptors) {
return createArrayList(interceptors);
}
}