Java tutorial
/* * Copyright 2007-2012 the original author or authors. * * 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 net.paoding.rose.web.portal.impl; import java.util.concurrent.ExecutorService; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; import net.paoding.rose.web.Invocation; import net.paoding.rose.web.impl.thread.InvocationBean; import net.paoding.rose.web.portal.Pipe; import net.paoding.rose.web.portal.Portal; import net.paoding.rose.web.portal.PortalFactory; import net.paoding.rose.web.portal.WindowListener; import net.paoding.rose.web.portal.PortalSetting; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.util.Assert; /** * {@link PortalFactory} * <p> * * {@link PortalFactoryImpl}? * {@link #setExecutorService(ExecutorService)} * {@link #setExecutorServiceBySpring(ThreadPoolTaskExecutor)} * Portal??? * <p> * * ? {@link WindowListener} ?portal????? * * @see PortalImpl * * @author [qieqie.wang@gmail.com] * */ public class PortalFactoryImpl implements PortalFactory, InitializingBean { protected Log logger = LogFactory.getLog(getClass()); private ExecutorService executorService; private WindowListener windowListener; public void setExecutorService(ExecutorService executor) { if (logger.isInfoEnabled()) { logger.info("using executorService: " + executor); } this.executorService = executor; } public ExecutorService getExecutorService() { return executorService; } public void setWindowListener(WindowListener portalListener) { this.windowListener = portalListener; } public WindowListener getWindowListener() { return windowListener; } @Override public void afterPropertiesSet() throws Exception { Assert.notNull(windowListener); Assert.notNull(executorService); } @Override public Portal createPortal(Invocation inv) { PortalImpl portal = (PortalImpl) inv.getAttribute("$$paoding-rose-portal.portal"); if (portal != null) { return portal; } portal = new PortalImpl(inv, executorService, windowListener); // long timeout = 0; PortalSetting portalSetting = inv.getMethod().getAnnotation(PortalSetting.class); if (portalSetting != null) { if (portalSetting.timeout() >= 0) { long annotationTimeout = portalSetting.timeUnit().toMillis(portalSetting.timeout()); // < 0PortalSetting?PortalSettingtimeoutdefaultTimeout // == 0????defaultTimeout if (annotationTimeout >= 0) { timeout = annotationTimeout; } } } if (timeout > 0) { portal.setTimeout(timeout); } // ?request HttpServletRequest innerRequest = inv.getRequest(); HttpServletRequestWrapper requestWrapper = null; while (innerRequest instanceof HttpServletRequestWrapper) { requestWrapper = (HttpServletRequestWrapper) innerRequest; innerRequest = (HttpServletRequest) ((HttpServletRequestWrapper) innerRequest).getRequest(); } final PortalRequest portalRequest = new PortalRequest(portal, innerRequest); if (requestWrapper == null) { inv.setRequest(portalRequest); } else { requestWrapper.setRequest(portalRequest); } // ?response HttpServletResponse innerResponse = inv.getResponse(); HttpServletResponseWrapper responseWrapper = null; while (innerResponse instanceof HttpServletResponseWrapper) { responseWrapper = (HttpServletResponseWrapper) innerResponse; innerResponse = (HttpServletResponse) ((HttpServletResponseWrapper) innerResponse).getResponse(); } final PortalResponse portalResponse = new PortalResponse(portal, innerResponse); if (responseWrapper == null) { ((InvocationBean) inv).setResponse(portalResponse); } else { responseWrapper.setResponse(portalResponse); } // inv.setAttribute("$$paoding-rose-portal.portal", portal); return portal; } @Override public Pipe createPipe(Invocation inv, boolean create) { PipeImpl pipe = (PipeImpl) inv.getHeadInvocation().getAttribute("$$paoding-rose-portal.pipe"); if (pipe == null) { if (create) { pipe = new PipeImpl(inv, executorService, windowListener); inv.getHeadInvocation().setAttribute("$$paoding-rose-portal.pipe", pipe); } } else if (pipe.getInvocation() != inv) { // PortalWaitInterceptorwaitForPipeWindows? // ??portal/pipe??pipe // ?waitForPipeWindowsgetWindows?java.util.ConcurrentModificationException throw new UnsupportedOperationException(// "Pipe is only allowed in one place for a request, " + "don't forward to path that using pipe. "); } return pipe; } }