<commit_before>package net.hillsdon.svnwiki.vc;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import org.tmatesoft.svn.core.ISVNLogEntryHandler;
import org.tmatesoft.svn.core.SVNAuthenticationException;
import org.tmatesoft.svn.core.SVNDirEntry;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNLogEntry;
import org.tmatesoft.svn.core.SVNNodeKind;
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
import org.tmatesoft.svn.core.io.ISVNEditor;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.diff.SVNDeltaGenerator;

/**
 * Provides exception translation and low-level functionality.
 * 
 * @author mth
 */
public class SVNHelper {

  public interface SVNAction<T> {
    T perform(SVNRepository repository) throws SVNException, PageStoreException;
  }
  
  private final SVNRepository _repository;

  public SVNHelper(final SVNRepository repository) {
    _repository = repository;
  }

  public List<ChangeInfo> log(final String path, final long limit, final boolean pathOnly, final long startRevision, long endRevision) throws SVNException {
    final String rootPath = getRoot();
    final List<ChangeInfo> entries = new LinkedList<ChangeInfo>();
    // Start and end reversed to get newest changes first.
    _repository.log(new String[] {path}, endRevision, startRevision, true, true, limit, new ISVNLogEntryHandler() {
      public void handleLogEntry(final SVNLogEntry logEntry) throws SVNException {
        entries.addAll(logEntryToChangeInfos(rootPath, path, logEntry));
      }
    });
    return entries;
  }
  
  public Collection<PageStoreEntry> listFiles(final String dir) throws SVNException {
    List<SVNDirEntry> entries = new ArrayList<SVNDirEntry>();
    _repository.getDir(dir, -1, false, entries);
    // Need order, contains() is a reasonable operation however.
    Set<PageStoreEntry> results = new LinkedHashSet<PageStoreEntry>(entries.size());
    for (SVNDirEntry e : entries) {
      if (SVNNodeKind.FILE.equals(e.getKind())) {
        results.add(new PageStoreEntry(e.getName(), e.getRevision()));
      }
    }
    return results;
  }

  @SuppressWarnings("unchecked")
  private List<ChangeInfo> logEntryToChangeInfos(final String rootPath, final String path, final SVNLogEntry entry) throws SVNException {
    List<ChangeInfo> results = new LinkedList<ChangeInfo>();
    String user = entry.getAuthor();
    Date date = entry.getDate();
    for (String changedPath : (Iterable<String>) entry.getChangedPaths().keySet()) {
      if (changedPath.length() > rootPath.length()) {
        String name = changedPath.substring(rootPath.length() + 1);
        results.add(new ChangeInfo(name, user, date, entry.getRevision(), entry.getMessage()));
      }
    }
    return results;
  }

  public String getRoot() throws SVNException {
    return _repository.getRepositoryPath("");
  }

  public <T> T execute(final SVNAction<T> action) throws PageStoreException, PageStoreAuthenticationException {
    try {
      return action.perform(_repository);
    }
    catch (SVNAuthenticationException ex) {<commit_msg>Consider attachment changes as changes to the corresponding page.<commit_after>package net.hillsdon.svnwiki.vc;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.tmatesoft.svn.core.ISVNLogEntryHandler;
import org.tmatesoft.svn.core.SVNAuthenticationException;
import org.tmatesoft.svn.core.SVNDirEntry;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNLogEntry;
import org.tmatesoft.svn.core.SVNNodeKind;
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
import org.tmatesoft.svn.core.io.ISVNEditor;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.diff.SVNDeltaGenerator;

/**
 * Provides exception translation and low-level functionality.
 * 
 * @author mth
 */
public class SVNHelper {

  public interface SVNAction<T> {
    T perform(SVNRepository repository) throws SVNException, PageStoreException;
  }
  
  private final SVNRepository _repository;

  public SVNHelper(final SVNRepository repository) {
    _repository = repository;
  }

  public List<ChangeInfo> log(final String path, final long limit, final boolean pathOnly, final long startRevision, long endRevision) throws SVNException {
    final String rootPath = getRoot();
    final List<ChangeInfo> entries = new LinkedList<ChangeInfo>();
    // Start and end reversed to get newest changes first.
    _repository.log(new String[] {path}, endRevision, startRevision, true, true, limit, new ISVNLogEntryHandler() {
      public void handleLogEntry(final SVNLogEntry logEntry) throws SVNException {
        entries.addAll(logEntryToChangeInfos(rootPath, path, logEntry));
      }
    });
    return entries;
  }
  
  public Collection<PageStoreEntry> listFiles(final String dir) throws SVNException {
    List<SVNDirEntry> entries = new ArrayList<SVNDirEntry>();
    _repository.getDir(dir, -1, false, entries);
    // Need order, contains() is a reasonable operation however.
    Set<PageStoreEntry> results = new LinkedHashSet<PageStoreEntry>(entries.size());
    for (SVNDirEntry e : entries) {
      if (SVNNodeKind.FILE.equals(e.getKind())) {
        results.add(new PageStoreEntry(e.getName(), e.getRevision()));
      }
    }
    return results;
  }

  private static final Pattern ATTACHMENT_PATH = Pattern.compile(".*/(.*?)-attachments/.*");
  
  @SuppressWarnings("unchecked")
  private List<ChangeInfo> logEntryToChangeInfos(final String rootPath, final String path, final SVNLogEntry entry) throws SVNException {
    List<ChangeInfo> results = new LinkedList<ChangeInfo>();
    String user = entry.getAuthor();
    Date date = entry.getDate();
    for (String changedPath : (Iterable<String>) entry.getChangedPaths().keySet()) {
      if (changedPath.length() > rootPath.length()) {
        String name = changedPath.substring(rootPath.length() + 1);
        Matcher matcher = ATTACHMENT_PATH.matcher(changedPath);
        if (matcher.matches()) {
          name = matcher.group(1);
        }
        results.add(new ChangeInfo(name, user, date, entry.getRevision(), entry.getMessage()));
      }
    }
    return results;
  }

  public String getRoot() throws SVNException {
    return _repository.getRepositoryPath("");
  }

  public <T> T execute(final SVNAction<T> action) throws PageStoreException, PageStoreAuthenticationException {
    try {
      return action.perform(_repository);
    }
    catch (SVNAuthenticationException ex) {
{'fraction_non_alphanumeric': 0.10771238040011598, 'fraction_numerical': 0.0007248477819657872, 'mean_word_length': 4.352211016291699, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '662909', 'n_tokens_mistral': 2079, 'n_tokens_neox': 2052, 'n_words': 485}