All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.jetty.server.handler.HandlerCollection Maven / Gradle / Ivy

There is a newer version: 12.1.0.alpha0
Show newest version
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

package org.eclipse.jetty.server.handler;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HandlerContainer;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.ArrayUtil;
import org.eclipse.jetty.util.MultiException;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;

/**
 * A collection of handlers.
 * 

* The default implementations calls all handlers in list order, * regardless of the response status or exceptions. Derived implementation * may alter the order or the conditions of calling the contained * handlers. */ @ManagedObject("Handler of multiple handlers") public class HandlerCollection extends AbstractHandlerContainer { private final boolean _mutableWhenRunning; protected final AtomicReference _handlers = new AtomicReference<>(); public HandlerCollection() { this(false); } public HandlerCollection(Handler... handlers) { this(false, handlers); } public HandlerCollection(boolean mutableWhenRunning, Handler... handlers) { _mutableWhenRunning = mutableWhenRunning; if (handlers.length > 0) setHandlers(handlers); } /** * @return the array of handlers. */ @Override @ManagedAttribute(value = "Wrapped handlers", readonly = true) public Handler[] getHandlers() { Handlers handlers = _handlers.get(); return handlers == null ? null : handlers._handlers; } /** * @param handlers the array of handlers to set. */ public void setHandlers(Handler[] handlers) { if (!_mutableWhenRunning && isStarted()) throw new IllegalStateException(getState()); while (true) { if (updateHandlers(_handlers.get(), newHandlers(handlers))) break; } } protected Handlers newHandlers(Handler[] handlers) { if (handlers == null || handlers.length == 0) return null; return new Handlers(handlers); } protected boolean updateHandlers(Handlers old, Handlers handlers) { if (handlers != null) { // check for loops for (Handler handler : handlers._handlers) { if (handler == this || (handler instanceof HandlerContainer && Arrays.asList(((HandlerContainer)handler).getChildHandlers()).contains(this))) throw new IllegalStateException("setHandler loop"); } // Set server for (Handler handler : handlers._handlers) { if (handler.getServer() != getServer()) handler.setServer(getServer()); } } if (_handlers.compareAndSet(old, handlers)) { Handler[] oldBeans = old == null ? null : old._handlers; Handler[] newBeans = handlers == null ? null : handlers._handlers; updateBeans(oldBeans, newBeans); return true; } return false; } @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { if (isStarted()) { Handlers handlers = _handlers.get(); if (handlers == null) return; MultiException mex = null; for (Handler handler : handlers._handlers) { try { handler.handle(target, baseRequest, request, response); } catch (IOException | RuntimeException e) { throw e; } catch (Exception e) { if (mex == null) mex = new MultiException(); mex.add(e); } } if (mex != null) { if (mex.size() == 1) throw new ServletException(mex.getThrowable(0)); else throw new ServletException(mex); } } } /** * Adds a handler. * This implementation adds the passed handler to the end of the existing collection of handlers. * If the handler is already added, it is removed and readded */ public void addHandler(Handler handler) { while (true) { Handlers old = _handlers.get(); Handlers handlers = newHandlers(ArrayUtil.addToArray(old == null ? null : ArrayUtil.removeFromArray(old._handlers, handler), handler, Handler.class)); if (updateHandlers(old, handlers)) break; } } /** * Prepends a handler. * This implementation adds the passed handler to the start of the existing collection of handlers. */ public void prependHandler(Handler handler) { while (true) { Handlers old = _handlers.get(); Handlers handlers = newHandlers(ArrayUtil.prependToArray(handler, old == null ? null : old._handlers, Handler.class)); if (updateHandlers(old, handlers)) break; } } public void removeHandler(Handler handler) { while (true) { Handlers old = _handlers.get(); if (old == null || old._handlers.length == 0) break; Handlers handlers = newHandlers(ArrayUtil.removeFromArray(old._handlers, handler)); if (updateHandlers(old, handlers)) break; } } @Override protected void expandChildren(List list, Class byClass) { Handler[] handlers = getHandlers(); if (handlers != null) for (Handler h : handlers) { expandHandler(h, list, byClass); } } @Override public void destroy() { if (!isStopped()) throw new IllegalStateException("!STOPPED"); Handler[] children = getChildHandlers(); setHandlers(null); for (Handler child : children) { child.destroy(); } super.destroy(); } protected static class Handlers { private final Handler[] _handlers; protected Handlers(Handler[] handlers) { this._handlers = handlers; } public Handler[] getHandlers() { return _handlers; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy