Skip to content

Commit

Permalink
Rename Handler Nested & Collection (#9305)
Browse files Browse the repository at this point in the history
There is now a Handler interface hierarchy:
 + Container is a Handler that has 1 or more contained Handlers.
 + Wrapper is a Container with only 1 handler and a setHandler method.
 + Collection is a Container with n handlers and a addHandler method

class are now:
 + Abstract implements Handler
 + AbstractContainer extends Abstract implements Container
 + BaseWrapper extends AbstractContainer implements Wrapper
 + Sequence extends AbstractContainer implements Collection

 Lots of other associated cleanups
  • Loading branch information
gregw authored Feb 6, 2023
1 parent 377798f commit 60a08f5
Show file tree
Hide file tree
Showing 88 changed files with 406 additions and 536 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ public boolean process(Request request, Response response, Callback callback)
}
}

public static class RootHandler extends Handler.Collection
public static class RootHandler extends Handler.Sequence
{
@Override
public boolean process(Request request, Response response, Callback callback) throws Exception
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -511,11 +511,11 @@ public boolean process(Request request, Response response, Callback callback) th
GzipHandler gzipHandler = new GzipHandler();
server.setHandler(gzipHandler);

Handler.Collection collection = new Handler.Collection();
gzipHandler.setHandler(collection);
Handler.Sequence sequence = new Handler.Sequence();
gzipHandler.setHandler(sequence);

collection.addHandler(new App1Handler());
collection.addHandler(new App2Handler());
sequence.addHandler(new App1Handler());
sequence.addHandler(new App2Handler());
// end::handlerTree[]
}

Expand Down Expand Up @@ -583,7 +583,7 @@ public boolean process(Request request, Response response, Callback callback)
}

