001/* 002 * Copyright 2002-2016 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.test.web.servlet.htmlunit; 018 019import java.io.IOException; 020import java.util.Arrays; 021import java.util.List; 022 023import com.gargoylesoftware.htmlunit.WebConnection; 024import com.gargoylesoftware.htmlunit.WebRequest; 025import com.gargoylesoftware.htmlunit.WebResponse; 026 027import org.springframework.util.Assert; 028 029/** 030 * Implementation of {@link WebConnection} that allows delegating to various 031 * {@code WebConnection} implementations. 032 * 033 * <p>For example, if you host your JavaScript on the domain {@code code.jquery.com}, 034 * you might want to use the following. 035 * 036 * <pre class="code"> 037 * WebClient webClient = new WebClient(); 038 * 039 * MockMvc mockMvc = ... 040 * MockMvcWebConnection mockConnection = new MockMvcWebConnection(mockMvc, webClient); 041 * 042 * WebRequestMatcher cdnMatcher = new UrlRegexRequestMatcher(".*?//code.jquery.com/.*"); 043 * WebConnection httpConnection = new HttpWebConnection(webClient); 044 * WebConnection webConnection = new DelegatingWebConnection(mockConnection, new DelegateWebConnection(cdnMatcher, httpConnection)); 045 * 046 * webClient.setWebConnection(webConnection); 047 * 048 * WebClient webClient = new WebClient(); 049 * webClient.setWebConnection(webConnection); 050 * </pre> 051 * 052 * @author Rob Winch 053 * @author Sam Brannen 054 * @since 4.2 055 */ 056public final class DelegatingWebConnection implements WebConnection { 057 058 private final List<DelegateWebConnection> connections; 059 060 private final WebConnection defaultConnection; 061 062 063 public DelegatingWebConnection(WebConnection defaultConnection, List<DelegateWebConnection> connections) { 064 Assert.notNull(defaultConnection, "Default WebConnection must not be null"); 065 Assert.notEmpty(connections, "Connections List must not be empty"); 066 this.connections = connections; 067 this.defaultConnection = defaultConnection; 068 } 069 070 public DelegatingWebConnection(WebConnection defaultConnection, DelegateWebConnection... connections) { 071 this(defaultConnection, Arrays.asList(connections)); 072 } 073 074 075 @Override 076 public WebResponse getResponse(WebRequest request) throws IOException { 077 for (DelegateWebConnection connection : this.connections) { 078 if (connection.getMatcher().matches(request)) { 079 return connection.getDelegate().getResponse(request); 080 } 081 } 082 return this.defaultConnection.getResponse(request); 083 } 084 085 @Override 086 public void close() { 087 } 088 089 090 public static final class DelegateWebConnection { 091 092 private final WebRequestMatcher matcher; 093 094 private final WebConnection delegate; 095 096 public DelegateWebConnection(WebRequestMatcher matcher, WebConnection delegate) { 097 this.matcher = matcher; 098 this.delegate = delegate; 099 } 100 101 private WebRequestMatcher getMatcher() { 102 return this.matcher; 103 } 104 105 private WebConnection getDelegate() { 106 return this.delegate; 107 } 108 } 109 110}