use of com.gitblit.models.PathModel in project gitblit by gitblit.
the class JGitUtils method getFilesInPath2.
/**
* Returns the list of files in the specified folder at the specified
* commit. If the repository does not exist or is empty, an empty list is
* returned.
*
* This is modified version that implements path compression feature.
*
* @param repository
* @param path
* if unspecified, root folder is assumed.
* @param commit
* if null, HEAD is assumed.
* @return list of files in specified path
*/
public static List<PathModel> getFilesInPath2(Repository repository, String path, RevCommit commit) {
List<PathModel> list = new ArrayList<PathModel>();
if (!hasCommits(repository)) {
return list;
}
if (commit == null) {
commit = getCommit(repository, null);
}
final TreeWalk tw = new TreeWalk(repository);
try {
tw.addTree(commit.getTree());
final boolean isPathEmpty = Strings.isNullOrEmpty(path);
if (!isPathEmpty) {
PathFilter f = PathFilter.create(path);
tw.setFilter(f);
}
tw.setRecursive(true);
List<String> paths = new ArrayList<>();
while (tw.next()) {
String pathString = tw.getPathString();
String child = isPathEmpty ? pathString : pathString.replaceFirst(Pattern.quote(String.format("%s/", path)), "");
paths.add(child);
}
for (String p : PathUtils.compressPaths(paths)) {
String pathString = isPathEmpty ? p : String.format("%s/%s", path, p);
list.add(getPathModel(repository, pathString, path, commit));
}
} catch (IOException e) {
error(e, repository, "{0} failed to get files for commit {1}", commit.getName());
} finally {
tw.close();
}
Collections.sort(list);
return list;
}
use of com.gitblit.models.PathModel in project gitblit by gitblit.
the class BranchTicketService method getTickets.
/**
* Returns all the tickets in the repository. Querying tickets from the
* repository requires deserializing all tickets. This is an expensive
* process and not recommended. Tickets are indexed by Lucene and queries
* should be executed against that index.
*
* @param repository
* @param filter
* optional filter to only return matching results
* @return a list of tickets
*/
@Override
public List<TicketModel> getTickets(RepositoryModel repository, TicketFilter filter) {
List<TicketModel> list = new ArrayList<TicketModel>();
Repository db = repositoryManager.getRepository(repository.name);
try {
RefModel ticketsBranch = getTicketsBranch(db);
if (ticketsBranch == null) {
return list;
}
// Collect the set of all json files
List<PathModel> paths = JGitUtils.getDocuments(db, Arrays.asList("json"), BRANCH);
// Deserialize each ticket and optionally filter out unwanted tickets
for (PathModel path : paths) {
String name = path.name.substring(path.name.lastIndexOf('/') + 1);
if (!JOURNAL.equals(name)) {
continue;
}
String json = readTicketsFile(db, path.path);
if (StringUtils.isEmpty(json)) {
// journal was touched but no changes were written
continue;
}
try {
// Reconstruct ticketId from the path
// id/26/326/journal.json
String tid = path.path.split("/")[2];
long ticketId = Long.parseLong(tid);
List<Change> changes = TicketSerializer.deserializeJournal(json);
if (ArrayUtils.isEmpty(changes)) {
log.warn("Empty journal for {}:{}", repository, path.path);
continue;
}
TicketModel ticket = TicketModel.buildTicket(changes);
ticket.project = repository.projectPath;
ticket.repository = repository.name;
ticket.number = ticketId;
// add the ticket, conditionally, to the list
if (filter == null) {
list.add(ticket);
} else {
if (filter.accept(ticket)) {
list.add(ticket);
}
}
} catch (Exception e) {
log.error("failed to deserialize {}/{}\n{}", new Object[] { repository, path.path, e.getMessage() });
log.error(null, e);
}
}
// sort the tickets by creation
Collections.sort(list);
return list;
} finally {
db.close();
}
}
use of com.gitblit.models.PathModel in project gitblit by gitblit.
the class BranchTicketService method getIds.
/**
* Returns the assigned ticket ids.
*
* @return the assigned ticket ids
*/
@Override
public synchronized Set<Long> getIds(RepositoryModel repository) {
Repository db = repositoryManager.getRepository(repository.name);
try {
if (getTicketsBranch(db) == null) {
return Collections.emptySet();
}
Set<Long> ids = new TreeSet<Long>();
List<PathModel> paths = JGitUtils.getDocuments(db, Arrays.asList("json"), BRANCH);
for (PathModel path : paths) {
String name = path.name.substring(path.name.lastIndexOf('/') + 1);
if (!JOURNAL.equals(name)) {
continue;
}
String tid = path.path.split("/")[2];
long ticketId = Long.parseLong(tid);
ids.add(ticketId);
}
return ids;
} finally {
if (db != null) {
db.close();
}
}
}
use of com.gitblit.models.PathModel in project gitblit by gitblit.
the class RawServlet method processRequest.
/**
* Retrieves the specified resource from the specified branch of the
* repository.
*
* @param request
* @param response
* @throws javax.servlet.ServletException
* @throws java.io.IOException
*/
private void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String path = request.getPathInfo();
if (path.toLowerCase().endsWith(".git")) {
// forward to url with trailing /
// this is important for relative pages links
response.sendRedirect(request.getServletPath() + path + "/");
return;
}
if (path.charAt(0) == '/') {
// strip leading /
path = path.substring(1);
}
// determine repository and resource from url
String repository = path;
Repository r = null;
int terminator = repository.length();
do {
repository = repository.substring(0, terminator);
r = repositoryManager.getRepository(repository, false);
terminator = repository.lastIndexOf('/');
} while (r == null && terminator > -1);
ServletContext context = request.getSession().getServletContext();
try {
if (r == null) {
// repository not found!
String mkd = MessageFormat.format("# Error\nSorry, no valid **repository** specified in this url: {0}!", path);
error(response, mkd);
return;
}
// identify the branch
String branch = getBranch(repository, path);
if (StringUtils.isEmpty(branch)) {
branch = r.getBranch();
if (branch == null) {
// no branches found! empty?
String mkd = MessageFormat.format("# Error\nSorry, no valid **branch** specified in this url: {0}!", path);
error(response, mkd);
} else {
// redirect to default branch
String base = request.getRequestURI();
String url = base + branch + "/";
response.sendRedirect(url);
}
return;
}
// identify the requested path
String requestedPath = getPath(repository, branch, path);
// identify the commit
RevCommit commit = JGitUtils.getCommit(r, branch);
if (commit == null) {
// branch not found!
String mkd = MessageFormat.format("# Error\nSorry, the repository {0} does not have a **{1}** branch!", repository, branch);
error(response, mkd);
return;
}
Map<String, String> quickContentTypes = new HashMap<>();
quickContentTypes.put("html", "text/html");
quickContentTypes.put("htm", "text/html");
quickContentTypes.put("xml", "application/xml");
quickContentTypes.put("json", "application/json");
List<PathModel> pathEntries = JGitUtils.getFilesInPath(r, requestedPath, commit);
if (pathEntries.isEmpty()) {
// requested a specific resource
String file = StringUtils.getLastPathElement(requestedPath);
try {
String ext = StringUtils.getFileExtension(file).toLowerCase();
// We can't parse out an extension for classic "dotfiles", so make a general assumption that
// they're text files to allow presenting them in browser instead of only for download.
//
// However, that only holds for files with no other extension included, for files that happen
// to start with a dot but also include an extension, process the extension normally.
// This logic covers .gitattributes, .gitignore, .zshrc, etc., but does not cover .mongorc.js, .zshrc.bak
boolean isExtensionlessDotfile = file.charAt(0) == '.' && (file.length() == 1 || file.indexOf('.', 1) < 0);
String contentType = isExtensionlessDotfile ? "text/plain" : quickContentTypes.get(ext);
if (contentType == null) {
List<String> exts = runtimeManager.getSettings().getStrings(Keys.web.prettyPrintExtensions);
if (exts.contains(ext)) {
// extension is a registered text type for pretty printing
contentType = "text/plain";
} else {
// query Tika for the content type
Tika tika = new Tika();
contentType = tika.detect(file);
}
}
if (contentType == null) {
// ask the container for the content type
contentType = context.getMimeType(requestedPath);
if (contentType == null) {
// still unknown content type, assume binary
contentType = "application/octet-stream";
}
}
if (isTextType(contentType) || isTextDataType(contentType)) {
// load, interpret, and serve text content as UTF-8
String[] encodings = runtimeManager.getSettings().getStrings(Keys.web.blobEncodings).toArray(new String[0]);
String content = JGitUtils.getStringContent(r, commit.getTree(), requestedPath, encodings);
if (content == null) {
logger.error("RawServlet Failed to load {} {} {}", repository, commit.getName(), path);
notFound(response, requestedPath, branch);
return;
}
byte[] bytes = content.getBytes(Constants.ENCODING);
setContentType(response, contentType);
response.setContentLength(bytes.length);
ByteArrayInputStream is = new ByteArrayInputStream(bytes);
sendContent(response, JGitUtils.getCommitDate(commit), is);
} else {
// stream binary content directly from the repository
if (!streamFromRepo(request, response, r, commit, requestedPath)) {
logger.error("RawServlet Failed to load {} {} {}", repository, commit.getName(), path);
notFound(response, requestedPath, branch);
}
}
return;
} catch (Exception e) {
logger.error(null, e);
}
} else {
// path request
if (!request.getPathInfo().endsWith("/")) {
// redirect to trailing '/' url
response.sendRedirect(request.getServletPath() + request.getPathInfo() + "/");
return;
}
if (renderIndex()) {
// locate and render an index file
Map<String, String> names = new TreeMap<String, String>();
for (PathModel entry : pathEntries) {
names.put(entry.name.toLowerCase(), entry.name);
}
List<String> extensions = new ArrayList<String>();
extensions.add("html");
extensions.add("htm");
String content = null;
for (String ext : extensions) {
String key = "index." + ext;
if (names.containsKey(key)) {
String fileName = names.get(key);
String fullPath = fileName;
if (!requestedPath.isEmpty()) {
fullPath = requestedPath + "/" + fileName;
}
String[] encodings = runtimeManager.getSettings().getStrings(Keys.web.blobEncodings).toArray(new String[0]);
String stringContent = JGitUtils.getStringContent(r, commit.getTree(), fullPath, encodings);
if (stringContent == null) {
continue;
}
content = stringContent;
requestedPath = fullPath;
break;
}
}
response.setContentType("text/html; charset=" + Constants.ENCODING);
byte[] bytes = content.getBytes(Constants.ENCODING);
response.setContentLength(bytes.length);
ByteArrayInputStream is = new ByteArrayInputStream(bytes);
sendContent(response, JGitUtils.getCommitDate(commit), is);
return;
}
}
// no content, document list or 404 page
if (pathEntries.isEmpty()) {
// default 404 page
notFound(response, requestedPath, branch);
return;
} else {
//
// directory list
//
response.setContentType("text/html");
response.getWriter().append("<style>table th, table td { min-width: 150px; text-align: left; }</style>");
response.getWriter().append("<table>");
response.getWriter().append("<thead><tr><th>path</th><th>mode</th><th>size</th></tr>");
response.getWriter().append("</thead>");
response.getWriter().append("<tbody>");
String pattern = "<tr><td><a href=\"{0}/{1}\">{1}</a></td><td>{2}</td><td>{3}</td></tr>";
final ByteFormat byteFormat = new ByteFormat();
if (!pathEntries.isEmpty()) {
if (pathEntries.get(0).path.indexOf('/') > -1) {
// we are in a subdirectory, add parent directory link
String pp = URLEncoder.encode(requestedPath, Constants.ENCODING);
pathEntries.add(0, new PathModel("..", pp + "/..", null, 0, FileMode.TREE.getBits(), null, null));
}
}
String basePath = request.getServletPath() + request.getPathInfo();
if (basePath.charAt(basePath.length() - 1) == '/') {
// strip trailing slash
basePath = basePath.substring(0, basePath.length() - 1);
}
for (PathModel entry : pathEntries) {
String pp = URLEncoder.encode(entry.name, Constants.ENCODING);
response.getWriter().append(MessageFormat.format(pattern, basePath, pp, JGitUtils.getPermissionsFromMode(entry.mode), entry.isFile() ? byteFormat.format(entry.size) : ""));
}
response.getWriter().append("</tbody>");
response.getWriter().append("</table>");
}
} catch (Throwable t) {
logger.error("Failed to write page to client", t);
} finally {
r.close();
}
}
use of com.gitblit.models.PathModel in project gitblit by gitblit.
the class JGitUtils method getPathModel.
/**
* Returns a path model of the current file in the treewalk.
*
* @param tw
* @param basePath
* @param commit
* @return a path model of the current file in the treewalk
*/
private static PathModel getPathModel(TreeWalk tw, String basePath, RevCommit commit) {
String name;
long size = 0;
if (StringUtils.isEmpty(basePath)) {
name = tw.getPathString();
} else {
name = tw.getPathString().substring(basePath.length() + 1);
}
ObjectId objectId = tw.getObjectId(0);
FilestoreModel filestoreItem = null;
try {
if (!tw.isSubtree() && (tw.getFileMode(0) != FileMode.GITLINK)) {
size = tw.getObjectReader().getObjectSize(objectId, Constants.OBJ_BLOB);
if (isPossibleFilestoreItem(size)) {
filestoreItem = getFilestoreItem(tw.getObjectReader().open(objectId));
}
}
} catch (Throwable t) {
error(t, null, "failed to retrieve blob size for " + tw.getPathString());
}
return new PathModel(name, tw.getPathString(), filestoreItem, size, tw.getFileMode(0).getBits(), objectId.getName(), commit.getName());
}
Aggregations