/**
* This file is part of Waarp Project.
*
* Copyright 2009, Frederic Bregier, and individual contributors by the @author tags. See the
* COPYRIGHT.txt in the distribution for a full listing of individual contributors.
*
* All Waarp Project is free software: you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* Waarp 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 General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with Waarp . If not, see
* <http://www.gnu.org/licenses/>.
*/
package org.waarp.openr66.context;
import java.io.File;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.HashMap;
import org.waarp.common.command.exception.CommandAbstractException;
import org.waarp.common.database.data.AbstractDbData.UpdatedInfo;
import org.waarp.common.exception.IllegalFiniteStateException;
import org.waarp.common.exception.NoRestartException;
import org.waarp.common.file.SessionInterface;
import org.waarp.common.file.filesystembased.FilesystemBasedFileParameterImpl;
import org.waarp.common.logging.WaarpLogger;
import org.waarp.common.logging.WaarpLoggerFactory;
import org.waarp.common.state.MachineState;
import org.waarp.openr66.context.authentication.R66Auth;
import org.waarp.openr66.context.filesystem.R66Dir;
import org.waarp.openr66.context.filesystem.R66File;
import org.waarp.openr66.context.filesystem.R66Restart;
import org.waarp.openr66.context.task.exception.OpenR66RunnerErrorException;
import org.waarp.openr66.database.data.DbTaskRunner;
import org.waarp.openr66.database.data.DbTaskRunner.TASKSTEP;
import org.waarp.openr66.protocol.configuration.Configuration;
import org.waarp.openr66.protocol.exception.OpenR66ProtocolSystemException;
import org.waarp.openr66.protocol.localhandler.LocalChannelReference;
import org.waarp.openr66.protocol.utils.FileUtils;
/**
* The global object session in OpenR66, a session by local channel
*
* @author frederic bregier
*
*/
public class R66Session implements SessionInterface {
/**
* Internal Logger
*/
private static final WaarpLogger logger = WaarpLoggerFactory
.getLogger(R66Session.class);
/**
* Block size used during file transfer
*/
private int blockSize = Configuration.configuration.getBLOCKSIZE();
/**
* The local channel reference
*/
private LocalChannelReference localChannelReference;
/**
* Authentication
*/
private final R66Auth auth;
/**
* Remote Address
*/
private SocketAddress raddress;
/**
* Local Address
*/
private SocketAddress laddress;
/**
* Current directory
*/
private final R66Dir dir;
/**
* Current file
*/
private R66File file;
/**
* Does this session is Ready to serve a request
*/
private volatile boolean isReady = false;
/**
* Used to prevent deny of service
*/
private volatile int numOfError = 0;
/**
* Current Restart information
*/
private final R66Restart restart;
/**
* DbTaskRunner
*/
private DbTaskRunner runner = null;
private String status = "NoStatus";
/**
* The Finite Machine State
*/
private final MachineState<R66FiniteDualStates> state;
/**
* Business Object if used
*/
private R66BusinessInterface businessObject = null;
/**
* Extended protocol or not
*/
private boolean extendedProtocol = Configuration.configuration.isExtendedProtocol();
private final HashMap<String, R66Dir> dirsFromSession = new HashMap<String, R66Dir>();
/**
* Create the session
*/
public R66Session() {
isReady = false;
auth = new R66Auth(this);
dir = new R66Dir(this);
restart = new R66Restart(this);
state = R66FiniteDualStates.newSessionMachineState();
}
/**
* @return extendedProtocol
*/
public boolean getExtendedProtocol() {
return extendedProtocol;
}
/**
* @return the businessObject
*/
public R66BusinessInterface getBusinessObject() {
return businessObject;
}
/**
* @param businessObject
* the businessObject to set
*/
public void setBusinessObject(R66BusinessInterface businessObject) {
this.businessObject = businessObject;
}
/**
* Propose a new State
*
* @param desiredstate
* @throws IllegalFiniteStateException
* if the new status if not ok
*/
public void newState(R66FiniteDualStates desiredstate) {
try {
state.setCurrent(desiredstate);
} catch (IllegalFiniteStateException e) {
logger.warn("Should not changed of State: {} {}", this, e.getMessage());
state.setDryCurrent(desiredstate);
}
}
/**
*
* @return the current state in the finite state machine
*/
public R66FiniteDualStates getState() {
return state.getCurrent();
}
/**
* Debugging purpose
*
* @param stat
*/
public void setStatus(int stat) {
StackTraceElement elt = Thread.currentThread().getStackTrace()[2];
this.status = "(" + elt.getFileName() + ":" + elt.getLineNumber() + "):" + stat;
}
public void clear() {
// First check if a transfer was on going
if (runner != null && (!runner.isFinished()) && (!runner.continueTransfer())) {
if (localChannelReference != null) {
if (!localChannelReference.getFutureRequest().isDone()) {
R66Result result = new R66Result(new OpenR66RunnerErrorException(
"Close before ending"), this, true,
ErrorCode.Disconnection, runner);// True since called from closed
result.setRunner(runner);
try {
setFinalizeTransfer(false, result);
} catch (OpenR66RunnerErrorException e) {
} catch (OpenR66ProtocolSystemException e) {
}
}
}
}
if (dir != null) {
dir.clear();
}
if (auth != null) {
auth.clear();
}
if (runner != null) {
runner.clear();
}
if (state != null) {
try {
state.setCurrent(R66FiniteDualStates.CLOSEDCHANNEL);
} catch (IllegalFiniteStateException e) {
}
// R66FiniteDualStates.endSessionMachineSate(state);
}
// No clean of file since it can be used after channel is closed
isReady = false;
if (businessObject != null) {
businessObject.releaseResources(this);
businessObject = null;
}
}
public void partialClear() {
// First check if a transfer was on going
if (runner != null && (!runner.isFinished()) && (!runner.continueTransfer())) {
if (localChannelReference != null) {
if (!localChannelReference.getFutureRequest().isDone()) {
R66Result result = new R66Result(new OpenR66RunnerErrorException(
"Close before ending"), this, true,
ErrorCode.Disconnection, runner);// True since called from closed
result.setRunner(runner);
try {
setFinalizeTransfer(false, result);
} catch (OpenR66RunnerErrorException e) {
} catch (OpenR66ProtocolSystemException e) {
}
}
}
}
/*
if (dir != null) {
dir.clear();
}
if (auth != null) {
auth.clear();
}
if (runner != null) {
runner.clear();
}
*/
// No clean of file since it can be used after channel is closed
isReady = false;
if (businessObject != null) {
businessObject.releaseResources(this);
businessObject = null;
}
}
public R66Auth getAuth() {
return auth;
}
public int getBlockSize() {
return blockSize;
}
/**
* @param blocksize
* the blocksize to set
*/
public void setBlockSize(int blocksize) {
blockSize = blocksize;
}
public R66Dir getDir() {
return dir;
}
public FilesystemBasedFileParameterImpl getFileParameter() {
return Configuration.getFileParameter();
}
public R66Restart getRestart() {
return restart;
}
/**
*
* @return True if the connection is currently authenticated
*/
public boolean isAuthenticated() {
if (auth == null) {
return false;
}
return auth.isIdentified();
}
/**
* @return True if the Channel is ready to accept transfer
*/
public boolean isReady() {
return isReady;
}
/**
* @param isReady
* the isReady for transfer to set
*/
public void setReady(boolean isReady) {
this.isReady = isReady;
}
/**
* @return the runner
*/
public DbTaskRunner getRunner() {
return runner;
}
/**
* @param localChannelReference
* the localChannelReference to set
*/
public void setLocalChannelReference(
LocalChannelReference localChannelReference) {
this.localChannelReference = localChannelReference;
this.localChannelReference.setSession(this);
if (this.localChannelReference.getNetworkChannel() != null) {
this.raddress = this.localChannelReference.getNetworkChannel().remoteAddress();
this.laddress = this.localChannelReference.getNetworkChannel().localAddress();
} else {
this.raddress = this.laddress = new InetSocketAddress(0);
}
}
/**
*
* @return the remote SocketAddress
*/
public SocketAddress getRemoteAddress() {
return this.raddress;
}
/**
*
* @return the local SocketAddress
*/
public SocketAddress getLocalAddress() {
return this.laddress;
}
/**
* @return the localChannelReference
*/
public LocalChannelReference getLocalChannelReference() {
return localChannelReference;
}
/**
* To be called in case of No Session not from a valid LocalChannelHandler
*
* @param runner
* @param localChannelReference
*/
public void setNoSessionRunner(DbTaskRunner runner, LocalChannelReference localChannelReference) {
this.runner = runner;
// Warning: the file is not correctly setup
try {
file = (R66File) dir.setFile(this.runner.getFilename(),
false);
} catch (CommandAbstractException e1) {
}
this.auth.specialNoSessionAuth(false, Configuration.configuration.getHOST_ID());
this.localChannelReference = localChannelReference;
if (this.localChannelReference == null) {
if (this.runner.getLocalChannelReference() != null) {
this.localChannelReference = this.runner.getLocalChannelReference();
} else {
this.localChannelReference = new LocalChannelReference();
}
this.localChannelReference.setErrorMessage(this.runner.getErrorInfo().mesg,
this.runner.getErrorInfo());
}
runner.setLocalChannelReference(this.localChannelReference);
this.localChannelReference.setSession(this);
}
/**
* Set the File from the runner before PRE operation are done
*
* @throws OpenR66RunnerErrorException
*/
public void setFileBeforePreRunner() throws OpenR66RunnerErrorException {
// check first if the next step is the PRE task from beginning
try {
file = FileUtils.getFile(logger, this, this.runner.getOriginalFilename(),
this.runner.isPreTaskStarting(), this.runner.isSender(),
this.runner.isSendThrough(), file);
} catch (OpenR66RunnerErrorException e) {
this.runner.setErrorExecutionStatus(ErrorCode.FileNotFound);
throw e;
}
if (this.runner.isSender() && !runner.isSendThrough()) {
// possibly resolved filename
try {
runner.setOriginalFilename(file.getFile());
runner.setFilename(file.getFile());
logger.debug("Old size: " + runner.getOriginalSize() + " => " + file.length());
if (runner.getOriginalSize() <= 0) {
long originalSize = file.length();
if (originalSize > 0) {
this.runner.setOriginalSize(originalSize);
}
}
} catch (CommandAbstractException e) {
throw new OpenR66RunnerErrorException(e);
}
}
}
/**
* Set the File from the runner once PRE operation are done
*
* @param createFile
* When True, the file can be newly created if needed. If False, no new file will be
* created, thus having an Exception.
* @throws OpenR66RunnerErrorException
* @throws CommandAbstractException
* only when new received created file cannot be created
*/
public void setFileAfterPreRunner(boolean createFile) throws OpenR66RunnerErrorException, CommandAbstractException {
if (this.businessObject != null) {
this.businessObject.checkAtChangeFilename(this);
}
// Now create the associated file
if (this.runner.isSender()) {
try {
if (file == null) {
try {
file = (R66File) dir.setFile(this.runner.getFilename(),
false);
} catch (CommandAbstractException e) {
// file is not under normal base directory, so is external
// File must already exist but can be using special code ('*?')
file = dir.setFileNoCheck(this.runner.getFilename());
// file = new R66File(this, dir, this.runner.getFilename());
}
}
if (runner.isSendThrough()) {
// no test on file since it does not really exist
logger.debug("File is in through mode: {}", file);
} else if (!file.canRead()) {
// file is not under normal base directory, so is external
// File must already exist but cannot used special code ('*?')
file = new R66File(this, dir, this.runner.getFilename());
if (!file.canRead()) {
this.runner.setErrorExecutionStatus(ErrorCode.FileNotFound);
throw new OpenR66RunnerErrorException("File cannot be read: " +
file.getTrueFile().getAbsolutePath());
}
}
} catch (CommandAbstractException e) {
throw new OpenR66RunnerErrorException(e);
}
} else {
// File should not exist except if restart
if (runner.getRank() > 0) {
// Filename should be get back from runner load from database
try {
file = (R66File) dir.setFile(this.runner
.getFilename(), true);
if (runner.isRecvThrough()) {
// no test on file since it does not really exist
logger.debug("File is in through mode: {}", file);
} else if (!file.canWrite()) {
throw new OpenR66RunnerErrorException(
"File cannot be write");
}
} catch (CommandAbstractException e) {
throw new OpenR66RunnerErrorException(e);
}
} else {
// New FILENAME if necessary and store it
if (createFile) {
file = null;
String newfilename = this.runner.getOriginalFilename();
if (newfilename.charAt(1) == ':') {
// Windows path
newfilename = newfilename.substring(2);
}
newfilename = R66File.getBasename(newfilename);
try {
file = dir.setUniqueFile(this.runner.getSpecialId(),
newfilename);
this.runner.setFilename(file.getBasename());
} catch (CommandAbstractException e) {
this.runner.deleteTempFile();
throw e;
}
try {
if (runner.isRecvThrough()) {
// no test on file since it does not really exist
logger.debug("File is in through mode: {}", file);
this.runner.deleteTempFile();
} else if (!file.canWrite()) {
this.runner.deleteTempFile();
throw new OpenR66RunnerErrorException(
"File cannot be write");
}
} catch (CommandAbstractException e) {
this.runner.deleteTempFile();
throw new OpenR66RunnerErrorException(e);
}
} else {
throw new OpenR66RunnerErrorException("No file created");
}
}
}
// Store TRUEFILENAME
try {
if (this.runner.isFileMoved()) {
this.runner.setFileMoved(file.getFile(), true);
} else {
this.runner.setFilename(file.getFile());
}
} catch (CommandAbstractException e) {
this.runner.deleteTempFile();
throw new OpenR66RunnerErrorException(e);
}
// check fileSize
if (runner.isSender() && file != null) {
logger.debug("could change size: " + this.runner.getOriginalSize() + " => " + file.length());
if (this.runner.getOriginalSize() < 0) {
long originalSize = file.length();
if (originalSize > 0) {
this.runner.setOriginalSize(originalSize);
}
}
}
}
/**
* To be used when a request comes with a bad code so it cannot be set normally
*
* @param runner
* @param code
*/
public void setBadRunner(DbTaskRunner runner, ErrorCode code) {
this.runner = runner;
if (code == ErrorCode.QueryAlreadyFinished) {
if (this.runner.isSender()) {
// Change dir
try {
dir.changeDirectory(this.runner.getRule().getSendPath());
} catch (CommandAbstractException e) {
}
} else {
// Change dir
try {
dir.changeDirectory(this.runner.getRule().getWorkPath());
} catch (CommandAbstractException e) {
}
}
if (this.businessObject != null) {
this.businessObject.checkAtError(this);
}
this.runner.setPostTask();
try {
setFileAfterPreRunner(false);
} catch (OpenR66RunnerErrorException e) {
} catch (CommandAbstractException e) {
}
}
}
/**
* Set the runner, and setup the directory first.
*
* This call should be followed by a startup() call.
*
* @param runner
* the runner to set
* @throws OpenR66RunnerErrorException
*/
public void setRunner(DbTaskRunner runner)
throws OpenR66RunnerErrorException {
this.runner = runner;
logger.debug("Runner to set: {} {}", runner.shallIgnoreSave(), runner);
this.runner.checkThroughMode();
if (this.businessObject != null) {
this.businessObject.checkAtStartup(this);
}
if (this.runner.isSender()) {
if (runner.isSendThrough()) {
// May not change dir as needed
// Change dir
try {
dir.changeDirectory(this.runner.getRule().getSendPath());
} catch (CommandAbstractException e) {
// ignore
}
} else {
// Change dir
try {
dir.changeDirectory(this.runner.getRule().getSendPath());
} catch (CommandAbstractException e) {
throw new OpenR66RunnerErrorException(e);
}
}
} else {
if (runner.isRecvThrough()) {
// May not change dir as needed
// Change dir
try {
dir.changeDirectory(this.runner.getRule().getWorkPath());
} catch (CommandAbstractException e) {
}
} else {
// Change dir
try {
dir.changeDirectory(this.runner.getRule().getWorkPath());
} catch (CommandAbstractException e) {
throw new OpenR66RunnerErrorException(e);
}
}
}
logger.debug("Dir is: " + dir.getFullPath());
}
/**
* START from the PreTask if necessary, and prepare the file
*
* @param checkNotExternal
* if True, the file as Sender should not be external to current directory
* @throws OpenR66RunnerErrorException
*/
public void startup(boolean checkNotExternal) throws OpenR66RunnerErrorException {
if (runner.getRank() > 0) {
logger.debug("restart at " + runner.getRank() + " {}", runner);
logger.debug("restart at " + runner.getRank() + " {}", dir);
runner.setTransferTask(runner.getRank());
restart.restartMarker(runner.getBlocksize() * runner.getRank());
} else {
restart.restartMarker(0);
}
logger.debug("GlobalLastStep: " + runner.getGloballaststep() + " vs " + TASKSTEP.NOTASK.ordinal() + ":"
+ TASKSTEP.PRETASK.ordinal());
if (runner.getGloballaststep() == TASKSTEP.NOTASK.ordinal() ||
runner.getGloballaststep() == TASKSTEP.PRETASK.ordinal()) {
setFileBeforePreRunner();
if (runner.isSender() && !runner.isSendThrough() && file != null && checkNotExternal) {
String path = null;
try {
path = file.getFile();
} catch (CommandAbstractException e1) {
}
if (file.isExternal() || (path != null && !dir.isPathInCurrentDir(path))) {
// should not be
logger.error("File cannot be found in the current output directory: {} not in {}", file, dir);
this.runner.setErrorExecutionStatus(ErrorCode.FileNotAllowed);
throw new OpenR66RunnerErrorException("File cannot be found in the current output directory");
}
}
this.runner.setPreTask();
runner.saveStatus();
this.runner.run();
if (runner.isSender() && !runner.isSendThrough()) {
if (file != null) {
try {
long originalSize = file.length();
if (originalSize > 0) {
this.runner.setOriginalSize(originalSize);
}
} catch (CommandAbstractException e) {
// ignore
}
}
}
runner.saveStatus();
runner.setTransferTask(runner.getRank());
} else {
runner.reset();
runner.changeUpdatedInfo(UpdatedInfo.RUNNING);
runner.saveStatus();
}
// Now create the associated file
try {
setFileAfterPreRunner(true);
} catch (CommandAbstractException e2) {
// generated due to a possible wildcard not ready
file = null;
}
logger.debug("GlobalLastStep: " + runner.getGloballaststep());
if (runner.getGloballaststep() == TASKSTEP.TRANSFERTASK.ordinal()) {
if (this.businessObject != null) {
this.businessObject.checkAfterPreCommand(this);
}
if (!this.runner.isSender()) {
// Check file length according to rank
if (runner.isRecvThrough()) {
// no size can be checked
} else {
long length = 0;
if (file != null) {
try {
length = file.length();
} catch (CommandAbstractException e) {
}
}
long needed = this.runner.getOriginalSize() - length;
long available = 0;
String targetDir = null;
try {
available = this.dir.getFreeSpace();
targetDir = this.dir.getPwd();
} catch (CommandAbstractException e1) {
}
if (file != null) {
File truefile = file.getTrueFile().getParentFile();
available = truefile.getFreeSpace();
targetDir = truefile.getPath();
}
logger.debug("Check available space: " + available + " >? " + needed + "(+" + length + ")");
// Available > 0 since some system returns 0 (wrong size)
if (available > 0 && needed > available) {
// not enough space
this.runner.setErrorExecutionStatus(ErrorCode.Internal);
throw new OpenR66RunnerErrorException(
"File cannot be written due to unsufficient space available: " +
targetDir + " need " + needed + " more while available is " + available);
}
if (file == null) {
this.runner.saveStatus();
logger.info("Final PARTIAL init: {}", this.runner);
return;
}
// First check available space
try {
long oldPosition = restart.getPosition();
restart.setSet(true);
if (oldPosition > length) {
int newRank = ((int) (length / this.runner.getBlocksize()))
- Configuration.getRANKRESTART();
if (newRank <= 0) {
newRank = 1;
}
logger.info("OldPos: " + oldPosition + ":" + runner.getRank() +
" curLength: " + length + ":" + newRank);
logger.warn("Decreased Rank Restart for {} at " + newRank, runner);
runner.setTransferTask(newRank);
restart.restartMarker(this.runner.getBlocksize()
* this.runner.getRank());
}
try {
file.restartMarker(restart);
} catch (CommandAbstractException e) {
this.runner.deleteTempFile();
throw new OpenR66RunnerErrorException(e);
}
} catch (NoRestartException e) {
// length is not to be changed
}
}
} else {
try {
this.localChannelReference.getFutureRequest().setFilesize(file.length());
} catch (CommandAbstractException e1) {
}
try {
file.restartMarker(restart);
} catch (CommandAbstractException e) {
this.runner.deleteTempFile();
throw new OpenR66RunnerErrorException(e);
}
}
}
this.runner.saveStatus();
logger.debug("Final init: {} {}", this.runner, this.file != null);
}
/**
* Rename the current receive file from the very beginning since the sender has a post action
* that changes its name
*
* @param newFilename
* @throws OpenR66RunnerErrorException
*/
public void renameReceiverFile(String newFilename) throws OpenR66RunnerErrorException {
if (runner == null) {
return;
}
// First delete the temporary file if needed
if (runner.getRank() > 0) {
logger.error("Renaming file is not correct since transfer does not start from first block");
// Not correct
throw new OpenR66RunnerErrorException(
"Renaming file not correct since transfer already started");
}
if (!runner.isRecvThrough()) {
this.runner.deleteTempFile();
}
// Now rename it
this.runner.setOriginalFilename(newFilename);
try {
this.setFileAfterPreRunner(true);
} catch (CommandAbstractException e) {
throw new OpenR66RunnerErrorException(e);
}
this.runner.saveStatus();
}
/**
* Finalize the transfer step by running the error or post operation according to the status.
*
* @param status
* @param finalValue
* @throws OpenR66RunnerErrorException
* @throws OpenR66ProtocolSystemException
*/
public void setFinalizeTransfer(boolean status, R66Result finalValue)
throws OpenR66RunnerErrorException, OpenR66ProtocolSystemException {
logger.debug(status + ":" + finalValue + ":" + runner);
if (runner == null) {
if (localChannelReference != null) {
if (status) {
localChannelReference.validateRequest(finalValue);
} else {
localChannelReference.invalidateRequest(finalValue);
}
}
if (this.businessObject != null) {
if (status) {
this.businessObject.checkAfterTransfer(this);
} else {
this.businessObject.checkAtError(this);
}
}
return;
}
if (this.businessObject != null) {
if (status) {
this.businessObject.checkAfterTransfer(this);
} else {
this.businessObject.checkAtError(this);
}
}
if (runner.isAllDone()) {
logger.debug(
"Transfer already done but " + status + " on " + file + runner.toShortString(),
new OpenR66RunnerErrorException(finalValue.toString()));
// FIXME ??
/*
* if (! status) runner.finalizeTransfer(localChannelReference, file, finalValue,
* status);
*/
return;
}
if (localChannelReference.getFutureRequest().isDone()) {
logger.debug(
"Request already done but " + status + " on " + file + runner.toShortString(),
new OpenR66RunnerErrorException(finalValue.toString()));
// Already finished once so do nothing more
return;
}
if (!status) {
this.runner.deleteTempFile();
runner.setErrorExecutionStatus(finalValue.getCode());
}
if (status) {
runner.finishTransferTask(ErrorCode.TransferOk);
} else {
runner.finishTransferTask(finalValue.getCode());
}
runner.saveStatus();
logger.debug("Transfer " + status + " on {} and {}", file, runner);
if (!runner.ready()) {
// Pre task in error (or even before)
OpenR66RunnerErrorException runnerErrorException;
if (!status && finalValue.getException() != null) {
runnerErrorException = new OpenR66RunnerErrorException(
"Pre task in error (or even before)",
finalValue.getException());
} else {
runnerErrorException = new OpenR66RunnerErrorException(
"Pre task in error (or even before)");
}
finalValue.setException(runnerErrorException);
logger.debug("Pre task in error (or even before) : " +
runnerErrorException.getMessage());
if (Configuration.configuration.isExecuteErrorBeforeTransferAllowed()) {
runner.finalizeTransfer(localChannelReference, file, finalValue, status);
}
localChannelReference.invalidateRequest(finalValue);
throw runnerErrorException;
}
try {
if (file != null) {
file.closeFile();
}
} catch (CommandAbstractException e1) {
R66Result result = finalValue;
if (status) {
result = new R66Result(new OpenR66RunnerErrorException(e1),
this, false, ErrorCode.Internal, runner);
}
localChannelReference.invalidateRequest(result);
throw (OpenR66RunnerErrorException) result.getException();
}
runner.finalizeTransfer(localChannelReference, file, finalValue, status);
if (this.businessObject != null) {
this.businessObject.checkAfterPost(this);
}
}
/**
* Try to finalize the request if possible
*
* @param errorValue
* @throws OpenR66RunnerErrorException
* @throws OpenR66ProtocolSystemException
*/
public void tryFinalizeRequest(R66Result errorValue)
throws OpenR66RunnerErrorException, OpenR66ProtocolSystemException {
if (this.getLocalChannelReference() == null) {
return;
}
if (this.getLocalChannelReference().getFutureRequest().isDone()) {
return;
}
// setRunnerFromLocalChannelReference(localChannelReference);
if (runner == null) {
localChannelReference.invalidateRequest(errorValue);
return;
}
// do the real end
if (runner.getStatus() == ErrorCode.CompleteOk) {
// status = true;
runner.setAllDone();
runner.forceSaveStatus();
localChannelReference.validateRequest(
new R66Result(this, true, ErrorCode.CompleteOk, runner));
} else if (runner.getStatus() == ErrorCode.TransferOk &&
((!runner.isSender()) || errorValue.getCode() == ErrorCode.QueryAlreadyFinished)) {
// Try to finalize it
// status = true;
try {
this.setFinalizeTransfer(true,
new R66Result(this, true, ErrorCode.CompleteOk, runner));
localChannelReference.validateRequest(
localChannelReference.getFutureEndTransfer().getResult());
} catch (OpenR66ProtocolSystemException e) {
logger.error("Cannot validate runner: {}", runner.toShortString());
runner.changeUpdatedInfo(UpdatedInfo.INERROR);
runner.setErrorExecutionStatus(errorValue.getCode());
runner.forceSaveStatus();
this.setFinalizeTransfer(false, errorValue);
} catch (OpenR66RunnerErrorException e) {
logger.error("Cannot validate runner: {}", runner.toShortString());
runner.changeUpdatedInfo(UpdatedInfo.INERROR);
runner.setErrorExecutionStatus(errorValue.getCode());
runner.forceSaveStatus();
this.setFinalizeTransfer(false, errorValue);
}
} else {
// invalidate Request
this.setFinalizeTransfer(false, errorValue);
}
}
/**
* @return the file
*/
public R66File getFile() {
return file;
}
/**
*
* @return True if the number of Error is still acceptable
*/
public boolean addError() {
numOfError++;
return (numOfError < Configuration.RETRYNB);
}
@Override
public String toString() {
return "Session: FS[" + state.getCurrent() + "] " + status + " " +
(auth != null ? auth.toString() : "no Auth") + " " +
(dir != null ? dir.toString() : "no Dir") + " " +
(file != null ? file.toString() : "no File") + " " +
(runner != null ? runner.toShortString() : "no Runner");
}
public String getUniqueExtension() {
return Configuration.EXT_R66;
}
/**
* @return the dirsFromSession
*/
public HashMap<String, R66Dir> getDirsFromSession() {
return dirsFromSession;
}
}