All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.tcdng.unify.jcifs.server.JcifsFileTransferServer Maven / Gradle / Ivy

There is a newer version: 2.1.64
Show newest version
/*
 * Copyright 2018-2024 The Code Department.
 * 
 * Licensed 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 com.tcdng.unify.jcifs.server;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import jcifs.smb.NtlmPasswordAuthentication;
import jcifs.smb.SmbException;
import jcifs.smb.SmbFile;
import jcifs.smb.SmbFileFilter;
import jcifs.smb.SmbFileInputStream;
import jcifs.smb.SmbFileOutputStream;

import com.tcdng.unify.core.UnifyException;
import com.tcdng.unify.core.annotation.Component;
import com.tcdng.unify.core.annotation.Configurable;
import com.tcdng.unify.core.file.AbstractFileTransferServer;
import com.tcdng.unify.core.file.FileInfo;
import com.tcdng.unify.core.file.FileFilter;
import com.tcdng.unify.core.file.FileTransferSetup;
import com.tcdng.unify.core.util.IOUtils;
import com.tcdng.unify.jcifs.JCIFSApplicationComponents;

/**
 * File transfer server based on JCIFS.
 * 
 * @author The Code Department
 * @since 1.0
 */
@Component(name = JCIFSApplicationComponents.JCIFS_TRANSFERSERVER, description = "JCIFS (Windows SMB)")
public class JcifsFileTransferServer extends AbstractFileTransferServer {

    @Configurable("8192")
    private int bufferSize;

    @Override
    public List getRemoteFileList(FileTransferSetup fileTransferSetup) throws UnifyException {
        List list = Collections.emptyList();
        try {
            SmbFile smbFile = getSmbFile(fileTransferSetup, null);
            SmbFile[] files = smbFile.listFiles(new SMBFileFilter(fileTransferSetup));
            if (files != null && files.length > 0) {
                list = new ArrayList();
                for (SmbFile file : files) {
                    String name = file.getName();
                    if (name.endsWith("/") || name.endsWith("\\")) {
                        name = name.substring(0, name.length() - 1);
                    }
                    list.add(new FileInfo(name, file.getCanonicalPath(), file.length(), file.createTime(),
                            file.lastModified(), file.isFile(), file.isHidden()));
                }
            }
        } catch (UnifyException e) {
            throw e;
        } catch (Exception e) {
            throwOperationErrorException(e);
        }
        return list;
    }

    @Override
    public boolean remoteDirectoryExists(FileTransferSetup fileTransferSetup) throws UnifyException {
        try {
            SmbFile smbFile = getSmbFile(fileTransferSetup, null);
            return smbFile.exists() && smbFile.isDirectory();
        } catch (UnifyException e) {
            throw e;
        } catch (Exception e) {
            throwOperationErrorException(e);
        }
        return false;
    }

    @Override
    public boolean remoteFileExists(FileTransferSetup fileTransferSetup, String serverFile) throws UnifyException {
        try {
            SmbFile smbFile = getSmbFile(fileTransferSetup, serverFile);
            return smbFile.exists() && smbFile.isFile();
        } catch (UnifyException e) {
            throw e;
        } catch (Exception e) {
            throwOperationErrorException(e);
        }
        return false;
    }

    @Override
    public void createRemoteDirectory(FileTransferSetup fileTransferSetup) throws UnifyException {
        createRemoteDirectories(getSmbFile(fileTransferSetup, null));
    }

    @Override
    public void createRemoteFile(FileTransferSetup fileTransferSetup, String serverFile) throws UnifyException {
        SmbFileOutputStream smbFileOutputStream = null;
        try {
            SmbFile smbFile = getSmbFile(fileTransferSetup, serverFile);
            smbFileOutputStream = new SmbFileOutputStream(smbFile);
        } catch (UnifyException e) {
            throw e;
        } catch (Exception e) {
            throwOperationErrorException(e);
        } finally {
            IOUtils.close(smbFileOutputStream);
        }
    }

    @Override
    public void deleteRemoteFile(FileTransferSetup fileTransferSetup, String serverFile) throws UnifyException {
        try {
            SmbFile smbFile = getSmbFile(fileTransferSetup, serverFile);
            smbFile.delete();
        } catch (UnifyException e) {
            throw e;
        } catch (Exception e) {
            throwOperationErrorException(e);
        }
    }

