asfgit closed pull request #328: MBW for Spring Views URL: https://github.com/apache/cxf/pull/328
This is a PR merged from a forked repository. As GitHub hides the original diff on merge, it is displayed below for the sake of provenance: As this is a foreign pull request (from a fork), the diff is supplied below (as it won't show otherwise due to GitHub magic): diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/Messages.properties b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/Messages.properties new file mode 100644 index 00000000000..7dd277348d8 --- /dev/null +++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/Messages.properties @@ -0,0 +1,21 @@ +# +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. +# +# +RESPONSE_REDIRECTED_TO=Setting an instance of \"{0}\" as HttpServletRequest attribute \"{1}\" and redirecting the response to \"{2}\". diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/SpringViewResolverProvider.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/SpringViewResolverProvider.java new file mode 100644 index 00000000000..8fa38cd0bea --- /dev/null +++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/SpringViewResolverProvider.java @@ -0,0 +1,395 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.cxf.jaxrs.spring; + +import java.io.IOException; +import java.io.OutputStream; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; +import java.util.Collections; +import java.util.Locale; +import java.util.Map; +import java.util.ResourceBundle; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.servlet.RequestDispatcher; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.ext.MessageBodyWriter; +import javax.ws.rs.ext.Provider; + +import org.apache.cxf.common.i18n.BundleUtils; +import org.apache.cxf.common.logging.LogUtils; +import org.apache.cxf.common.util.StringUtils; +import org.apache.cxf.jaxrs.ext.MessageContext; +import org.apache.cxf.jaxrs.provider.AbstractConfigurableProvider; +import org.apache.cxf.jaxrs.utils.ExceptionUtils; +import org.apache.cxf.message.Message; +import org.apache.cxf.phase.PhaseInterceptorChain; +import org.apache.cxf.transport.http.AbstractHTTPDestination; +import org.springframework.web.servlet.LocaleResolver; +import org.springframework.web.servlet.View; +import org.springframework.web.servlet.ViewResolver; + +/** + * CXF view provider that delegates view rendering to Spring MVC Views. + * + * Sample usage in a spring application: + * <pre> + @Bean + public SpringViewResolverProvider springViewProvider(ViewResolver viewResolver) { + SpringViewResolverProvider viewProvider = new SpringViewResolverProvider(viewResolver, + new AcceptHeaderLocaleResolver()); + viewProvider.setUseClassNames(true); + viewProvider.setBeanName("model"); + viewProvider.setResourcePaths(Collections.singletonMap("/remove", "registeredClients")); + return viewProvider; + } + * </pre> + */ +@Produces("text/html") +@Provider +public class SpringViewResolverProvider extends AbstractConfigurableProvider implements MessageBodyWriter<Object> { + + private static final ResourceBundle BUNDLE = BundleUtils.getBundle(SpringViewResolverProvider.class); + + private static final Logger LOG = LogUtils.getL7dLogger(SpringViewResolverProvider.class); + + private static final String MESSAGE_RESOURCE_PATH_PROPERTY = "redirect.resource.path"; + + private static final String DEFAULT_RESOURCE_EXTENSION = ""; + + private static final String DEFAULT_LOCATION_PREFIX = ""; + + private final ViewResolver viewResolver; + + private String resourcePath; + + private Map<String, String> resourcePaths = Collections.emptyMap(); + + private Map<String, String> classResources = Collections.emptyMap(); + + private Map<? extends Enum<?>, String> enumResources = Collections.emptyMap(); + + private boolean useClassNames; + + private Map<String, String> beanNames = Collections.emptyMap(); + + private String beanName; + + private boolean logRedirects; + + private boolean strictPathCheck; + + private String locationPrefix; + + private String resourceExtension; + + private MessageContext mc; + + private LocaleResolver localeResolver; + + private String errorView = "/error"; + + public SpringViewResolverProvider(ViewResolver viewResolver, LocaleResolver localeResolver) { + if (viewResolver == null) { + throw new IllegalArgumentException("Argument viewResolver is required"); + } + if (localeResolver == null) { + throw new IllegalArgumentException("Argument localeResolver is required"); + } + this.viewResolver = viewResolver; + this.localeResolver = localeResolver; + } + + @Context + public void setMessageContext(MessageContext context) { + this.mc = context; + } + + public void setStrictPathCheck(boolean use) { + strictPathCheck = use; + } + + public void setUseClassNames(boolean use) { + useClassNames = use; + } + + public long getSize(Object t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mt) { + return -1; + } + + private String getViewName(Class<?> type) { + String viewName = doGetClassResourceName(type); + if (viewName == null) { + for (Class<?> in : type.getInterfaces()) { + viewName = doGetClassResourceName(in); + if (viewName != null) { + break; + } + } + } + return viewName; + } + + private Locale getLocale() { + return localeResolver.resolveLocale(mc.getHttpServletRequest()); + } + + private String doGetClassResourceName(Class<?> type) { + String simpleName = StringUtils.uncapitalize(type.getSimpleName()); + String thePrefix = locationPrefix == null ? DEFAULT_LOCATION_PREFIX : locationPrefix; + String theExtension = resourceExtension == null ? DEFAULT_RESOURCE_EXTENSION : resourceExtension; + String viewName = thePrefix + simpleName + theExtension; + View view = resolveView(viewName); + return view != null ? viewName : null; + } + + public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mt) { + + if (useClassNames && getViewName(type) != null) { + return true; + } + if (resourcePath != null || classResourceSupported(type)) { + return true; + } + if (!resourcePaths.isEmpty()) { + String path = getRequestPath(); + for (String requestPath : resourcePaths.keySet()) { + boolean result = strictPathCheck ? path.endsWith(requestPath) : path.contains(requestPath); + if (result) { + return true; + } + } + } + return mc != null && mc.get(MESSAGE_RESOURCE_PATH_PROPERTY) != null; + } + + private boolean classResourceSupported(Class<?> type) { + String typeName = type.getName(); + if (type.isEnum()) { + for (Object o : enumResources.keySet()) { + if (o.getClass().getName().equals(typeName)) { + return true; + } + } + for (String name : classResources.keySet()) { + if (name.startsWith(typeName)) { + return true; + } + } + return false; + } + return classResources.containsKey(typeName); + } + + public void writeTo(Object o, Class<?> clazz, Type genericType, Annotation[] annotations, MediaType type, + MultivaluedMap<String, Object> headers, OutputStream os) throws IOException { + + View view = getView(clazz, o); + String attributeName = getBeanName(o); + Map<String, Object> model = Collections.singletonMap(attributeName, o); + + try { + mc.put(AbstractHTTPDestination.REQUEST_REDIRECTED, Boolean.TRUE); + logRedirection(view, attributeName, o); + view.render(model, mc.getHttpServletRequest(), mc.getHttpServletResponse()); + } catch (Throwable ex) { + handleViewRenderingException(view, ex); + } + } + + /** + * By default we'll try to forward to Spring error handler. + * + * If no such handler has been set, or if there is an error during error handling, + * we throw an error and let CXF handle the internal error. + * + * @param view view that produced the rendering error + * @param exception rendering error + */ + private void handleViewRenderingException(View view, Throwable exception) { + LOG.log(Level.WARNING, String.format("Error forwarding to '%s': %s", view, exception.getMessage()), exception); + if (errorView != null) { + mc.getHttpServletRequest().setAttribute(RequestDispatcher.ERROR_EXCEPTION, exception); + mc.getHttpServletRequest().setAttribute(RequestDispatcher.ERROR_STATUS_CODE, 500); + mc.getHttpServletRequest().setAttribute(RequestDispatcher.ERROR_MESSAGE, exception.getMessage()); + try { + mc.getServletContext().getRequestDispatcher(errorView).forward(mc.getHttpServletRequest(), + mc.getHttpServletResponse()); + } catch (Exception e) { + LOG.log(Level.SEVERE, String.format("Error forwarding to error page '%s': %s", + errorView, e.toString()), + e); + handleInternalViewRenderingException(exception); + } + } else { + handleInternalViewRenderingException(exception); + } + } + + private void handleInternalViewRenderingException(Throwable exception) { + mc.put(AbstractHTTPDestination.REQUEST_REDIRECTED, Boolean.FALSE); + throw ExceptionUtils.toInternalServerErrorException(exception, null); + } + + private void logRedirection(View view, String attributeName, Object o) { + Level level = logRedirects ? Level.INFO : Level.FINE; + if (LOG.isLoggable(level)) { + String message = new org.apache.cxf.common.i18n.Message("RESPONSE_REDIRECTED_TO", + BUNDLE, o.getClass().getName(), + attributeName, view).toString(); + LOG.log(level, message); + } + } + + View getView(Class<?> cls, Object o) { + String currentResourcePath = getPathFromMessageContext(); + if (currentResourcePath != null) { + return resolveView(currentResourcePath); + } + + if (!resourcePaths.isEmpty()) { + + String path = getRequestPath(); + for (Map.Entry<String, String> entry : resourcePaths.entrySet()) { + if (path.endsWith(entry.getKey())) { + return resolveView(entry.getValue()); + } + } + } + if (!enumResources.isEmpty() || !classResources.isEmpty()) { + String name = cls.getName(); + if (cls.isEnum()) { + String enumResource = enumResources.get(o); + if (enumResource != null) { + return resolveView(enumResource); + } + name += "." + o.toString(); + } + + String clsResourcePath = classResources.get(name); + if (clsResourcePath != null) { + return resolveView(clsResourcePath); + } + } + + if (useClassNames) { + return resolveView(getViewName(cls)); + } + + return resolveView(resourcePath); + } + + private View resolveView(String viewName) { + try { + return viewResolver.resolveViewName(viewName, getLocale()); + } catch (Exception ex) { + LOG.warning(ExceptionUtils.getStackTrace(ex)); + throw ExceptionUtils.toInternalServerErrorException(ex, null); + } + } + + private String getPathFromMessageContext() { + if (mc != null) { + Object resourcePathProp = mc.get(MESSAGE_RESOURCE_PATH_PROPERTY); + if (resourcePathProp != null) { + StringBuilder sb = new StringBuilder(); + if (locationPrefix != null) { + sb.append(locationPrefix); + } + sb.append(resourcePathProp.toString()); + if (resourceExtension != null) { + sb.append(resourceExtension); + } + return sb.toString(); + } + } + return null; + } + + private String getRequestPath() { + Message inMessage = PhaseInterceptorChain.getCurrentMessage().getExchange().getInMessage(); + return (String) inMessage.get(Message.REQUEST_URI); + } + + public void setResourcePath(String resourcePath) { + this.resourcePath = resourcePath; + } + + public void setBeanNames(Map<String, String> beanNames) { + this.beanNames = beanNames; + } + + public void setBeanName(String beanName) { + this.beanName = beanName; + } + + public void setLogRedirects(String value) { + this.logRedirects = Boolean.valueOf(value); + } + + protected String getBeanName(Object bean) { + if (beanName != null) { + return beanName; + } + String name = beanNames.get(bean.getClass().getName()); + if (name != null) { + return name; + } + Class<?> resourceClass = bean.getClass(); + if (useClassNames && doGetClassResourceName(resourceClass) == null) { + for (Class<?> cls : bean.getClass().getInterfaces()) { + if (doGetClassResourceName(cls) != null) { + resourceClass = cls; + break; + } + } + } + + return resourceClass.getSimpleName().toLowerCase(); + } + + public void setResourcePaths(Map<String, String> resourcePaths) { + this.resourcePaths = resourcePaths; + } + + public void setClassResources(Map<String, String> resources) { + this.classResources = resources; + } + + public void setEnumResources(Map<? extends Enum<?>, String> enumResources) { + this.enumResources = enumResources; + } + + public void setLocationPrefix(String locationPrefix) { + this.locationPrefix = locationPrefix; + } + + public void setResourceExtension(String resourceExtension) { + this.resourceExtension = resourceExtension; + } + + public void setErrorView(String errorView) { + this.errorView = errorView; + } +} \ No newline at end of file diff --git a/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/spring/SpringViewResolverProviderTest.java b/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/spring/SpringViewResolverProviderTest.java new file mode 100644 index 00000000000..6dc9365f4da --- /dev/null +++ b/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/spring/SpringViewResolverProviderTest.java @@ -0,0 +1,408 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.cxf.jaxrs.spring; + +import java.io.Closeable; +import java.lang.annotation.Annotation; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.concurrent.Executor; + +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.InternalServerErrorException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedHashMap; + +import org.apache.cxf.Bus; +import org.apache.cxf.binding.Binding; +import org.apache.cxf.endpoint.Endpoint; +import org.apache.cxf.feature.Feature; +import org.apache.cxf.interceptor.AbstractAttributedInterceptorProvider; +import org.apache.cxf.interceptor.Interceptor; +import org.apache.cxf.jaxrs.ext.MessageContextImpl; +import org.apache.cxf.jaxrs.provider.ServerProviderFactory; +import org.apache.cxf.message.ExchangeImpl; +import org.apache.cxf.message.Message; +import org.apache.cxf.message.MessageImpl; +import org.apache.cxf.service.Service; +import org.apache.cxf.service.model.BindingInfo; +import org.apache.cxf.service.model.EndpointInfo; +import org.apache.cxf.transport.MessageObserver; +import org.apache.cxf.transport.http.AbstractHTTPDestination; +import org.easymock.EasyMockRule; +import org.easymock.EasyMockSupport; +import org.easymock.Mock; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.springframework.web.servlet.LocaleResolver; +import org.springframework.web.servlet.View; +import org.springframework.web.servlet.ViewResolver; +import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver; +import org.springframework.web.servlet.view.BeanNameViewResolver; + +import static org.easymock.EasyMock.anyObject; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.expectLastCall; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class SpringViewResolverProviderTest extends EasyMockSupport { + + @Rule + public EasyMockRule rule = new EasyMockRule(this); + + @Mock + private ViewResolver viewResolverMock; + + @Mock + private LocaleResolver localeResolverMock; + + @Mock + private View viewMock; + + @Mock + private HttpServletRequest requestMock; + + @Mock + private HttpServletResponse responseMock; + + @Mock + private ServletContext servletContextMock; + + @Mock + private RequestDispatcher requestDispatcherMock; + + private SpringViewResolverProvider viewResolver; + + private Locale locale = Locale.US; + + @Before + public void setUp() { + this.viewResolver = new SpringViewResolverProvider(viewResolverMock, localeResolverMock); + ExchangeImpl exchange = new ExchangeImpl(); + Endpoint endpoint = new MockEndpoint(); + endpoint.put(ServerProviderFactory.class.getName(), ServerProviderFactory.getInstance()); + exchange.put(Endpoint.class, endpoint); + exchange.put(ServerProviderFactory.class.getName(), ServerProviderFactory.getInstance()); + MessageImpl message = new MessageImpl(); + message.setExchange(exchange); + message.put(AbstractHTTPDestination.HTTP_REQUEST, requestMock); + message.put(AbstractHTTPDestination.HTTP_RESPONSE, responseMock); + message.put(AbstractHTTPDestination.HTTP_CONTEXT, servletContextMock); + viewResolver.setMessageContext(new MessageContextImpl(message)); + } + + @Test + public void testIsWriteableEnum() throws Exception { + String viewName = "/test"; + View view = expectGetView(viewName); + viewResolver.setClassResources(Collections.singletonMap(TestEnum.class.getName() + "." + + TestEnum.ONE, viewName)); + replayAll(); + assertTrue(viewResolver.isWriteable(TestEnum.ONE.getClass(), null, null, null)); + assertEquals(view, viewResolver.getView(TestEnum.ONE.getClass(), TestEnum.ONE)); + } + + @Test + public void testIsWriteableEnum2() { + String viewName = "/test"; + View view = expectGetView(viewName); + viewResolver.setEnumResources(Collections.singletonMap(TestEnum.ONE, viewName)); + replayAll(); + assertTrue(viewResolver.isWriteable(TestEnum.ONE.getClass(), null, null, null)); + assertEquals(view, viewResolver.getView(TestEnum.ONE.getClass(), TestEnum.ONE)); + } + + @Test + public void testWriteTo() throws Exception { + String viewName = "/test"; + expectWriteTo(viewName); + viewMock.render(anyObject(Map.class), anyObject(HttpServletRequest.class), + anyObject(HttpServletResponse.class)); + expectLastCall(); + replayAll(); + viewResolver.writeTo(TestEnum.ONE, TestEnum.ONE.getClass(), null, new Annotation[] {}, + MediaType.TEXT_HTML_TYPE, + new MultivaluedHashMap<String, Object>(), null); + } + + @Test + public void testWriteToWithRenderingError() throws Exception { + String viewName = "/test"; + Exception exception = new RuntimeException("my exception"); + expectWriteTo(viewName); + viewMock.render(anyObject(Map.class), anyObject(HttpServletRequest.class), + anyObject(HttpServletResponse.class)); + expectLastCall().andThrow(exception); + requestMock.setAttribute(RequestDispatcher.ERROR_EXCEPTION, exception); + requestMock.setAttribute(RequestDispatcher.ERROR_STATUS_CODE, 500); + requestMock.setAttribute(RequestDispatcher.ERROR_MESSAGE, exception.getMessage()); + expect(servletContextMock.getRequestDispatcher("/error")).andReturn(requestDispatcherMock); + requestDispatcherMock.forward(anyObject(HttpServletRequest.class), anyObject(HttpServletResponse.class)); + expectLastCall(); + replayAll(); + viewResolver.writeTo(TestEnum.ONE, TestEnum.ONE.getClass(), null, new Annotation[] {}, + MediaType.TEXT_HTML_TYPE, + new MultivaluedHashMap<String, Object>(), null); + } + + @Test(expected = InternalServerErrorException.class) + public void testWriteToWithInternalRenderingError() throws Exception { + String viewName = "/test"; + Exception exception = new RuntimeException("my exception"); + expectWriteTo(viewName); + viewMock.render(anyObject(Map.class), anyObject(HttpServletRequest.class), + anyObject(HttpServletResponse.class)); + expectLastCall().andThrow(exception); + requestMock.setAttribute(RequestDispatcher.ERROR_EXCEPTION, exception); + requestMock.setAttribute(RequestDispatcher.ERROR_STATUS_CODE, 500); + requestMock.setAttribute(RequestDispatcher.ERROR_MESSAGE, exception.getMessage()); + expect(servletContextMock.getRequestDispatcher("/error")).andReturn(requestDispatcherMock); + requestDispatcherMock.forward(anyObject(HttpServletRequest.class), anyObject(HttpServletResponse.class)); + expectLastCall().andThrow(new RuntimeException("internal")); + replayAll(); + viewResolver.writeTo(TestEnum.ONE, TestEnum.ONE.getClass(), null, new Annotation[] {}, + MediaType.TEXT_HTML_TYPE, + new MultivaluedHashMap<String, Object>(), null); + } + + @Test(expected = InternalServerErrorException.class) + public void testWriteToWithNullErrorView() throws Exception { + viewResolver.setErrorView(null); + String viewName = "/test"; + Exception exception = new RuntimeException("my exception"); + expectWriteTo(viewName); + viewMock.render(anyObject(Map.class), anyObject(HttpServletRequest.class), + anyObject(HttpServletResponse.class)); + expectLastCall().andThrow(exception); + replayAll(); + viewResolver.writeTo(TestEnum.ONE, TestEnum.ONE.getClass(), null, new Annotation[] {}, + MediaType.TEXT_HTML_TYPE, + new MultivaluedHashMap<String, Object>(), null); + } + + @Test(expected = IllegalArgumentException.class) + public void testConstructorWithViewResolverNull() { + new SpringViewResolverProvider(null, new AcceptHeaderLocaleResolver()); + } + + @Test(expected = IllegalArgumentException.class) + public void testConstructorWithLocaleResolverNull() { + new SpringViewResolverProvider(new BeanNameViewResolver(), null); + } + + private View expectGetView(String viewName) { + expect(localeResolverMock.resolveLocale(anyObject(HttpServletRequest.class))).andReturn(locale); + try { + expect(viewResolverMock.resolveViewName(viewName, locale)).andReturn(viewMock); + } catch (Exception e) { + throw new RuntimeException(e); + } + return viewMock; + } + + private void expectWriteTo(String viewName) { + expectGetView(viewName); + viewResolver.setEnumResources(Collections.singletonMap(TestEnum.ONE, viewName)); + expect(localeResolverMock.resolveLocale(anyObject(HttpServletRequest.class))).andReturn(locale); + try { + expect(viewResolverMock.resolveViewName(viewName, locale)).andReturn(viewMock); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private enum TestEnum { + ONE, + TWO + } + + private static final class TestView implements View { + + private String viewName; + + TestView(String viewName) { + this.viewName = viewName; + } + + @Override + public String getContentType() { + return null; + } + + @Override + public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) + throws Exception { + } + + public String getViewName() { + return viewName; + } + } + + private static final class MockEndpoint extends AbstractAttributedInterceptorProvider implements Endpoint { + + private static final long serialVersionUID = 1L; + + private EndpointInfo epi = new EndpointInfo(); + + MockEndpoint() { + epi.setBinding(new BindingInfo(null, null)); + } + + public List<Feature> getActiveFeatures() { + return null; + } + + public Binding getBinding() { + return null; + } + + public EndpointInfo getEndpointInfo() { + return this.epi; + } + + public Executor getExecutor() { + return null; + } + + public void setExecutor(Executor executor) { + } + + public MessageObserver getInFaultObserver() { + return null; + } + + public void setInFaultObserver(MessageObserver observer) { + } + + public MessageObserver getOutFaultObserver() { + return null; + } + + public void setOutFaultObserver(MessageObserver observer) { + } + + public Service getService() { + return null; + } + + public void addCleanupHook(Closeable c) { + } + + public List<Closeable> getCleanupHooks() { + return null; + } + } + + private static class MockBus implements Bus { + + @Override + public <T> T getExtension(Class<T> extensionType) { + return null; + } + + @Override + public <T> void setExtension(T extension, Class<T> extensionType) { + + } + + @Override + public boolean hasExtensionByName(String name) { + return false; + } + + @Override + public String getId() { + return null; + } + + @Override + public void setId(String i) { + + } + + @Override + public void shutdown(boolean wait) { + + } + + @Override + public void setProperty(String s, Object o) { + + } + + @Override + public Object getProperty(String s) { + return null; + } + + @Override + public Map<String, Object> getProperties() { + return null; + } + + @Override + public void setProperties(Map<String, Object> properties) { + + } + + @Override + public Collection<Feature> getFeatures() { + return null; + } + + @Override + public void setFeatures(Collection<? extends Feature> features) { + + } + + @Override + public BusState getState() { + return null; + } + + @Override + public List<Interceptor<? extends Message>> getInInterceptors() { + return null; + } + + @Override + public List<Interceptor<? extends Message>> getOutInterceptors() { + return null; + } + + @Override + public List<Interceptor<? extends Message>> getInFaultInterceptors() { + return null; + } + + @Override + public List<Interceptor<? extends Message>> getOutFaultInterceptors() { + return null; + } + } +} \ No newline at end of file ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: [email protected] With regards, Apache Git Services
