package com.perforce.spark.store;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import spark.Request;
import spark.Response;
import com.perforce.p4java.core.IDepot;
import com.perforce.p4java.core.file.FileSpecBuilder;
import com.perforce.p4java.core.file.FileSpecOpStatus;
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.GetFileContentsOptions;
import com.perforce.p4java.server.IOptionsServer;
import com.perforce.spark.artifact.ArtifactType;
import com.perforce.spark.repository.RepoFormID;
import com.perforce.spark.repository.RepoInterface;
import com.perforce.spark.site.SiteType;
public abstract class DefaultStore implements RepoInterface {
private static Logger logger = LoggerFactory.getLogger(DefaultStore.class);
protected String name;
protected String title;
protected SiteType site;
protected ArtifactType type;
protected String description;
public DefaultStore(ArtifactType type) {
this.type = type;
}
public DefaultStore(Request request) {
this.name = RepoFormID.DEPOT.get(request);
this.title = RepoFormID.TITLE.get(request);
this.site = SiteType.STORE;
String typeStr = RepoFormID.TYPE.get(request);
this.type = ArtifactType.parse(typeStr);
this.description = RepoFormID.DESC.get(request);
}
public DefaultStore(IDepot depot) {
this.site = SiteType.STORE;
this.name = depot.getName();
this.type = ArtifactType.parse(depot.getDepotType());
this.description = depot.getDescription();
this.title = "Local Depot (" + name + ")";
}
@Override
public String getName() {
return name;
}
@Override
public SiteType getSiteType() {
return site;
}
@Override
public ArtifactType getArtifactType() {
return type;
}
@Override
public String getTitle() {
return title;
}
@Override
public String getDescription() {
return description;
}
protected HttpServletResponse getFile(IOptionsServer p4, String path,
Response response) throws Exception {
// Check if file is in repository.
if (!isFile(p4, path)) {
throw new P4JavaException("No such file");
}
List<IFileSpec> fileSpecs = getIFileSpecs(path);
logger.info("view: serving file: [" + name + "] " + path);
// p4 print the file (in memory)
GetFileContentsOptions printOpts = new GetFileContentsOptions();
printOpts.setNoHeaderLine(true);
InputStream in = p4.getFileContents(fileSpecs, printOpts);
// write to the ServletOutputStream
HttpServletResponse raw = response.raw();
byte[] buf = new byte[1024 * 64];
int bytesRead;
while ((bytesRead = in.read(buf)) != -1) {
raw.getOutputStream().write(buf, 0, bytesRead);
}
raw.getOutputStream().flush();
raw.getOutputStream().close();
in.close();
return raw;
}
protected boolean isFile(IOptionsServer p4, String path)
throws P4JavaException {
List<IFileSpec> fileSpecs = getIFileSpecs(path);
GetDepotFilesOptions fileOpts = new GetDepotFilesOptions();
fileOpts.setAllRevs(false);
List<IFileSpec> specs = p4.getDepotFiles(fileSpecs, fileOpts);
for (IFileSpec s : specs) {
if (s.getOpStatus() == FileSpecOpStatus.ERROR) {
return false;
}
}
return true;
}
protected String mapExtension(String path, String from, String to) {
if (path.endsWith(from)) {
int p = path.lastIndexOf(from);
path = path.substring(0, p) + to;
}
return path;
}
/**
* A relative Perforce not including the depot name.
*
* @param request
* @return
*/
protected static String toPath(Request request) {
String base = request.pathInfo();
List<String> parts = new ArrayList<>();
parts.addAll(Arrays.asList(base.split("/")));
parts.remove(0);
parts.remove(0);
parts.remove(0);
String path = String.join("/", parts);
return path;
}
private List<IFileSpec> getIFileSpecs(String path) {
List<IFileSpec> fileSpecs;
String depotPath = "//" + name + "/" + path;
fileSpecs = FileSpecBuilder.makeFileSpecList(depotPath);
return fileSpecs;
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("Name: " + getName() + "\n");
sb.append("Type: " + getArtifactType() + "\n");
sb.append("Title: " + getTitle() + "\n");
sb.append("Description: " + getDescription() + "\n");
return sb.toString();
}
}