FileUtils.java
/*
* This file is part of Waarp Project (named also Waarp or GG).
*
* Copyright (c) 2019, Waarp SAS, 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.protocol.utils;
import org.waarp.common.command.exception.CommandAbstractException;
import org.waarp.common.digest.FilesystemBasedDigest;
import org.waarp.common.digest.FilesystemBasedDigest.DigestAlgo;
import org.waarp.common.file.AbstractDir;
import org.waarp.common.logging.WaarpLogger;
import org.waarp.openr66.context.R66Session;
import org.waarp.openr66.context.filesystem.R66File;
import org.waarp.openr66.context.task.exception.OpenR66RunnerErrorException;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
/**
* File Utils
*/
public final class FileUtils {
private static final byte[] EMPTY_ARRAY = {};
private FileUtils() {
}
/**
* Change or create the R66File associated with the context
*
* @param logger
* @param session
* @param filenameSrc new filename
* @param isPreStart
* @param isSender
* @param isThrough
* @param file old R66File if any (might be null)
*
* @return the R66File
*
* @throws OpenR66RunnerErrorException
*/
public static R66File getFile(final WaarpLogger logger,
final R66Session session,
final String filenameSrc,
final boolean isPreStart,
final boolean isSender, final boolean isThrough,
R66File file)
throws OpenR66RunnerErrorException {
String filename;
logger.debug("PreStart: {}", isPreStart);
logger.debug("Dir is: {}", session.getDir().getFullPath());
logger.debug("File is: {}", filenameSrc);
if (isPreStart) {
filename = AbstractDir.normalizePath(filenameSrc);
filename = AbstractDir.pathFromURI(filename);
logger.debug("File becomes: {}", filename);
} else {
filename = filenameSrc;
}
if (isSender) {
try {
if (file == null) {
try {
file = (R66File) session.getDir().setFile(filename, false);
} catch (final CommandAbstractException e) {
logger.warn("File not placed in normal directory" + " : {}",
e.getMessage());
// file is not under normal base directory, so is external
// File should already exist but can be using special code ('*?')
file = session.getDir().setFileNoCheck(filename);
}
}
if (isThrough) {
// no test on file since it does not really exist
logger.debug("File is in through mode: {}", file);
} else if (!file.canRead()) {
logger.debug(
"File {} cannot be read, so try external from " + filename, file);
// file is not under normal base directory, so is external
// File should already exist but cannot use special code ('*?')
final R66File file2 =
new R66File(session, session.getDir(), filename);
if (!file2.canRead()) {
throw new OpenR66RunnerErrorException(
"File cannot be read: " + file.getTrueFile().getAbsolutePath());
}
file = file2;
}
} catch (final CommandAbstractException e) {
throw new OpenR66RunnerErrorException(e);
}
} else {
// not sender so file is just registered as is but no test of existence
file = new R66File(session, session.getDir(), filename);
}
return file;
}
/**
* @param buffer
* @param size
* @param algo for packet only
* @param digestGlobal
*
* @return the hash from the given Buffer
*/
public static byte[] getHash(final byte[] buffer, final int size,
final DigestAlgo algo,
final FilesystemBasedDigest digestGlobal) {
if (buffer == null || size == 0) {
return EMPTY_ARRAY;
}
final byte[] newkey;
try {
if (digestGlobal == null) {
newkey = FilesystemBasedDigest.getHash(buffer, size, algo);
} else {
final FilesystemBasedDigest digestPacket =
new FilesystemBasedDigest(algo);
digestPacket.Update(buffer, 0, size);
newkey = digestPacket.Final();
digestGlobal.Update(buffer, 0, size);
}
} catch (final IOException e) {
return EMPTY_ARRAY;
} catch (final NoSuchAlgorithmException e) {
return EMPTY_ARRAY;
}
return newkey;
}
/**
* Compute global hash and local hash (if possible)
*
* @param digestGlobal
* @param digestLocal
* @param buffer
* @param size size of the buffer
*/
public static void computeGlobalHash(final FilesystemBasedDigest digestGlobal,
final FilesystemBasedDigest digestLocal,
final byte[] buffer, final int size) {
if (buffer == null || size == 0) {
return;
}
if (digestGlobal != null) {
digestGlobal.Update(buffer, 0, size);
}
if (digestLocal != null) {
digestLocal.Update(buffer, 0, size);
}
}
}