    @Override
    public byte[] readRemoteBlock(FileTransferSetup fileTransferSetup, String serverFile, long index, int size)
            throws UnifyException {
        byte[] block = null;
        SmbFileInputStream smbFileInputStream = null;
        try {
            // Prepare remote file stream
            SmbFile smbFile = getSmbFile(fileTransferSetup, serverFile);
            smbFileInputStream = new SmbFileInputStream(smbFile);
            smbFileInputStream.skip(index);

            // Read block
            block = new byte[size];
            IOUtils.read(block, smbFileInputStream);
        } catch (UnifyException e) {
            throw e;
        } catch (Exception e) {
            throwOperationErrorException(e);
        } finally {
            IOUtils.close(smbFileInputStream);
        }
        return block;
    }

    @Override
    public void uploadFile(FileTransferSetup fileTransferSetup, String serverFile, String localFile)
            throws UnifyException {
        SmbFile remoteSmbFile = getSmbFile(fileTransferSetup, serverFile);
        File actLocalFile = getLocalFile(fileTransferSetup, localFile);
        uploadFile(remoteSmbFile, actLocalFile, fileTransferSetup.isDeleteSourceOnTransfer());
    }

    @Override
    public void uploadFiles(FileTransferSetup fileTransferSetup) throws UnifyException {
        String remotePath = getNormalizedRemotePath(fileTransferSetup);
        NtlmPasswordAuthentication auth = getAuthentication(fileTransferSetup);
        File localDir = new File(getNormalizedLocalPath(fileTransferSetup));
        FileFilter fileFilter = new FileFilter(fileTransferSetup);
        uploadFiles(fileTransferSetup, auth, remotePath, localDir, fileFilter);
    }

    @Override
    public void downloadFile(FileTransferSetup fileTransferSetup, String serverFile, String localFile)
            throws UnifyException {
        SmbFile remoteSmbFile = getSmbFile(fileTransferSetup, serverFile);
        File actLocalFile = getLocalFile(fileTransferSetup, localFile);
        downloadFile(remoteSmbFile, actLocalFile, fileTransferSetup.isDeleteSourceOnTransfer());
    }

    @Override
    public void downloadFiles(FileTransferSetup fileTransferSetup) throws UnifyException {
        String remotePath = getNormalizedRemotePath(fileTransferSetup);
        NtlmPasswordAuthentication auth = getAuthentication(fileTransferSetup);
        File localDir = new File(getNormalizedLocalPath(fileTransferSetup));
        SMBFileFilter smbFileFilter = new SMBFileFilter(fileTransferSetup);
        downloadFiles(fileTransferSetup, auth, remotePath, localDir, smbFileFilter);
    }

    private void uploadFiles(FileTransferSetup fileTransferSetup, NtlmPasswordAuthentication auth, String remotePath,
            File localDir, FileFilter fileFilter) throws UnifyException {
        SmbFile remoteFile = getSmbFile(fileTransferSetup, auth, remotePath, null);
        createRemoteDirectories(remoteFile);
        File[] files = localDir.listFiles(fileFilter);
        for (File file : files) {
            if (file.isDirectory()) {
                String newRemotePath = remotePath + file.getName() + '/';
                uploadFiles(fileTransferSetup, auth, newRemotePath, file, fileFilter);
            } else {
                SmbFile remoteSmbFile = getSmbFile(fileTransferSetup, auth, remotePath, file.getName());
                uploadFile(remoteSmbFile, file, fileTransferSetup.isDeleteSourceOnTransfer());
            }
        }
    }

    private void uploadFile(SmbFile remoteSmbFile, File localFile, boolean deleteSourceOnTransfer)
            throws UnifyException {
        SmbFileOutputStream smbFileOutputStream = null;
        FileInputStream fileInputStream = null;
        try {
            logDebug("Upload: [File: {0}]", localFile.getName());
            smbFileOutputStream = new SmbFileOutputStream(remoteSmbFile);
            fileInputStream = new FileInputStream(localFile);

            // Upload
            byte[] buffer = new byte[bufferSize];
            int read = 0;
            while ((read = fileInputStream.read(buffer)) >= 0) {
                smbFileOutputStream.write(buffer, 0, read);
                logDebug("Upload: [Data: {0}]", read);
            }
            logDebug("Upload: [Status: SENT ]");

            if (deleteSourceOnTransfer) {
                IOUtils.close(fileInputStream);
                localFile.delete();
                logDebug("Local file deleted.");
            }
        } catch (Exception e) {
            throwOperationErrorException(e);
        } finally {
            IOUtils.close(smbFileOutputStream);
            IOUtils.close(fileInputStream);
        }
    }

