/*
 * Copyright (c) 2010, 2017 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package org.glassfish.grizzly.portunif;

import java.io.IOException;
import org.glassfish.grizzly.ReadResult;
import org.glassfish.grizzly.filterchain.BaseFilter;
import org.glassfish.grizzly.filterchain.FilterChain;
import org.glassfish.grizzly.filterchain.FilterChainContext;
import org.glassfish.grizzly.filterchain.FilterChainEvent;
import org.glassfish.grizzly.filterchain.FilterChainContext.TransportContext;
import org.glassfish.grizzly.filterchain.NextAction;

The Filter, which is responsible to connect custom protocol FilterChain with main FilterChain. Usually this Filter is getting added to the custom protocol FilterChain as first Filter.
Author:Alexey Stashok
/** * The {@link org.glassfish.grizzly.filterchain.Filter}, which is responsible to connect custom protocol {@link FilterChain} with * main {@link FilterChain}. Usually this {@link org.glassfish.grizzly.filterchain.Filter} is getting added to the * custom protocol {@link FilterChain} as first {@link org.glassfish.grizzly.filterchain.Filter}. * * @author Alexey Stashok */
public class BackChannelFilter extends BaseFilter { private final PUFilter puFilter; BackChannelFilter(final PUFilter puFilter) { this.puFilter = puFilter; } @Override public NextAction handleRead(final FilterChainContext ctx) throws IOException { // If this method is called as part of natural PU filterchain processing - // just pass process to the next filter if (!isFilterChainRead(ctx)) { return ctx.getInvokeAction(); } // if this is filterchain read - delegate read to the underlying filterchain final FilterChainContext suspendedParentContext = puFilter.suspendedContextAttribute.get(ctx); assert suspendedParentContext != null; final ReadResult readResult = suspendedParentContext.read(); ctx.setMessage(readResult.getMessage()); ctx.setAddressHolder(readResult.getSrcAddressHolder()); readResult.recycle(); return ctx.getInvokeAction(); }
Methods returns true, if handleRead(FilterChainContext) is called because user explicitly initiated FilterChain by calling FilterChainContext.read() or FilterChain.read(FilterChainContext); otherwise false is returned.
/** * Methods returns <tt>true</tt>, if {@link #handleRead(org.glassfish.grizzly.filterchain.FilterChainContext)} * is called because user explicitly initiated FilterChain by calling * {@link FilterChainContext#read()} or {@link FilterChain#read(org.glassfish.grizzly.filterchain.FilterChainContext)}; * otherwise <tt>false</tt> is returned. */
private boolean isFilterChainRead(final FilterChainContext ctx) { return ctx.getMessage() == null; } @Override @SuppressWarnings("unchecked") public NextAction handleWrite(final FilterChainContext ctx) throws IOException { final FilterChainContext suspendedParentContext = puFilter.suspendedContextAttribute.get(ctx); assert suspendedParentContext != null; final TransportContext transportContext = ctx.getTransportContext(); suspendedParentContext.write(ctx.getAddress(), ctx.getMessage(), transportContext.getCompletionHandler(), transportContext.getPushBackHandler(), transportContext.getMessageCloner(), transportContext.isBlocking()); return ctx.getStopAction(); } @Override public NextAction handleEvent(final FilterChainContext ctx, final FilterChainEvent event) throws IOException { // if downstream event - pass it to the puFilter if (isDownstream(ctx)) { final FilterChainContext suspendedParentContext = puFilter.suspendedContextAttribute.get(ctx); assert suspendedParentContext != null; suspendedParentContext.notifyDownstream(event); } return ctx.getInvokeAction(); } @Override public void exceptionOccurred(final FilterChainContext ctx, final Throwable error) { // if downstream event - pass it to the puFilter if (isDownstream(ctx)) { final FilterChainContext suspendedParentContext = puFilter.suspendedContextAttribute.get(ctx); assert suspendedParentContext != null; suspendedParentContext.fail(error); } } private static boolean isDownstream(final FilterChainContext context) { return context.getStartIdx() > context.getEndIdx(); } }