package com.perforce.spark; import java.io.InputStream; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; import javax.servlet.http.HttpServletResponse; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathFactory; import org.w3c.dom.Document; import spark.Request; import spark.Response; 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.GetDirectoriesOptions; import com.perforce.p4java.option.server.GetFileContentsOptions; import com.perforce.p4java.server.IOptionsServer; public class ConnectionHelper { private static SortedMap<String, String> mapParentID = new TreeMap<>(); static { mapParentID.put("/project/groupId", "GroupID"); mapParentID.put("/project/artifactId", "ArtifactID"); mapParentID.put("/project/version", "Version"); mapParentID.put("/project/packaging", "Packaging"); mapParentID.put("/project/name", "Name"); mapParentID.put("/project/url", "Url"); mapParentID.put("/project/description", "Description"); } public static HttpServletResponse view(Request request, Response response) throws Exception { // get p4 session IOptionsServer p4 = ConnectionSession.get(request, response); String file = request.pathInfo(); String depotFile = toDepotPath(file); // exit if no POM file. if (!isFile(p4, depotFile)) { throw new P4JavaException("No such file."); } // get the POM file and read List<IFileSpec> fileSpecs = FileSpecBuilder.makeFileSpecList(depotFile); GetFileContentsOptions printOpts = new GetFileContentsOptions(); printOpts.setNoHeaderLine(true); InputStream in = p4.getFileContents(fileSpecs, printOpts); 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; } public static Map<String, Object> browse(Request request, Response response) { IOptionsServer p4; Map<String, Object> attributes; attributes = NavBar.attributes("browse", request); attributes.put("breadcrumb", ""); attributes.put("directories", ""); attributes.put("assets", ""); attributes.put("summary", ""); // get p4 session try { p4 = ConnectionSession.get(request, response); } catch (P4JavaException e) { //response.redirect("/"); String msg = e.getMessage(); msg = (msg == null) ? "Unknown Connection Error" : msg; attributes.put("error_show", "inherit"); attributes.put("error_message", msg); return attributes; } // fetch paths try { String base = request.pathInfo(); base = (base.endsWith("/")) ? base : base + "/"; List<String> dirs = listDirs(p4, base); List<String> files = listFiles(p4, base); attributes.put("breadcrumb", breadcrumbForm(base)); attributes.put("directories", directoryForm(dirs, base)); attributes.put("summary", parentForm(p4, dirs, base)); attributes.put("assets", assetForm(files)); } catch (Exception e) { String msg = e.getMessage(); msg = (msg == null) ? "Unknown Browse Error" : msg; attributes.put("error_show", "inherit"); attributes.put("error_message", msg); return attributes; } return attributes; } private static String breadcrumbForm(String base) { StringBuilder form = new StringBuilder(); form.append("<ol class=\"breadcrumb\">"); Path path = Paths.get(base); Iterator<Path> p = path.iterator(); String link = "/"; boolean home = true; while (p.hasNext()) { Path crumb = p.next(); link += crumb + "/"; form.append("<li><a href=\""); form.append(link); form.append("\">"); if (home) { form.append("<span class=\"glyphicon glyphicon-home\" aria-hidden=\"true\">"); form.append("</span>"); } else { form.append(crumb); } form.append("</a></li>"); home = false; } form.append("</ol>"); return form.toString(); } private static String directoryForm(List<String> dirs, String base) { StringBuilder form = new StringBuilder(); form.append("<ul class=\"list-group\">"); for (String d : dirs) { Path path = Paths.get(d); Path dir = path.getFileName(); form.append("<li class=\"list-group-item\">"); form.append("<a href=\""); form.append(base + dir); form.append("\">"); form.append(dir); form.append("</a>"); form.append("</li>"); } form.append("</ul>"); return form.toString(); } private static String assetForm(List<String> files) { StringBuilder form = new StringBuilder(); form.append("<ul class=\"list-group\">"); for (String f : files) { Path path = Paths.get(f); Path file = path.getFileName(); String view = toBasePath(f); form.append("<li class=\"list-group-item\">"); form.append("<a href=\""); form.append(view); form.append("\">"); form.append(file); form.append("</a>"); form.append("</li>"); } form.append("</ul>"); return form.toString(); } private static String parentForm(IOptionsServer p4, List<String> dirs, String base) throws Exception { StringBuilder form = new StringBuilder(); // exit early if not deep enough if (base.split("/").length < 4) { return ""; } // exit early if too deep if (dirs == null || dirs.isEmpty()) { return ""; } // Gather parts to build asset filename Path currentPath = Paths.get(base); Path dir = currentPath.getFileName(); Path nextPath = Paths.get(dirs.get(0)); Path version = nextPath.getFileName(); String file = dir + "-" + version + ".pom"; String path = toDepotPath(base); path += "/" + version + "/" + file; // exit if no POM file. if (!isFile(p4, path)) { return ""; } // get the POM file and read List<IFileSpec> fileSpecs = FileSpecBuilder.makeFileSpecList(path); GetFileContentsOptions printOpts = new GetFileContentsOptions(); printOpts.setNoHeaderLine(true); InputStream ins = p4.getFileContents(fileSpecs, printOpts); // create a new document from input stream DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(ins); form.append("<div class=\"panel panel-success\">"); form.append("<div class=\"panel-heading\">"); form.append("<h3 class=\"panel-title\">Artifact Summary</h3>"); form.append("</div>"); form.append("<ul class=\"list-group\">"); XPath xPath = XPathFactory.newInstance().newXPath(); for (String id : mapParentID.keySet()) { String name = mapParentID.get(id); String value = xPath.compile(id).evaluate(doc); form.append("<li class=\"list-group-item\">"); form.append("<strong>"); form.append(name); form.append("</string>"); form.append("<code class=\"code-id\">"); form.append(value); form.append("</code>"); form.append("</li>"); } form.append("</ul>"); form.append("</div>"); return form.toString(); } private static boolean isFile(IOptionsServer p4, String path) throws P4JavaException { List<IFileSpec> fileSpecs = FileSpecBuilder.makeFileSpecList(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; } private static List<String> listDirs(IOptionsServer p4, String base) throws P4JavaException { String path = toDepotPath(base) + "/*"; List<String> 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(d.toString()); } } return list; } private static List<String> listFiles(IOptionsServer p4, String base) throws P4JavaException { String path = toDepotPath(base) + "/*"; List<String> 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 f : files) { if (f.getOpStatus() == FileSpecOpStatus.VALID) { list.add(f.getDepotPathString()); } } return list; } private static String toDepotPath(String base) { List<String> parts = new ArrayList<>(); parts.addAll(Arrays.asList(base.split("/"))); parts.remove(0); parts.remove(0); String depot = ConnectionConfig.getDepot(); parts.add(0, depot); String path = String.join("/", parts); path = "//" + path; return path; } private static String toBasePath(String depot) { List<String> parts = new ArrayList<>(); parts.addAll(Arrays.asList(depot.split("/"))); parts.remove(0); parts.remove(0); parts.remove(0); String path = String.join("/", parts); path = "/view/" + path; return path; } }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#12 | 14228 | Paul Allen |
Moved View over to the new model. Retactor connection to package. |
||
#11 | 14227 | Paul Allen | Moved over MAVEN Artifact summary. | ||
#10 | 14226 | Paul Allen | Tidy up Browse elements over to micro MVC model | ||
#9 | 14181 | Paul Allen | Lots of updates and refactoring. | ||
#8 | 14047 | Paul Allen | Moved depot to list and added config. | ||
#7 | 14017 | Paul Allen | Proxy caching to Perforce and SLF4J logging. | ||
#6 | 14013 | Paul Allen | Basic proxy | ||
#5 | 13969 | Paul Allen | Depot list/create for Assets | ||
#4 | 13863 | Paul Allen | Minor fix to session vs cookie for login check. | ||
#3 | 13862 | Paul Allen | Submit uploads to Perforce | ||
#2 | 13798 | Paul Allen | Basic file upload and login/logout cookie tidyup | ||
#1 | 13746 | Paul Allen | Basic File/Dir browsing and Cookie management. |