/** * Check if a file is local to the current project. If we don't have projects, check if the file * is in the source root. * * @param path the path to a file * @return true if the file is local to the current repository */ private boolean isLocal(String path) { RuntimeEnvironment env = RuntimeEnvironment.getInstance(); String srcRoot = env.getSourceRootPath(); boolean local = false; if (path.startsWith(srcRoot)) { if (env.hasProjects()) { String relPath = path.substring(srcRoot.length()); if (project.equals(Project.getProject(relPath))) { // File is under the current project, so it's local. local = true; } } else { // File is under source root, and we don't have projects, so // consider it local. local = true; } } return local; }
/** * Dump the configuration as an HTML table. * * @param out destination for the HTML output * @throws IOException if an error happens while writing to {@code out} * @throws HistoryException if the history guru cannot be accesses */ @SuppressWarnings("boxing") public static void dumpConfiguration(Appendable out) throws IOException, HistoryException { out.append("<table border=\"1\" width=\"100%\">"); out.append("<tr><th>Variable</th><th>Value</th></tr>"); RuntimeEnvironment env = RuntimeEnvironment.getInstance(); printTableRow(out, "Source root", env.getSourceRootPath()); printTableRow(out, "Data root", env.getDataRootPath()); printTableRow(out, "CTags", env.getCtags()); printTableRow(out, "Bug page", env.getBugPage()); printTableRow(out, "Bug pattern", env.getBugPattern()); printTableRow(out, "User page", env.getUserPage()); printTableRow(out, "User page suffix", env.getUserPageSuffix()); printTableRow(out, "Review page", env.getReviewPage()); printTableRow(out, "Review pattern", env.getReviewPattern()); printTableRow(out, "Using projects", env.hasProjects()); out.append("<tr><td>Ignored files</td><td>"); printUnorderedList(out, env.getIgnoredNames().getItems()); out.append("</td></tr>"); printTableRow(out, "Index word limit", env.getIndexWordLimit()); printTableRow(out, "Allow leading wildcard in search", env.isAllowLeadingWildcard()); printTableRow(out, "History cache", HistoryGuru.getInstance().getCacheInfo()); out.append("</table>"); }
private void storeHistory(ConnectionResource conn, History history, Repository repository) throws SQLException { Integer reposId = null; Map<String, Integer> authors = null; Map<String, Integer> files = null; Map<String, Integer> directories = null; PreparedStatement addChangeset = null; PreparedStatement addDirchange = null; PreparedStatement addFilechange = null; PreparedStatement addFilemove = null; RuntimeEnvironment env = RuntimeEnvironment.getInstance(); // return immediately when there is nothing to do List<HistoryEntry> entries = history.getHistoryEntries(); if (entries.isEmpty()) { return; } for (int i = 0; ; i++) { try { if (reposId == null) { reposId = getRepositoryId(conn, repository); conn.commit(); } if (authors == null) { authors = getAuthors(conn, history, reposId); conn.commit(); } if (directories == null || files == null) { Map<String, Integer> dirs = new HashMap<String, Integer>(); Map<String, Integer> fls = new HashMap<String, Integer>(); getFilesAndDirectories(conn, history, reposId, dirs, fls); conn.commit(); directories = dirs; files = fls; } if (addChangeset == null) { addChangeset = conn.getStatement(ADD_CHANGESET); } if (addDirchange == null) { addDirchange = conn.getStatement(ADD_DIRCHANGE); } if (addFilechange == null) { addFilechange = conn.getStatement(ADD_FILECHANGE); } if (addFilemove == null) { addFilemove = conn.getStatement(ADD_FILEMOVE); } // Success! Break out of the loop. break; } catch (SQLException sqle) { handleSQLException(sqle, i); conn.rollback(); } } addChangeset.setInt(1, reposId); // getHistoryEntries() returns the entries in reverse chronological // order, but we want to insert them in chronological order so that // their auto-generated identity column can be used as a chronological // ordering column. Otherwise, incremental updates will make the // identity column unusable for chronological ordering. So therefore // we walk the list backwards. for (ListIterator<HistoryEntry> it = entries.listIterator(entries.size()); it.hasPrevious(); ) { HistoryEntry entry = it.previous(); retry: for (int i = 0; ; i++) { try { addChangeset.setString(2, entry.getRevision()); addChangeset.setInt(3, authors.get(entry.getAuthor())); addChangeset.setTimestamp(4, new Timestamp(entry.getDate().getTime())); String msg = entry.getMessage(); // Truncate the message if it can't fit in a VARCHAR // (bug #11663). if (msg.length() > MAX_MESSAGE_LENGTH) { msg = truncate(msg, MAX_MESSAGE_LENGTH); } addChangeset.setString(5, msg); int changesetId = nextChangesetId.getAndIncrement(); addChangeset.setInt(6, changesetId); addChangeset.executeUpdate(); // Add one row for each file in FILECHANGES, and one row // for each path element of the directories in DIRCHANGES. Set<String> addedDirs = new HashSet<String>(); addDirchange.setInt(1, changesetId); addFilechange.setInt(1, changesetId); for (String file : entry.getFiles()) { // ignore ignored files String repodir = ""; try { repodir = env.getPathRelativeToSourceRoot(new File(repository.getDirectoryName()), 0); } catch (IOException ex) { Logger.getLogger(JDBCHistoryCache.class.getName()).log(Level.SEVERE, null, ex); } String fullPath = toUnixPath(file); if (!history.isIgnored(file.substring(repodir.length() + 1))) { int fileId = files.get(fullPath); addFilechange.setInt(2, fileId); addFilechange.executeUpdate(); } String[] pathElts = splitPath(fullPath); for (int j = 0; j < pathElts.length; j++) { String dir = unsplitPath(pathElts, j); // Only add to DIRCHANGES if we haven't already // added this dir/changeset combination. if (!addedDirs.contains(dir)) { addDirchange.setInt(2, directories.get(dir)); addDirchange.executeUpdate(); addedDirs.add(dir); } } } conn.commit(); // Successfully added the entry. Break out of retry loop. break retry; } catch (SQLException sqle) { handleSQLException(sqle, i); conn.rollback(); } } } /* * Special handling for certain files - this is mainly for files which * have been renamed in Mercurial repository. * This ensures that their complete history (follow) will be saved. */ for (String filename : history.getIgnoredFiles()) { String file_path = repository.getDirectoryName() + File.separatorChar + filename; File file = new File(file_path); String repo_path = file_path.substring(env.getSourceRootPath().length()); History hist; try { hist = repository.getHistory(file); } catch (HistoryException ex) { Logger.getLogger(JDBCHistoryCache.class.getName()).log(Level.SEVERE, null, ex); continue; } int fileId = files.get(repo_path); for (HistoryEntry entry : hist.getHistoryEntries()) { retry: for (int i = 0; ; i++) { try { int changesetId = getIdForRevision(entry.getRevision()); /* * If the file exists in the changeset, store it in * the table tracking moves of the file when it had * one of its precedent names so it can be found * when performing historyget on directory. */ if (entry.getFiles().contains(repo_path)) { addFilechange.setInt(1, changesetId); addFilechange.setInt(2, fileId); addFilechange.executeUpdate(); } else { addFilemove.setInt(1, changesetId); addFilemove.setInt(2, fileId); addFilemove.executeUpdate(); } conn.commit(); break retry; } catch (SQLException sqle) { handleSQLException(sqle, i); conn.rollback(); } } } } }