Search in sources :

Example 6 with PathModel

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;
}
Also used : PathFilter(org.eclipse.jgit.treewalk.filter.PathFilter) PathModel(com.gitblit.models.PathModel) ArrayList(java.util.ArrayList) IOException(java.io.IOException) TreeWalk(org.eclipse.jgit.treewalk.TreeWalk)

Example 7 with PathModel

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();
    }
}
Also used : RefModel(com.gitblit.models.RefModel) ArrayList(java.util.ArrayList) TicketModel(com.gitblit.models.TicketModel) Change(com.gitblit.models.TicketModel.Change) ConcurrentRefUpdateException(org.eclipse.jgit.api.errors.ConcurrentRefUpdateException) IOException(java.io.IOException) Repository(org.eclipse.jgit.lib.Repository) PathModel(com.gitblit.models.PathModel)

Example 8 with PathModel

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();
        }
    }
}
Also used : Repository(org.eclipse.jgit.lib.Repository) PathModel(com.gitblit.models.PathModel) TreeSet(java.util.TreeSet) AtomicLong(java.util.concurrent.atomic.AtomicLong)

Example 9 with PathModel

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();
    }
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Tika(org.apache.tika.Tika) TreeMap(java.util.TreeMap) ServletException(javax.servlet.ServletException) ParseException(java.text.ParseException) IOException(java.io.IOException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) Repository(org.eclipse.jgit.lib.Repository) PathModel(com.gitblit.models.PathModel) ByteArrayInputStream(java.io.ByteArrayInputStream) ByteFormat(com.gitblit.utils.ByteFormat) ServletContext(javax.servlet.ServletContext) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 10 with PathModel

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());
}
Also used : PathModel(com.gitblit.models.PathModel) AnyObjectId(org.eclipse.jgit.lib.AnyObjectId) ObjectId(org.eclipse.jgit.lib.ObjectId) FilestoreModel(com.gitblit.models.FilestoreModel)

Aggregations

PathModel (com.gitblit.models.PathModel)13 ArrayList (java.util.ArrayList)6 Repository (org.eclipse.jgit.lib.Repository)6 IOException (java.io.IOException)5 TreeWalk (org.eclipse.jgit.treewalk.TreeWalk)4 RevCommit (org.eclipse.jgit.revwalk.RevCommit)3 Test (org.junit.Test)3 FilestoreModel (com.gitblit.models.FilestoreModel)2 HashMap (java.util.HashMap)2 PathFilter (org.eclipse.jgit.treewalk.filter.PathFilter)2 RefModel (com.gitblit.models.RefModel)1 TicketModel (com.gitblit.models.TicketModel)1 Change (com.gitblit.models.TicketModel.Change)1 ByteFormat (com.gitblit.utils.ByteFormat)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1 ParseException (java.text.ParseException)1 TreeMap (java.util.TreeMap)1 TreeSet (java.util.TreeSet)1 AtomicLong (java.util.concurrent.atomic.AtomicLong)1