package com.perforce.spark.browse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import com.perforce.p4java.core.file.FileSpecBuilder;
import com.perforce.p4java.core.file.FileSpecOpStatus;
import com.perforce.p4java.core.file.IFileSize;
import com.perforce.p4java.core.file.IFileSpec;
import com.perforce.p4java.exception.P4JavaException;
import com.perforce.p4java.option.server.GetDepotFilesOptions;
import com.perforce.p4java.option.server.GetDirectoriesOptions;
import com.perforce.p4java.server.IOptionsServer;
import com.perforce.spark.artifact.ArtifactFactory;
import com.perforce.spark.artifact.ArtifactType;
import com.perforce.spark.artifact.SummaryInterface;
import com.perforce.spark.depot.DepotFactory;
import com.perforce.spark.depot.DepotModel;
import com.perforce.spark.repository.RepoInterface;
public class BrowseModel {
private final List<BrowseFile> files;
private final List<BrowseDir> dirs;
private SummaryInterface summary;
public BrowseModel(IOptionsServer p4, String base) throws P4JavaException {
this.dirs = listDirs(p4, base);
this.files = listFiles(p4, base);
summary = findSummary(p4, base);
}
private static List<BrowseDir> listDirs(IOptionsServer p4, String base)
throws P4JavaException {
String path = toDepotPath(base) + "/*";
List<BrowseDir> list = new ArrayList<>();
List<IFileSpec> fileSpecs = FileSpecBuilder.makeFileSpecList(path);
GetDirectoriesOptions opts = new GetDirectoriesOptions();
List<IFileSpec> dirs = p4.getDirectories(fileSpecs, opts);
for (IFileSpec d : dirs) {
if (d.getOpStatus() == FileSpecOpStatus.VALID) {
list.add(new BrowseDir(d, base));
}
}
return list;
}
private static List<BrowseFile> listFiles(IOptionsServer p4, String base)
throws P4JavaException {
String path = toDepotPath(base) + "/*";
List<BrowseFile> list = new ArrayList<>();
List<IFileSpec> fileSpecs = FileSpecBuilder.makeFileSpecList(path);
GetDepotFilesOptions opts = new GetDepotFilesOptions();
opts.setMaxResults(101);
List<IFileSpec> files = p4.getDepotFiles(fileSpecs, opts);
for (IFileSpec file : files) {
if (file.getOpStatus() == FileSpecOpStatus.VALID) {
List<IFileSpec> sizeSpec = Arrays.asList(file);
IFileSize size = p4.getFileSizes(sizeSpec, null).get(0);
list.add(new BrowseFile(file, size));
}
}
return list;
}
private static SummaryInterface findSummary(IOptionsServer p4, String base)
throws P4JavaException {
// Fetch the pattern from the repo used to find the summary file
DepotModel depotModel = DepotFactory.getByBase(p4, base);
RepoInterface repo = depotModel.getRepo();
// Gather parts to build search for summary filename
String path = toDepotPath(base);
path += "/" + repo.getSummaryPattern();
// Search Perforce
List<IFileSpec> fileSpecs = FileSpecBuilder.makeFileSpecList(path);
GetDepotFilesOptions fileOpts = new GetDepotFilesOptions();
fileOpts.setAllRevs(false);
List<IFileSpec> specs = p4.getDepotFiles(fileSpecs, fileOpts);
List<IFileSpec> summary = new ArrayList<>();
for (IFileSpec s : specs) {
if (s.getOpStatus() != FileSpecOpStatus.ERROR) {
summary.add(s);
}
}
// exit early if no matches found
if (summary.isEmpty()) {
return null;
}
ArtifactType type = repo.getArtifactType();
SummaryInterface artifact = ArtifactFactory.getSummary(p4, type,
summary);
return artifact;
}
private static String toDepotPath(String base) {
List<String> parts = new ArrayList<>();
parts.addAll(Arrays.asList(base.split("/")));
parts.remove(0);
parts.remove(0);
String path = String.join("/", parts);
path = "//" + path;
return path;
}
public List<BrowseFile> getFiles() {
return files;
}
public List<BrowseDir> getDirs() {
return dirs;
}
public SummaryInterface getSummary() {
return summary;
}
}