// tag::handlerFilter[]
class FilterHandler extends Handler.Wrapper
class FilterHandler extends Handler.BaseWrapper
{
@Override
public boolean process(Request request, Response response, Callback callback) throws Exception
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ public boolean process(Request request, Response response, Callback callback)
fcgiHandler.setOriginalQueryAttribute(queryAttribute);

proxyContext.stop();
proxyContext.insertHandler(new Handler.Wrapper()
proxyContext.insertHandler(new Handler.BaseWrapper()
{
@Override
public boolean process(Request request, Response response, Callback callback) throws Exception
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
* {@link PatternRule} subclasses), via regular expression matching (using
* {@link RegexRule} subclasses), or by a custom implementation of {@code Rule}.</p>
*/
public class RewriteHandler extends Handler.Wrapper
public class RewriteHandler extends Handler.BaseWrapper
{
private final RuleContainer _rules;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,13 +134,6 @@ public interface Handler extends LifeCycle, Destroyable, Invocable, Request.Proc
*/
interface Container extends Handler
{
void addHandler(Handler handler);

default void addHandler(Supplier<Handler> supplier)
{
addHandler(supplier.get());
}

/**
* @return an immutable collection of {@code Handler}s directly contained by this {@code Handler}.
*/
Expand Down Expand Up @@ -223,20 +216,56 @@ default <T extends Handler.Container> T getContainer(Handler handler, Class<T> t
}
return null;
}

/**
* <p>Make a {@link Container} the parent of a {@link Handler}</p>
* @param parent The {@link Container} that will be the parent
* @param handler The {@link Handler} that will be the child
*/
static void setAsParent(Container parent, Handler handler)
{
if (parent instanceof Collection collection)
collection.addHandler(handler);
else if (parent instanceof Wrapper wrapper)
wrapper.setHandler(handler);
else if (parent != null)
throw new IllegalArgumentException("Unknown parent type: " + parent);
}
}

/**
* <p>A {@link Handler.Container} that can contain multiple other {@link Handler}s.</p>
* @see Sequence for an implementation of {@link Collection}.
*/
interface Collection extends Container
{
void addHandler(Handler handler);

default void addHandler(Supplier<Handler> supplier)
{
addHandler(supplier.get());
}

void setHandlers(List<Handler> handlers);

default void setHandlers(Handler... handlers)
{
setHandlers(handlers.length == 0 ? null : List.of(handlers));
}
}

/**
* <p>A {@link Handler.Container} that wraps a single other {@code Handler}.</p>
* @see Handler.Wrapper for an implementation of nested.
* <p>A {@link Handler.Container} that can contain a single other {@code Handler}.</p>
* @see BaseWrapper for an implementation of {@link Wrapper}.
*/
interface Nested extends Container
interface Wrapper extends Container
{
Handler getHandler();

/**
* Set the nested handler.
* Implementations should check for loops, set the server and update any {@link ContainerLifeCycle} beans, all
* of which can be done by using the utility method {@link #updateHandler(Nested, Handler)}
* of which can be done by using the utility method {@link #updateHandler(Wrapper, Handler)}
* @param handler The handler to set.
*/
void setHandler(Handler handler);
Expand All @@ -253,27 +282,16 @@ default void setHandler(Supplier<Handler> supplier)
@Override
default List<Handler> getHandlers()
{
Handler h = getHandler();
if (h == null)
return Collections.emptyList();
return Collections.singletonList(h);
}

@Override
default void addHandler(Handler handler)
{
Handler existing = getHandler();
setHandler(handler);
if (existing != null && handler instanceof Container container)
container.addHandler(existing);
Handler next = getHandler();
return (next == null) ? Collections.emptyList() : Collections.singletonList(next);
}

default void insertHandler(Handler.Nested handler)
default void insertHandler(Wrapper handler)
{
Handler.Nested tail = handler;
while (tail.getHandler() instanceof Handler.Wrapper)
Wrapper tail = handler;
while (tail.getHandler() instanceof BaseWrapper)
{
tail = (Handler.Wrapper)tail.getHandler();
tail = (BaseWrapper)tail.getHandler();
}
if (tail.getHandler() != null)
throw new IllegalArgumentException("bad tail of inserted wrapper chain");
Expand All @@ -282,21 +300,32 @@ default void insertHandler(Handler.Nested handler)
setHandler(handler);
}

/**
* @return The tail {@link Wrapper} of a chain of {@link Wrapper}s
*/
default Wrapper getTail()
{
Wrapper tail = this;
while (tail.getHandler() instanceof Wrapper wrapped)
tail = wrapped;
return tail;
}

/**
* Utility method to: <ul>
* <li>Check the server state and invocation type</li>
* <li>Check for handler loops</li>
* <li>Set the server on the handler</li>
* <li>Update the beans on if the Nests is a {@link ContainerLifeCycle} </li>
* </ul>
* @param nested The Nested implementation to update
* @param wrapper The Nested implementation to update
* @param handler The handle to set
* @return The set handler.
*/
static Handler updateHandler(Nested nested, Handler handler)
static Handler updateHandler(Wrapper wrapper, Handler handler)
{
// check state
Server server = nested.getServer();
Server server = wrapper.getServer();

// If the collection is changed whilst started, then the risk is that if we switch from NON_BLOCKING to BLOCKING
// whilst the execution strategy may have already dispatched the very last available thread, thinking it would
Expand All @@ -310,15 +339,15 @@ static Handler updateHandler(Nested nested, Handler handler)
}

// Check for loops.
if (handler == nested || (handler instanceof Handler.Container container &&
container.getDescendants().contains(nested)))
if (handler == wrapper || (handler instanceof Handler.Container container &&
container.getDescendants().contains(wrapper)))
throw new IllegalStateException("setHandler loop");

if (handler != null && server != null)
handler.setServer(server);

if (nested instanceof org.eclipse.jetty.util.component.ContainerLifeCycle container)
container.updateBean(nested.getHandler(), handler);
if (wrapper instanceof org.eclipse.jetty.util.component.ContainerLifeCycle container)
container.updateBean(wrapper.getHandler(), handler);

return handler;
}
Expand Down Expand Up @@ -532,50 +561,45 @@ public static <T extends Handler.Container> T findContainerOf(Handler.Container
}

/**
* An implementation of {@link Nested}, which is a {@link Handler.Container} that wraps a single other {@link Handler}.
* An implementation of {@link Wrapper}, which is a {@link Handler.Container} that wraps a single other {@link Handler}.
*/
class Wrapper extends AbstractContainer implements Nested
class BaseWrapper extends AbstractContainer implements Wrapper
{
private Handler _handler;

public Wrapper()
public BaseWrapper()
{
this(null);
}

public Wrapper(boolean dynamic)
public BaseWrapper(boolean dynamic)
{
this(dynamic, null);
}

public Wrapper(Handler handler)
public BaseWrapper(Handler handler)
{
this(false, handler);
}

public Wrapper(boolean dynamic, Handler handler)
public BaseWrapper(boolean dynamic, Handler handler)
{
super(dynamic);
_handler = handler == null ? null : Nested.updateHandler(this, handler);
_handler = handler == null ? null : Wrapper.updateHandler(this, handler);
}

@Override
public Handler getHandler()
{
return _handler;
}

@Override
public void setHandler(Handler handler)
{
if (!isDynamic() && isStarted())
throw new IllegalStateException(getState());
_handler = Nested.updateHandler(this, handler);
}

@Override
public List<Handler> getHandlers()
{
Handler next = getHandler();
return (next == null) ? Collections.emptyList() : Collections.singletonList(next);
_handler = Wrapper.updateHandler(this, handler);
}

@Override
Expand All @@ -596,25 +620,24 @@ public InvocationType getInvocationType()
}

/**
* <p>A {@link Handler.Container} that contains a list of other {@code Handler}s.</p>
*
* TODO this should be called List instead
* <p>A {@link Handler.Container} that contains a list of other {@code Handler}s that are
* tried in sequence by {@link #process(Request, Response, Callback)}.</p>
*/
class Collection extends AbstractContainer
class Sequence extends AbstractContainer implements Collection
{
private volatile List<Handler> _handlers = new ArrayList<>();

public Collection(Handler... handlers)
public Sequence(Handler... handlers)
{
this(handlers.length == 0, List.of(handlers));
}

public Collection(boolean dynamic)
public Sequence(boolean dynamic)
{
this(dynamic, Collections.emptyList());
}

public Collection(List<Handler> handlers)
public Sequence(List<Handler> handlers)
{
this(handlers == null || handlers.size() == 0, handlers);
}
Expand All @@ -626,7 +649,7 @@ public Collection(List<Handler> handlers)
*
* @param handlers The handlers to add.
*/
public Collection(boolean dynamic, List<Handler> handlers)
public Sequence(boolean dynamic, List<Handler> handlers)
{
super(dynamic);
setHandlers(handlers);
Expand All @@ -649,11 +672,7 @@ public List<Handler> getHandlers()
return _handlers;
}

public void setHandlers(Handler... handlers)
{
setHandlers(handlers.length == 0 ? null : List.of(handlers));
}

@Override
public void setHandlers(List<Handler> handlers)
{
if (!isDynamic() && isStarted())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Server extends Handler.Wrapper implements Attributes
public class Server extends Handler.BaseWrapper implements Attributes
{
private static final Logger LOG = LoggerFactory.getLogger(Server.class);
private static final String __serverInfo = "jetty/" + Server.getVersion();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
* (obtained from {@link HttpStream#getNanoTime()}) until the stream completion event has been handled by
* {@link HttpStream#succeeded()} or {@link HttpStream#failed(Throwable)}.</p>
*/
public abstract class AbstractLatencyRecordingHandler extends Handler.Wrapper
public abstract class AbstractLatencyRecordingHandler extends Handler.BaseWrapper
{
private static final Logger LOG = LoggerFactory.getLogger(AbstractLatencyRecordingHandler.class);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
* generated can also be unbounded.
* </p>
*/
public class BufferedResponseHandler extends Handler.Wrapper
public class BufferedResponseHandler extends Handler.BaseWrapper
{
public static final String BUFFER_SIZE_ATTRIBUTE_NAME = BufferedResponseHandler.class.getName() + ".buffer-size";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
/**
* <p>Implementation of a {@link Handler} that supports HTTP CONNECT.</p>
*/
public class ConnectHandler extends Handler.Wrapper
public class ConnectHandler extends Handler.BaseWrapper
{
private static final Logger LOG = LoggerFactory.getLogger(ConnectHandler.class);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ContextHandler extends Handler.Wrapper implements Attributes, Graceful, AliasCheck
public class ContextHandler extends Handler.BaseWrapper implements Attributes, Graceful, AliasCheck
{
// TODO where should the alias checking go?
// TODO add protected paths to ServletContextHandler?
Expand Down Expand Up @@ -166,8 +166,7 @@ public ContextHandler(Handler.Container parent, String contextPath)
_context = newContext();
if (contextPath != null)
setContextPath(contextPath);
if (parent != null)
parent.addHandler(this);
Container.setAsParent(parent, this);

if (File.separatorChar == '/')
addAliasCheck(new SymlinkAllowedResourceAliasChecker(this));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
* handles the request.
*/
@ManagedObject("Context Handler Collection")
public class ContextHandlerCollection extends Handler.Collection
public class ContextHandlerCollection extends Handler.Sequence
{
private static final Logger LOG = LoggerFactory.getLogger(ContextHandlerCollection.class);
private final SerializedExecutor _serializedExecutor = new SerializedExecutor();
Expand Down
Loading

0 comments on commit 60a08f5

Please sign in to comment.