package com.atsebak.embeddedlinuxjvm.services;
import com.atsebak.embeddedlinuxjvm.protocol.ssh.SSHHandlerTarget;
import com.intellij.execution.configurations.RuntimeConfigurationException;
import com.intellij.openapi.project.Project;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.SftpException;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
import java.util.*;
public class ClasspathService {
@NotNull
private final Project project;
private List<File> previousLibraries;
/**
* IntelliJ Service Injected
*/
public ClasspathService(@NotNull Project project) {
this.project = project;
previousLibraries = new ArrayList<File>();
}
/**
* Gets the delta of jars between host and target machines. It will always add the normal project output path but not necessarily the external libs
* Some potential problems can be that the user stops it midway while deploying so the jars don't go on the target.
* Note: This is not a proper way of doing this but simple to do
* @param hostLibraries
* @return targetLibraries
*/
@Deprecated
public List<File> deltaOfDeployedJars(List<File> hostLibraries) {
List<File> targetLibraries = new ArrayList<File>();
for (File hostFile : hostLibraries) {
if (!hostFile.getName().contains("jar")) {
targetLibraries.add(hostFile);
} else if (!previousLibraries.contains(hostFile)) {
targetLibraries.add(hostFile);
}
}
previousLibraries = hostLibraries;
return targetLibraries;
}
/**
* Proper way: Gets the deployed jars on target machine using SSH than compares name, date and size to make sure its correct
* The reason for this as it will exponentially increase deployment times to not keep on uploading files that already exist on remote.
* @return
* @throws IOException
* @throws RuntimeConfigurationException
*/
public List<File> invokeFindDeployedJars(@NotNull final List<File> hostLibraries, @NotNull final SSHHandlerTarget target)
throws IOException, RuntimeConfigurationException, JSchException, SftpException {
Set<String> filesAlreadyDeployed = new HashSet<String>();
List<File> newLibraries = new ArrayList<File>();
Vector alreadyDeployedLibraries = target.getAlreadyDeployedLibraries();
for (Object alreadyDeployedLibrary : alreadyDeployedLibraries) {
ChannelSftp.LsEntry targetLibrary = (ChannelSftp.LsEntry) alreadyDeployedLibrary;
for (File hostFile : hostLibraries) {
//Names, Last Modified and Size have to be the exact same for it to be identied as the same file
if (targetLibrary.getFilename().equals(hostFile.getName()) && hostFile.length() == targetLibrary.getAttrs().getSize()
&& targetLibrary.getAttrs().getMtimeString().equals(new Date(hostFile.lastModified()).toString())) {
//hash what files exist
filesAlreadyDeployed.add(hostFile.getName());
break;
}
}
}
//add files that do not exist on target
for (File hostFile : hostLibraries) {
if (!filesAlreadyDeployed.contains(hostFile.getName())) {
newLibraries.add(hostFile);
}
}
return newLibraries;
}
}