    private void downloadFiles(FileTransferSetup fileTransferSetup, NtlmPasswordAuthentication auth, String remotePath,
            File localDir, SMBFileFilter smbFileFilter) throws UnifyException {
        try {
            localDir.mkdirs();
            SmbFile remoteFile = getSmbFile(fileTransferSetup, auth, remotePath, null);
            SmbFile[] files = remoteFile.listFiles(smbFileFilter);
            for (SmbFile file : files) {
                File localFile = new File(getNormalizedLocalPath(localDir.getAbsolutePath()) + file.getName());
                if (file.isDirectory()) {
                    String newRemotePath = remotePath + file.getName() + '/';
                    downloadFiles(fileTransferSetup, auth, newRemotePath, localFile, smbFileFilter);
                } else {
                    SmbFile actRemoteFile = getSmbFile(fileTransferSetup, auth, remotePath, file.getName());
                    downloadFile(actRemoteFile, localFile, fileTransferSetup.isDeleteSourceOnTransfer());
                }
            }
        } catch (IOException e) {
            throwOperationErrorException(e);
        }
    }

    private void downloadFile(SmbFile remoteSmbFile, File localFile, boolean deleteSourceOnTransfer)
            throws UnifyException {
        SmbFileInputStream smbFileInputStream = null;
        FileOutputStream fileOutputStream = null;
        try {
            logDebug("Download: [File: {0}]", localFile);
            fileOutputStream = new FileOutputStream(localFile);
            smbFileInputStream = new SmbFileInputStream(remoteSmbFile);

            // Download
            byte[] buffer = new byte[bufferSize];
            int read = 0;
            while ((read = smbFileInputStream.read(buffer)) >= 0) {
                fileOutputStream.write(buffer, 0, read);
                logDebug("Download: [Data: {0}]", read);
            }
            logDebug("Download: [Status: RECEIVED ]");

            if (deleteSourceOnTransfer) {
                IOUtils.close(smbFileInputStream);
                remoteSmbFile.delete();
                logDebug("Remote file deleted.");
            }
        } catch (Exception e) {
            throwOperationErrorException(e);
        } finally {
            IOUtils.close(fileOutputStream);
            IOUtils.close(smbFileInputStream);
        }
    }

    private void createRemoteDirectories(SmbFile smbFile) throws UnifyException {
        try {
            if (!smbFile.exists()) {
                smbFile.mkdirs();
            }
        } catch (SmbException e) {
            throwOperationErrorException(e);
        }
    }

    private SmbFile getSmbFile(FileTransferSetup fileTransferSetup, String serverFile) throws UnifyException {
        String remotePath = getNormalizedRemotePath(fileTransferSetup);
        NtlmPasswordAuthentication auth = getAuthentication(fileTransferSetup);
        return getSmbFile(fileTransferSetup, auth, remotePath, serverFile);
    }

    private SmbFile getSmbFile(FileTransferSetup fileTransferSetup, NtlmPasswordAuthentication auth, String remotePath,
            String serverFile) throws UnifyException {
        SmbFile smbFile = null;
        try {
            StringBuilder sb = new StringBuilder();
            sb.append("smb://").append(fileTransferSetup.getRemoteHost());
            if (fileTransferSetup.getRemotePort() > 0) {
                sb.append(':').append(fileTransferSetup.getRemotePort());
            }

            sb.append(remotePath);
            if (serverFile != null) {
                sb.append(serverFile);
            }

            String smbUrl = sb.toString();
            logDebug("Obtaining SMB file: File: [{0}]", smbUrl);
            if (auth != null) {
                smbFile = new SmbFile(smbUrl, auth);
            } else {
                smbFile = new SmbFile(smbUrl);
            }
        } catch (MalformedURLException e) {
            throwOperationErrorException(e);
        }
        return smbFile;
    }

    private NtlmPasswordAuthentication getAuthentication(FileTransferSetup fileTransferSetup) {
        NtlmPasswordAuthentication auth = null;
        if (fileTransferSetup.getAuthenticationId() != null) {
            String domain = null;
            String loginId = fileTransferSetup.getAuthenticationId();
            int domainIndex = loginId.indexOf('\\');
            if (domainIndex < 0) {
                domainIndex = loginId.indexOf('/');
            }

            if (domainIndex >= 0) {
                domain = loginId.substring(0, domainIndex);
                loginId = loginId.substring(domainIndex + 1);
            }

            auth = new NtlmPasswordAuthentication(domain, loginId, fileTransferSetup.getAuthenticationPassword());
        }

        return auth;
    }

    private class SMBFileFilter extends FileFilter implements SmbFileFilter {

        public SMBFileFilter(FileTransferSetup fileTransferSetup) {
            super(fileTransferSetup.getFilePrefixes(), fileTransferSetup.getFileSuffixes());
        }

        @Override
        public boolean accept(SmbFile smbFile) throws SmbException {
            return accept(smbFile.getName(), smbFile.isFile());
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy