@Override public boolean isAsyncSupported() { Valve valve = (first != null) ? first : basic; boolean supported = true; while (supported && valve != null) { supported = supported & valve.isAsyncSupported(); valve = valve.getNext(); } return supported; }
/** * Set the Valve instance that has been distinguished as the basic Valve for this Pipeline (if * any). Prior to setting the basic Valve, the Valve's <code>setContainer()</code> will be called, * if it implements <code>Contained</code>, with the owning Container as an argument. The method * may throw an <code>IllegalArgumentException</code> if this Valve chooses not to be associated * with this Container, or <code>IllegalStateException</code> if it is already associated with a * different Container. * * @param valve Valve to be distinguished as the basic Valve */ @Override public void setBasic(Valve valve) { // Change components if necessary Valve oldBasic = this.basic; if (oldBasic == valve) return; // Stop the old component if necessary if (oldBasic != null) { if (getState().isAvailable() && (oldBasic instanceof Lifecycle)) { try { ((Lifecycle) oldBasic).stop(); } catch (LifecycleException e) { log.error("StandardPipeline.setBasic: stop", e); } } if (oldBasic instanceof Contained) { try { ((Contained) oldBasic).setContainer(null); } catch (Throwable t) { ExceptionUtils.handleThrowable(t); } } } // Start the new component if necessary if (valve == null) return; if (valve instanceof Contained) { ((Contained) valve).setContainer(this.container); } if (getState().isAvailable() && valve instanceof Lifecycle) { try { ((Lifecycle) valve).start(); } catch (LifecycleException e) { log.error("StandardPipeline.setBasic: start", e); return; } } // Update the pipeline Valve current = first; while (current != null) { if (current.getNext() == oldBasic) { current.setNext(valve); break; } current = current.getNext(); } this.basic = valve; }
/** * Return the set of Valves in the pipeline associated with this Container, including the basic * Valve (if any). If there are no such Valves, a zero-length array is returned. */ @Override public Valve[] getValves() { ArrayList<Valve> valveList = new ArrayList<Valve>(); Valve current = first; if (current == null) { current = basic; } while (current != null) { valveList.add(current); current = current.getNext(); } return valveList.toArray(new Valve[0]); }
/** * Stop {@link Valve}s) in this pipeline and implement the requirements of {@link * LifecycleBase#stopInternal()}. * * @exception LifecycleException if this component detects a fatal error that prevents this * component from being used */ @Override protected synchronized void stopInternal() throws LifecycleException { setState(LifecycleState.STOPPING); // Stop the Valves in our pipeline (including the basic), if any Valve current = first; if (current == null) { current = basic; } while (current != null) { if (current instanceof Lifecycle) ((Lifecycle) current).stop(); current = current.getNext(); } }
public static void invokeRequest(Valve pipelineHead, Request request) throws ServletException, IOException { pipelineHead.invoke(request, request.getResponse()); // StandardHostValve calls request.getSession(false) on way out, so we will too request.getSession(false); request.recycle(); }
public ObjectName[] getValveObjectNames() { ArrayList<ObjectName> valveList = new ArrayList<ObjectName>(); Valve current = first; if (current == null) { current = basic; } while (current != null) { if (current instanceof ValveBase) { valveList.add(((ValveBase) current).getObjectName()); } current = current.getNext(); } return valveList.toArray(new ObjectName[0]); }
// -------------------- JMX and Registration -------------------- @Override public String getObjectNameKeyProperties() { StringBuilder name = new StringBuilder("type=Valve"); Container container = getContainer(); name.append(MBeanUtils.getContainerKeyProperties(container)); int seq = 0; // Pipeline may not be present in unit testing Pipeline p = container.getPipeline(); if (p != null) { for (Valve valve : p.getValves()) { // Skip null valves if (valve == null) { continue; } // Only compare valves in pipeline until we find this valve if (valve == this) { break; } if (valve.getClass() == this.getClass()) { // Duplicate valve earlier in pipeline // increment sequence number seq++; } } } if (seq > 0) { name.append(",seq="); name.append(seq); } String className = this.getClass().getName(); int period = className.lastIndexOf('.'); if (period >= 0) { className = className.substring(period + 1); } name.append(",name="); name.append(className); return name.toString(); }
/** Add Tomcat-style valve. */ public synchronized void addValve(Valve valve) { /* * Check if this is a GlassFish-style valve that was compiled * against the old org.apache.catalina.Valve interface (from * GlassFish releases prior to V3), which has since been renamed * to org.glassfish.web.valve.GlassFishValve (in V3) */ if (isGlassFishValve(valve)) { try { addValve(new GlassFishValveAdapter(valve)); } catch (Exception e) { String msg = MessageFormat.format(rb.getString(ADD_TOMCAT_STYLE_VALVE_EXCEPTION), valve); log.log(Level.SEVERE, msg, e); } return; } if (valve instanceof Contained) ((Contained) valve).setContainer(this.container); // Start the new Valve if necessary if (started) { if (valve instanceof Lifecycle) { try { ((Lifecycle) valve).start(); } catch (LifecycleException e) { log.log(Level.SEVERE, ADD_VALVE_EXCEPTION, e); } } } if (firstTcValve == null) { firstTcValve = lastTcValve = valve; } else { lastTcValve.setNext(valve); lastTcValve = valve; } if (basic != null) { valve.setNext((Valve) basic); } }
/** * Add a new Valve to the end of the pipeline associated with this Container. Prior to adding the * Valve, the Valve's <code>setContainer()</code> method will be called, if it implements <code> * Contained</code>, with the owning Container as an argument. The method may throw an <code> * IllegalArgumentException</code> if this Valve chooses not to be associated with this Container, * or <code>IllegalStateException</code> if it is already associated with a different Container. * * @param valve Valve to be added * @exception IllegalArgumentException if this Container refused to accept the specified Valve * @exception IllegalArgumentException if the specified Valve refuses to be associated with this * Container * @exception IllegalStateException if the specified Valve is already associated with a different * Container */ @Override public void addValve(Valve valve) { // Validate that we can add this Valve if (valve instanceof Contained) ((Contained) valve).setContainer(this.container); // Start the new component if necessary if (getState().isAvailable()) { if (valve instanceof Lifecycle) { try { ((Lifecycle) valve).start(); } catch (LifecycleException e) { log.error("StandardPipeline.addValve: start: ", e); } } } // Add this Valve to the set associated with this Pipeline if (first == null) { first = valve; valve.setNext(basic); } else { Valve current = first; while (current != null) { if (current.getNext() == basic) { current.setNext(valve); valve.setNext(basic); break; } current = current.getNext(); } } container.fireContainerEvent(Container.ADD_VALVE_EVENT, valve); }
/* * Checks if the give valve is a GlassFish-style valve that was compiled * against the old org.apache.catalina.Valve interface (from * GlassFish releases prior to V3), which has since been renamed * to org.glassfish.web.valve.GlassFishValve (in V3). * * The check is done by checking that it is not an abstract method with * return type int. Note that invoke method in the original Tomcat-based * Valve interface is declared to be void. * * @param valve the valve to check * * @return true if the given valve is a GlassFish-style valve, false * otherwise */ private boolean isGlassFishValve(Valve valve) { try { Method m = valve .getClass() .getMethod( "invoke", org.apache.catalina.Request.class, org.apache.catalina.Response.class); return (m != null && int.class.equals(m.getReturnType()) && (!Modifier.isAbstract(m.getModifiers()))); } catch (Exception e) { return false; } }
/** * Remove the specified Valve from the pipeline associated with this Container, if it is found; * otherwise, do nothing. If the Valve is found and removed, the Valve's <code>setContainer(null) * </code> method will be called if it implements <code>Contained</code>. * * @param valve Valve to be removed */ @Override public void removeValve(Valve valve) { Valve current; if (first == valve) { first = first.getNext(); current = null; } else { current = first; } while (current != null) { if (current.getNext() == valve) { current.setNext(valve.getNext()); break; } current = current.getNext(); } if (first == basic) first = null; if (valve instanceof Contained) ((Contained) valve).setContainer(null); // Stop this valve if necessary if (getState().isAvailable()) { if (valve instanceof Lifecycle) { try { ((Lifecycle) valve).stop(); } catch (LifecycleException e) { log.error("StandardPipeline.removeValve: stop: ", e); } } } try { ((Lifecycle) valve).destroy(); } catch (LifecycleException e) { log.error("StandardPipeline.removeValve: destroy: ", e); } container.fireContainerEvent(Container.REMOVE_VALVE_EVENT, valve); }
private void doInvoke(Request request, Response response, boolean chaining) throws IOException, ServletException { if ((valves.length > 0) || (basic != null)) { // Set the status so that if there are no valves (other than the // basic one), the basic valve's request processing logic will // be invoked int status = GlassFishValve.INVOKE_NEXT; // Iterate over all the valves in the pipeline and invoke // each valve's processing logic and then move onto to the // next valve in the pipeline only if the previous valve indicated // that the pipeline should proceed. int i; for (i = 0; i < valves.length; i++) { Request req = request; Response resp = response; if (chaining) { req = getRequest(request); resp = getResponse(request, response); } status = valves[i].invoke(req, resp); if (status != GlassFishValve.INVOKE_NEXT) break; } // Save a reference to the valve[], to ensure that postInvoke() // is invoked on the original valve[], in case a valve gets added // or removed during the invocation of the basic valve (e.g., // in case access logging is enabled or disabled by some kind of // admin servlet), in which case the indices used for postInvoke // invocations below would be off GlassFishValve[] savedValves = valves; // Invoke the basic valve's request processing and post-request // logic only if the pipeline was not aborted (i.e. no valve // returned END_PIPELINE). // In addition, the basic valve needs to be invoked by the // pipeline only if no Tomcat-style valves have been added. // Otherwise, it will be invoked by the last Tomcat-style valve // directly. if (status == GlassFishValve.INVOKE_NEXT) { if (firstTcValve != null) { firstTcValve.invoke( (org.apache.catalina.connector.Request) request, (org.apache.catalina.connector.Response) response); } else if (basic != null) { Request req = request; Response resp = response; if (chaining) { req = getRequest(request); resp = getResponse(request, response); } basic.invoke(req, resp); basic.postInvoke(req, resp); } } // Invoke the post-request processing logic only on those valves // that returned a status of INVOKE_NEXT for (int j = i - 1; j >= 0; j--) { Request req = request; Response resp = response; if (chaining) { req = getRequest(request); resp = getResponse(request, response); } savedValves[j].postInvoke(req, resp); } savedValves = null; } else { throw new ServletException(rb.getString(NO_VALVES_IN_PIPELINE_EXCEPTION)); } // Calls the protocol handler's init method if the request is marked to be upgraded if (request instanceof org.apache.catalina.connector.Request) { org.apache.catalina.connector.Request req = (org.apache.catalina.connector.Request) request; if (req.isUpgrade()) { HttpUpgradeHandler handler = req.getHttpUpgradeHandler(); if (handler != null) { WebConnectionImpl wc = new WebConnectionImpl( req.getInputStream(), ((org.apache.catalina.connector.Response) req.getResponse()).getOutputStream()); wc.setRequest(req); req.setWebConnection(wc); if (response instanceof org.apache.catalina.connector.Response) { wc.setResponse((org.apache.catalina.connector.Response) response); } Context context = req.getContext(); try { context.fireContainerEvent(ContainerEvent.BEFORE_UPGRADE_HANDLER_INITIALIZED, handler); handler.init(wc); } finally { context.fireContainerEvent(ContainerEvent.AFTER_UPGRADE_HANDLER_INITIALIZED, handler); } } else { log.log(Level.SEVERE, PROTOCOL_HANDLER_REQUIRED_EXCEPTION); } req.setUpgrade(false); } } }