/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.ignite.internal.util.nio;
import java.io.IOException;
import java.nio.ByteBuffer;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteException;
import org.apache.ignite.IgniteLogger;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
import org.apache.ignite.internal.util.typedef.internal.LT;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.lang.IgniteInClosure;
/**
* Filter that transforms byte buffers to user-defined objects and vice-versa
* with specified {@link GridNioParser}.
*/
public class GridNioCodecFilter extends GridNioFilterAdapter {
/** Parser used. */
private GridNioParser parser;
/** Grid logger. */
@GridToStringExclude
private IgniteLogger log;
/** Whether direct mode is used. */
private boolean directMode;
/**
* Creates a codec filter.
*
* @param parser Parser to use.
* @param log Log instance to use.
* @param directMode Whether direct mode is used.
*/
public GridNioCodecFilter(GridNioParser parser, IgniteLogger log, boolean directMode) {
super("GridNioCodecFilter");
this.parser = parser;
this.log = log;
this.directMode = directMode;
}
/** {@inheritDoc} */
@Override public String toString() {
return S.toString(GridNioCodecFilter.class, this);
}
/** {@inheritDoc} */
@Override public void onSessionOpened(GridNioSession ses) throws IgniteCheckedException {
proceedSessionOpened(ses);
}
/** {@inheritDoc} */
@Override public void onSessionClosed(GridNioSession ses) throws IgniteCheckedException {
proceedSessionClosed(ses);
}
/** {@inheritDoc} */
@Override public void onExceptionCaught(
GridNioSession ses,
IgniteCheckedException ex
) throws IgniteCheckedException {
proceedExceptionCaught(ses, ex);
}
/** {@inheritDoc} */
@Override public GridNioFuture<?> onSessionWrite(
GridNioSession ses,
Object msg,
boolean fut,
IgniteInClosure<IgniteException> ackC
) throws IgniteCheckedException {
// No encoding needed in direct mode.
if (directMode)
return proceedSessionWrite(ses, msg, fut, ackC);
try {
ByteBuffer res = parser.encode(ses, msg);
return proceedSessionWrite(ses, res, fut, ackC);
}
catch (IOException e) {
throw new GridNioException(e);
}
}
/** {@inheritDoc} */
@Override public void onMessageReceived(GridNioSession ses, Object msg) throws IgniteCheckedException {
if (!(msg instanceof ByteBuffer))
throw new GridNioException("Failed to decode incoming message (incoming message is not a byte buffer, " +
"is filter properly placed?): " + msg.getClass());
try {
ByteBuffer input = (ByteBuffer)msg;
while (input.hasRemaining()) {
Object res = parser.decode(ses, input);
if (res != null)
proceedMessageReceived(ses, res);
else {
if (input.hasRemaining()) {
if (directMode)
return;
LT.warn(log, "Parser returned null but there are still unread data in input buffer (bug in " +
"parser code?) [parser=" + parser + ", ses=" + ses + ']');
input.position(input.limit());
}
}
}
}
catch (IOException e) {
throw new GridNioException(e);
}
}
/** {@inheritDoc} */
@Override public GridNioFuture<Boolean> onSessionClose(GridNioSession ses) throws IgniteCheckedException {
return proceedSessionClose(ses);
}
/** {@inheritDoc} */
@Override public void onSessionIdleTimeout(GridNioSession ses) throws IgniteCheckedException {
proceedSessionIdleTimeout(ses);
}
/** {@inheritDoc} */
@Override public void onSessionWriteTimeout(GridNioSession ses) throws IgniteCheckedException {
proceedSessionWriteTimeout(ses);
}
}