Java tutorial
/** * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. * If a copy of the MPL was not distributed with this file, You can obtain one at * http://mozilla.org/MPL/2.0/. * * This Source Code Form is also subject to the terms of the Health-Related Additional * Disclaimer of Warranty and Limitation of Liability available at * http://www.carewebframework.org/licensing/disclaimer. */ package org.carewebframework.ui.test; import java.lang.reflect.Method; import org.carewebframework.ui.ConsistentIdGenerator; import org.carewebframework.ui.LifecycleEventDispatcher; import org.carewebframework.ui.spring.FrameworkAppContext; import org.springframework.beans.BeanUtils; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpSession; import org.springframework.web.context.WebApplicationContext; import org.zkoss.zk.au.out.AuEcho; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Desktop; import org.zkoss.zk.ui.Execution; import org.zkoss.zk.ui.Session; import org.zkoss.zk.ui.WebApp; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.http.SimpleWebApp; import org.zkoss.zk.ui.impl.DesktopImpl; import org.zkoss.zk.ui.impl.EventProcessor; import org.zkoss.zk.ui.impl.PageImpl; import org.zkoss.zk.ui.metainfo.LanguageDefinition; import org.zkoss.zk.ui.sys.ExecutionsCtrl; import org.zkoss.zk.ui.sys.SessionsCtrl; import org.zkoss.zk.ui.util.Configuration; /** * This class creates a mock ZK environment suitable for certain kinds of unit tests. It creates a * web app instance with a single page and desktop and a mock session and execution. It also creates * a root Spring application context with a child desktop context. */ public class MockEnvironment { private DesktopImpl desktop; private Session session; private MockExecution execution; private FrameworkAppContext rootContext; private FrameworkAppContext desktopContext; private SimpleWebApp webApp; private Configuration configuration; private MockHttpServletRequest request; private MockHttpServletResponse response; private MockServletContext servletContext; private MockServerPush serverPush; /** * Creates a mock environment for unit testing. */ public MockEnvironment() { } /** * Initializes the mock environment. * * @param configLocations Additional config file locations. * @throws Exception Unspecified exception. */ public void init(String... configLocations) throws Exception { // Set up web app servletContext = init(new MockServletContext()); configuration = init(new Configuration()); webApp = init(new SimpleWebApp()); // Create root Spring context rootContext = init(new FrameworkAppContext(null, true), configLocations); servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, rootContext); rootContext.refresh(); // Create mock session request = init(new MockHttpServletRequest(servletContext)); response = init(new MockHttpServletResponse()); session = SessionsCtrl.newSession(webApp, init(new MockHttpSession(servletContext, "mock")), request); SessionsCtrl.setCurrent(session); // Create the page PageImpl page = init(new PageImpl(LanguageDefinition.lookup(null), null, null, null)); // Create the mock execution execution = init(new MockExecution(servletContext, request, response, null, page)); // Create desktop ExecutionsCtrl.setCurrent(execution); desktop = init(new DesktopImpl(webApp, "mock", null, null, request)); ExecutionsCtrl.setCurrent(null); // Initialize the environment webApp.getUiEngine().activate(execution); serverPush = init(new MockServerPush()); desktop.enableServerPush(serverPush); page.preInit(); page.init(init(new MockPageConfig())); inEventListener(true); // Create the desktop Spring context desktopContext = init(new FrameworkAppContext(desktop, true), configLocations); desktopContext.refresh(); } /** * Cleans up all application contexts and invalidates the session. */ public void close() { desktopContext.close(); desktop.destroy(); session.invalidate(); rootContext.close(); webApp.destroy(); } /** * Makes ZK believe the current thread is an event thread. * * @param value If true, the current thread becomes an event thread. If false, it is not an * event thread. * @throws Exception Unspecified exception. */ public void inEventListener(boolean value) throws Exception { Method inEventListener = BeanUtils.findMethod(EventProcessor.class, "inEventListener", boolean.class); inEventListener.setAccessible(true); inEventListener.invoke(null, value); } /** * Initialize the mock servlet context. * * @param servletContext The mock servlet context. * @return The initialized mock servlet context. */ protected MockServletContext init(MockServletContext servletContext) { return servletContext; } /** * Initialize the configuration. * * @param configuration The configuration. * @return The initialized configuration. * @throws Exception Unspecified exception. */ protected Configuration init(Configuration configuration) throws Exception { configuration.addListener(LifecycleEventDispatcher.class); return configuration; } /** * Initialize the web app. * * @param webApp The web app. * @return The initialized web app. */ protected SimpleWebApp init(SimpleWebApp webApp) { webApp.setIdGenerator(new ConsistentIdGenerator()); webApp.init(servletContext, configuration); return webApp; } /** * Initialize the app context. * * @param appContext The app context. * @param configLocations Optional configuration locations. * @return The initialized app context. */ protected FrameworkAppContext init(FrameworkAppContext appContext, String... configLocations) { appContext.setServletContext(servletContext); appContext.setConfigLocations(configLocations); return appContext; } /** * Initialize the mock session. * * @param session The mock session. * @return The initialized mock session. */ protected MockHttpSession init(MockHttpSession session) { return session; } /** * Initialize the page. * * @param page The page. * @return The initialized page. */ protected PageImpl init(PageImpl page) { return page; } /** * Initialize the mock execution. * * @param execution The mock execution. * @return The initialized mock execution. */ protected MockExecution init(MockExecution execution) { return execution; } /** * Initialize the desktop. * * @param desktop The desktop. * @return The initialized desktop. */ protected DesktopImpl init(DesktopImpl desktop) { return desktop; } /** * Initialize the mock server push. * * @param serverPush The mock serverPush. * @return The initialized mock serverPush. */ protected MockServerPush init(MockServerPush serverPush) { return serverPush; } /** * Initialize the mock servlet request. * * @param request The mock request. * @return The initialized mock request. */ protected MockHttpServletRequest init(MockHttpServletRequest request) { request.setRemoteAddr("127.0.0.1"); request.setRemoteHost("mock"); request.setRemotePort(8080); request.setRemoteUser("mockuser"); request.setRequestURI("/zkau/mock"); return request; } /** * Initialize the mock servlet response. * * @param response The mock response. * @return The initialized mock response. */ protected MockHttpServletResponse init(MockHttpServletResponse response) { return response; } /** * Initializes a mock page configuration. * * @param pageConfig The mock page configuration. * @return The initialized mock page configuration. */ protected MockPageConfig init(MockPageConfig pageConfig) { pageConfig.setViewport("auto"); return pageConfig; } public Desktop getDesktop() { return desktop; } public Session getSession() { return session; } public Execution getExecution() { return execution; } public FrameworkAppContext getRootContext() { return rootContext; } public FrameworkAppContext getDesktopContext() { return desktopContext; } public WebApp getWebApp() { return webApp; } /** * First, posts any pending echo requests to the event queue. Then empties the event queue, * sending each queued event to its target. Finally, processes any events on the server push * event queue. * * @return True if events were flushed. */ public boolean flushEvents() { Event event; boolean result = false; for (AuEcho echo : execution.getEchoedEvents()) { Events.postEvent(toEvent(echo)); } execution.getEchoedEvents().clear(); while ((event = execution.getNextEvent()) != null) { Events.sendEvent(event); result = true; } result |= serverPush.flush(); return result; } /** * Converts an echo response to the equivalent event. * * @param echo An echo response. * @return Event as it would be echoed by client. */ private Event toEvent(AuEcho echo) { Object[] raw = echo.getRawData(); Component target = (Component) raw[0]; String name = (String) raw[1]; Object data = raw.length < 3 ? null : AuEcho.getData(target, raw[2]); return new Event(name, target, data); } }