org.jboss.naming.remote.protocol.v1.BaseProtocolCommand Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jboss-remote-naming Show documentation
Show all versions of jboss-remote-naming Show documentation
Library for remote naming (JNDI) with JBoss AS
/*
* JBoss, Home of Professional Open Source.
* Copyright 2011, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.naming.remote.protocol.v1;
import java.io.DataInput;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.jboss.marshalling.Unmarshaller;
import org.jboss.naming.remote.protocol.ProtocolCommand;
import static org.jboss.naming.remote.protocol.v1.Constants.EXCEPTION;
import static org.jboss.naming.remote.protocol.v1.Constants.FAILURE;
import static org.jboss.naming.remote.protocol.v1.Constants.SUCCESS;
import static org.jboss.naming.remote.protocol.v1.ReadUtil.prepareForUnMarshalling;
/**
* @author John Bailey
*/
abstract class BaseProtocolCommand> implements ProtocolCommand {
public static final int DEFAULT_TIMEOUT = 10;
private int nextCorrelationId = 1;
private final Map requests = new HashMap();
private final byte commandId;
protected BaseProtocolCommand(byte commandId) {
this.commandId = commandId;
}
public byte getCommandId() {
return commandId;
}
protected void readResult(final int correlationId, final DataInput input, final ValueReader valueReader) throws IOException {
final F future = getFuture(correlationId);
try {
byte outcome = input.readByte();
if (outcome == SUCCESS) {
valueReader.read(input, future);
} else if (outcome == FAILURE) {
byte parameterType = input.readByte();
if (parameterType != EXCEPTION) {
throw new IOException("Unexpected response parameter received.");
}
final Unmarshaller unmarshaller = prepareForUnMarshalling(input, this.getClass().getClassLoader());
final Exception exception = unmarshaller.readObject(Exception.class);
future.setHeldException(exception);
} else {
future.setException(new IOException("Outcome not understood"));
}
} catch (ClassCastException e) {
future.setException(new IOException(e));
} catch (ClassNotFoundException e) {
future.setException(new IOException(e));
} catch (IOException e) {
future.setException(e);
}
}
private synchronized int getNextCorrelationId() {
int next = nextCorrelationId++;
// After the maximum integer start back at the beginning.
if (next < 0) {
nextCorrelationId = 2;
next = 1;
}
return next;
}
protected synchronized int reserveNextCorrelationId(F future) {
Integer next = getNextCorrelationId();
while (requests.containsKey(next)) {
next = getNextCorrelationId();
}
requests.put(next, future);
return next;
}
private synchronized F getFuture(final int correlationId) {
return requests.get(correlationId);
}
protected synchronized void releaseCorrelationId(int correlationId) {
requests.remove(correlationId);
}
protected interface ValueReader> {
void read(DataInput input, F future) throws IOException;
}
}