/* * This is part of Geomajas, a GIS framework, http://www.geomajas.org/. * * Copyright 2008-2015 Geosparc nv, http://www.geosparc.com/, Belgium. * * The program is available in open source according to the GNU Affero * General Public License. All contributions in this program are covered * by the Geomajas Contributors License Agreement. For full licensing * details, see LICENSE.txt in the project root. */ package org.geomajas.gwt2.plugin.wfs.client.service; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.io.StringReader; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.ArrayList; import java.util.List; import org.apache.commons.io.IOUtils; import org.apache.xerces.parsers.DOMParser; import org.geomajas.gwt2.plugin.wfs.client.protocol.WfsGetCapabilitiesInfo; import org.geomajas.gwt2.plugin.wfs.client.service.WfsServiceImpl.RequestBuilderFactory; import org.geomajas.gwt2.plugin.wfs.client.service.WfsServiceImpl.UrlEncoder; import org.junit.Before; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.xml.sax.InputSource; import com.google.gwt.core.client.Callback; import com.google.gwt.http.client.Request; import com.google.gwt.http.client.RequestBuilder; import com.google.gwt.http.client.RequestCallback; import com.google.gwt.http.client.Response; import com.google.gwt.xml.client.Document; import com.google.gwt.xml.client.impl.XMLParserImpl; import com.google.gwtmockito.GwtMockitoTestRunner; @RunWith(GwtMockitoTestRunner.class) public abstract class AbstractWfsServiceTest { @Mock protected RequestBuilder requestBuilder; protected WfsServiceImpl wfsService; protected String capabilitiesXml; protected Document capabilitiesDoc; @Before public void init() throws Exception { wfsService = new WfsServiceImpl(); wfsService.setRequestBuilderFactory(new RequestBuilderFactory() { @Override public RequestBuilder create(RequestBuilder.Method method, String url) { return requestBuilder; } }); wfsService.setUrlEncoder(new UrlEncoder() { @Override public String encodeUrl(String url) { return url; } }); when(XMLParserImpl.getInstance().parse(anyString())).thenAnswer(new Answer<Document>() { @Override public Document answer(InvocationOnMock invocation) throws Throwable { return capabilitiesDoc; } }); } protected void prepareResponse(String resource) throws Exception { capabilitiesXml = IOUtils.toString(this.getClass().getResourceAsStream(resource), "UTF-8"); DOMParser parser = new DOMParser(); parser.parse(new InputSource(new StringReader(capabilitiesXml))); capabilitiesDoc = w3cToGoogle(parser.getDocument()); final Response response = mock(Response.class); when(response.getStatusCode()).thenReturn(200); when(response.getText()).thenReturn(capabilitiesXml); when(requestBuilder.sendRequest(anyString(), any(RequestCallback.class))).thenAnswer(new Answer<Request>() { @Override public Request answer(InvocationOnMock invocation) throws Throwable { ((RequestCallback) invocation.getArguments()[1]).onResponseReceived(null, response); return null; } }); } private Document w3cToGoogle(final org.w3c.dom.Document document) { return (Document) Proxy.newProxyInstance(getClass().getClassLoader(), new Class<?>[] { Document.class }, new W3CToGoogleHandler(document)); } /** * Recursive proxy to expose w3c dom classes as gwt dom classes. * * @author Jan De Moerloose * */ public class W3CToGoogleHandler implements InvocationHandler { private Object delegate; public W3CToGoogleHandler(Object delegate) { this.delegate = delegate; } @Override public Object invoke(Object target, Method method, Object[] args) throws Throwable { try { Method m = delegate.getClass().getMethod(method.getName(), method.getParameterTypes()); Object result = m.invoke(delegate, args == null ? null : new Object[] { args[0] }); // equals() should equal the other's delegate if (m.getName().equals("equals")) { if (Proxy.isProxyClass(args[0].getClass())) { W3CToGoogleHandler handler = (W3CToGoogleHandler) Proxy.getInvocationHandler(args[0]); return delegate.equals(handler.delegate); } } if (result == null) { return null; } // find the matching interfaces for the return type and create a new proxy for those interfaces Class<?>[] c = getClasses(result, m.getReturnType()); if (c.length > 0) { return Proxy.newProxyInstance(getClass().getClassLoader(), c, new W3CToGoogleHandler(result)); } else { return result; } } catch (Exception e) { e.printStackTrace(); throw e; } } private Class[] getClasses(Object result, Class type) { List<Class> matches = new ArrayList<Class>(); if (result instanceof org.w3c.dom.NamedNodeMap) { matches.add(com.google.gwt.xml.client.NamedNodeMap.class); } if (result instanceof org.w3c.dom.NodeList) { matches.add(com.google.gwt.xml.client.NodeList.class); } if (result instanceof org.w3c.dom.Document) { matches.add(com.google.gwt.xml.client.Document.class); } if (result instanceof org.w3c.dom.Element) { matches.add(com.google.gwt.xml.client.Element.class); } if (result instanceof org.w3c.dom.Node) { matches.add(com.google.gwt.xml.client.Node.class); } return matches.toArray(new Class[0]); } } class CapabilitiesCallback implements Callback<WfsGetCapabilitiesInfo, String> { WfsGetCapabilitiesInfo result; private String reason; @Override public void onSuccess(WfsGetCapabilitiesInfo result) { this.result = result; } @Override public void onFailure(String reason) { this.reason = reason; } public WfsGetCapabilitiesInfo getResult() { return result; } public String getReason() { return reason; } } }