use of org.opensolaris.opengrok.util.ForbiddenSymlinkException in project OpenGrok by OpenGrok.
the class MonotoneHistoryParser method processStream.
/**
* Process the output from the hg log command and insert the HistoryEntries
* into the history field.
*
* @param input The output from the process
* @throws java.io.IOException If an error occurs while reading the stream
*/
@Override
public void processStream(InputStream input) throws IOException {
RuntimeEnvironment env = RuntimeEnvironment.getInstance();
DateFormat df = repository.getDateFormat();
BufferedReader in = new BufferedReader(new InputStreamReader(input));
String s;
HistoryEntry entry = null;
int state = 0;
while ((s = in.readLine()) != null) {
s = s.trim();
// the minimum amount for maximum compatibility between monotone versions.
if (s.startsWith("-----------------------------------------------------------------")) {
if (entry != null && state > 2) {
entries.add(entry);
}
entry = new HistoryEntry();
entry.setActive(true);
state = 0;
continue;
}
switch(state) {
case 0:
if (s.startsWith("Revision:")) {
String rev = s.substring("Revision:".length()).trim();
entry.setRevision(rev);
++state;
}
break;
case 1:
if (s.startsWith("Author:")) {
entry.setAuthor(s.substring("Author:".length()).trim());
++state;
}
break;
case 2:
if (s.startsWith("Date:")) {
Date date = new Date();
try {
date = df.parse(s.substring("date:".length()).trim());
} catch (ParseException pe) {
//
throw new IOException("Could not parse date: " + s, pe);
}
entry.setDate(date);
++state;
}
break;
case 3:
if (s.startsWith("Modified ") || s.startsWith("Added ") || s.startsWith("Deleted ")) {
++state;
} else if (s.equalsIgnoreCase("ChangeLog:")) {
state = 5;
}
break;
case 4:
if (s.startsWith("Modified ") || s.startsWith("Added ") || s.startsWith("Deleted ")) {
// NOPMD
/* swallow */
} else if (s.equalsIgnoreCase("ChangeLog:")) {
state = 5;
} else {
String[] files = s.split(" ");
for (String f : files) {
File file = new File(mydir, f);
try {
String path = env.getPathRelativeToSourceRoot(file);
entry.addFile(path.intern());
} catch (ForbiddenSymlinkException e) {
LOGGER.log(Level.FINER, e.getMessage());
// ignore
} catch (FileNotFoundException e) {
// NOPMD
// If the file is not located under the source root, ignore it
}
}
}
break;
case 5:
entry.appendMessage(s);
break;
default:
LOGGER.warning("Unknown parser state: " + state);
break;
}
}
if (entry != null && state > 2) {
entries.add(entry);
}
}
use of org.opensolaris.opengrok.util.ForbiddenSymlinkException in project OpenGrok by OpenGrok.
the class RuntimeEnvironment method generateProjectRepositoriesMap.
/**
* Generate a TreeMap of projects with corresponding repository information.
*
* Project with some repository information is considered as a repository
* otherwise it is just a simple project.
*/
private void generateProjectRepositoriesMap() throws IOException {
repository_map.clear();
for (RepositoryInfo r : getRepositories()) {
Project proj;
String repoPath;
try {
repoPath = getPathRelativeToSourceRoot(new File(r.getDirectoryName()), 0);
} catch (ForbiddenSymlinkException e) {
LOGGER.log(Level.FINER, e.getMessage());
continue;
}
if ((proj = Project.getProject(repoPath)) != null) {
List<RepositoryInfo> values = repository_map.get(proj);
if (values == null) {
values = new ArrayList<>();
repository_map.put(proj, values);
}
values.add(r);
}
}
}
use of org.opensolaris.opengrok.util.ForbiddenSymlinkException in project OpenGrok by OpenGrok.
the class ProjectMessage method applyMessage.
@Override
protected byte[] applyMessage(RuntimeEnvironment env) throws Exception {
String command = getText();
validateMore(env);
switch(command) {
case "add":
for (String projectName : getTags()) {
File srcRoot = env.getSourceRootFile();
File projDir = new File(srcRoot, projectName);
if (!env.getProjects().containsKey(projectName)) {
Project project = new Project(projectName, "/" + projectName);
project.setTabSize(env.getConfiguration().getTabSize());
// Add repositories in this project.
List<RepositoryInfo> repos = getRepositoriesInDir(env, projDir);
env.addRepositories(repos);
env.getProjectRepositoriesMap().put(project, repos);
// Finally introduce the project to the configuration.
// Note that the project is inactive in the UI until it is indexed.
// See {@code isIndexed()}
env.getProjects().put(projectName, project);
Set<Project> projectSet = new TreeSet<>();
projectSet.add(project);
env.populateGroups(env.getGroups(), projectSet);
} else {
Project project = env.getProjects().get(projectName);
Map<Project, List<RepositoryInfo>> map = env.getProjectRepositoriesMap();
// Refresh the list of repositories of this project.
// This is the goal of this action: if an existing project
// is re-added, this means its list of repositories has changed.
List<RepositoryInfo> repos = getRepositoriesInDir(env, projDir);
List<RepositoryInfo> allrepos = env.getRepositories();
synchronized (allrepos) {
// newly added repository
for (RepositoryInfo repo : repos) {
if (!allrepos.contains(repo)) {
allrepos.add(repo);
}
}
// deleted repository
for (RepositoryInfo repo : map.get(project)) {
if (!repos.contains(repo)) {
allrepos.remove(repo);
}
}
}
map.put(project, repos);
}
}
break;
case "delete":
for (String projectName : getTags()) {
Project proj = env.getProjects().get(projectName);
if (proj == null) {
throw new Exception("cannot get project \"" + projectName + "\"");
}
LOGGER.log(Level.INFO, "deleting configuration for project " + projectName);
// Remove the project from its groups.
for (Group group : proj.getGroups()) {
group.getRepositories().remove(proj);
group.getProjects().remove(proj);
}
// Now remove the repositories associated with this project.
List<RepositoryInfo> repos = env.getProjectRepositoriesMap().get(proj);
env.getRepositories().removeAll(repos);
env.getProjectRepositoriesMap().remove(proj);
env.getProjects().remove(projectName, proj);
// Prevent the project to be included in new searches.
env.refreshSearcherManagerMap();
// Lastly, remove data associated with the project.
LOGGER.log(Level.INFO, "deleting data for project " + projectName);
for (String dirName : new String[] { IndexDatabase.INDEX_DIR, IndexDatabase.XREF_DIR }) {
IOUtils.removeRecursive(Paths.get(env.getDataRootPath() + File.separator + dirName + File.separator + projectName));
}
HistoryGuru guru = HistoryGuru.getInstance();
guru.removeCache(repos.stream().map((x) -> {
try {
return env.getPathRelativeToSourceRoot(new File((x).getDirectoryName()));
} catch (ForbiddenSymlinkException e) {
LOGGER.log(Level.FINER, e.getMessage());
return "";
} catch (IOException e) {
LOGGER.log(Level.INFO, "cannot remove files for repository {0}", x.getDirectoryName());
// {@code removeCache()} will return nothing.
return "";
}
}).collect(Collectors.toSet()));
}
break;
case "indexed":
for (String projectName : getTags()) {
Project project;
if ((project = env.getProjects().get(projectName)) != null) {
project.setIndexed(true);
// Refresh current version of the project's repositories.
List<RepositoryInfo> riList = env.getProjectRepositoriesMap().get(project);
if (riList != null) {
for (RepositoryInfo ri : riList) {
Repository repo = getRepository(ri);
if (repo != null && repo.getCurrentVersion() != null && repo.getCurrentVersion().length() > 0) {
// getRepository() always creates fresh instance
// of the Repository object so there is no need
// to call setCurrentVersion() on it.
ri.setCurrentVersion(repo.determineCurrentVersion());
}
}
}
} else {
LOGGER.log(Level.WARNING, "cannot find project " + projectName + " to mark as indexed");
}
}
// In case this project has just been incrementally indexed,
// its IndexSearcher needs a poke.
env.maybeRefreshIndexSearchers(getTags());
env.refreshDateForLastIndexRun();
break;
case "list":
return (env.getProjectNames().stream().collect(Collectors.joining("\n")).getBytes());
case "list-indexed":
return (env.getProjectList().stream().filter(p -> p.isIndexed()).map(p -> p.getName()).collect(Collectors.joining("\n")).getBytes());
case "get-repos":
List<String> repos = new ArrayList<>();
for (String projectName : getTags()) {
Project project;
if ((project = env.getProjects().get(projectName)) == null) {
continue;
}
List<RepositoryInfo> infos = env.getProjectRepositoriesMap().get(project);
if (infos != null) {
repos.addAll(infos.stream().map(ri -> ri.getDirectoryNameRelative()).collect(Collectors.toList()));
}
}
return repos.stream().collect(Collectors.joining("\n")).getBytes();
case "get-repos-type":
Set<String> types = new TreeSet<>();
for (String projectName : getTags()) {
Project project;
if ((project = env.getProjects().get(projectName)) == null) {
continue;
}
List<RepositoryInfo> infos = env.getProjectRepositoriesMap().get(project);
if (infos != null) {
types.addAll(infos.stream().map(ri -> ri.getType()).collect(Collectors.toList()));
}
}
return types.stream().collect(Collectors.joining("\n")).getBytes();
}
return ("command \"" + getText() + "\" for projects " + String.join(",", getTags()) + " done").getBytes();
}
use of org.opensolaris.opengrok.util.ForbiddenSymlinkException in project OpenGrok by OpenGrok.
the class RuntimeEnvironmentTest method testGetPathRelativeToSourceRoot.
/**
* Verify that getPathRelativeToSourceRoot() returns path relative to
* source root for both directories and symbolic links.
* @throws java.io.IOException
*/
@Test
public void testGetPathRelativeToSourceRoot() throws IOException, ForbiddenSymlinkException {
RuntimeEnvironment env = RuntimeEnvironment.getInstance();
// Create and set source root.
File sourceRoot = FileUtilities.createTemporaryDirectory("src");
assertTrue(sourceRoot.exists());
assertTrue(sourceRoot.isDirectory());
env.setSourceRoot(sourceRoot.getPath());
// Create directory underneath source root and check.
String filename = "foo";
File file = new File(env.getSourceRootFile(), filename);
file.createNewFile();
assertTrue(file.exists());
assertEquals(File.separator + filename, env.getPathRelativeToSourceRoot(file));
// Create symlink underneath source root.
String symlinkName = "symlink";
File realDir = FileUtilities.createTemporaryDirectory("realdir");
File symlink = new File(sourceRoot, symlinkName);
Files.createSymbolicLink(Paths.get(symlink.getPath()), Paths.get(realDir.getPath()));
assertTrue(symlink.exists());
env.setAllowedSymlinks(new HashSet<>());
ForbiddenSymlinkException expex = null;
try {
env.getPathRelativeToSourceRoot(symlink);
} catch (ForbiddenSymlinkException e) {
expex = e;
}
assertTrue("getPathRelativeToSourceRoot() should have thrown " + "IOexception for symlink that is not allowed", expex != null);
// Allow the symlink and retest.
env.setAllowedSymlinks(new HashSet<>(Arrays.asList(symlink.getPath())));
assertEquals(File.separator + symlinkName, env.getPathRelativeToSourceRoot(symlink));
// cleanup
IOUtils.removeRecursive(sourceRoot.toPath());
IOUtils.removeRecursive(realDir.toPath());
}
use of org.opensolaris.opengrok.util.ForbiddenSymlinkException in project OpenGrok by OpenGrok.
the class FileHistoryCache method storeFile.
/**
* Store history object (encoded as XML and compressed with gzip) in a file.
*
* @param history history object to store
* @param file file to store the history object into
* @param repo repository for the file
* @param mergeHistory whether to merge the history with existing or
* store the histNew as is
* @throws HistoryException
*/
private void storeFile(History histNew, File file, Repository repo, boolean mergeHistory) throws HistoryException {
File cacheFile;
try {
cacheFile = getCachedFile(file);
} catch (ForbiddenSymlinkException e) {
LOGGER.log(Level.FINER, e.getMessage());
return;
}
History history = histNew;
File dir = cacheFile.getParentFile();
if (!dir.isDirectory() && !dir.mkdirs()) {
throw new HistoryException("Unable to create cache directory '" + dir + "'.");
}
if (mergeHistory && cacheFile.exists()) {
history = mergeOldAndNewHistory(cacheFile, histNew, repo);
}
// In such case store at least new history as a best effort.
if (history != null) {
writeHistoryToFile(dir, history, cacheFile);
} else {
writeHistoryToFile(dir, histNew, cacheFile);
}
}
Aggregations