| | |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | import java.util.TreeSet; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | import java.util.concurrent.atomic.AtomicLong; |
| | | |
| | |
| | | import com.gitblit.utils.ArrayUtils; |
| | | import com.gitblit.utils.FileUtils; |
| | | import com.gitblit.utils.StringUtils; |
| | | import com.google.inject.Inject; |
| | | import com.google.inject.Singleton; |
| | | |
| | | /** |
| | | * Implementation of a ticket service based on a directory within the repository. |
| | |
| | | * @author James Moger |
| | | * |
| | | */ |
| | | @Singleton |
| | | public class FileTicketService extends ITicketService { |
| | | |
| | | private static final String JOURNAL = "journal.json"; |
| | |
| | | |
| | | private final Map<String, AtomicLong> lastAssignedId; |
| | | |
| | | @Inject |
| | | public FileTicketService( |
| | | IRuntimeManager runtimeManager, |
| | | IPluginManager pluginManager, |
| | |
| | | |
| | | @Override |
| | | public FileTicketService start() { |
| | | log.info("{} started", getClass().getSimpleName()); |
| | | return this; |
| | | } |
| | | |
| | |
| | | return hasTicket; |
| | | } |
| | | |
| | | @Override |
| | | public synchronized Set<Long> getIds(RepositoryModel repository) { |
| | | Set<Long> ids = new TreeSet<Long>(); |
| | | Repository db = repositoryManager.getRepository(repository.name); |
| | | try { |
| | | // identify current highest ticket id by scanning the paths in the tip tree |
| | | File dir = new File(db.getDirectory(), TICKETS_PATH); |
| | | dir.mkdirs(); |
| | | List<File> journals = findAll(dir, JOURNAL); |
| | | for (File journal : journals) { |
| | | // Reconstruct ticketId from the path |
| | | // id/26/326/journal.json |
| | | String path = FileUtils.getRelativePath(dir, journal); |
| | | String tid = path.split("/")[1]; |
| | | long ticketId = Long.parseLong(tid); |
| | | ids.add(ticketId); |
| | | } |
| | | } finally { |
| | | if (db != null) { |
| | | db.close(); |
| | | } |
| | | } |
| | | return ids; |
| | | } |
| | | |
| | | /** |
| | | * Assigns a new ticket id. |
| | | * |
| | |
| | | } |
| | | AtomicLong lastId = lastAssignedId.get(repository.name); |
| | | if (lastId.get() <= 0) { |
| | | // identify current highest ticket id by scanning the paths in the tip tree |
| | | File dir = new File(db.getDirectory(), TICKETS_PATH); |
| | | dir.mkdirs(); |
| | | List<File> journals = findAll(dir, JOURNAL); |
| | | for (File journal : journals) { |
| | | // Reconstruct ticketId from the path |
| | | // id/26/326/journal.json |
| | | String path = FileUtils.getRelativePath(dir, journal); |
| | | String tid = path.split("/")[1]; |
| | | long ticketId = Long.parseLong(tid); |
| | | if (ticketId > lastId.get()) { |
| | | lastId.set(ticketId); |
| | | Set<Long> ids = getIds(repository); |
| | | for (long id : ids) { |
| | | if (id > lastId.get()) { |
| | | lastId.set(id); |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | /** |
| | | * Retrieves the ticket from the repository by first looking-up the changeId |
| | | * associated with the ticketId. |
| | | * Retrieves the ticket from the repository. |
| | | * |
| | | * @param repository |
| | | * @param ticketId |
| | |
| | | ticket.number = ticketId; |
| | | } |
| | | return ticket; |
| | | } finally { |
| | | db.close(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Retrieves the journal for the ticket. |
| | | * |
| | | * @param repository |
| | | * @param ticketId |
| | | * @return a journal, if it exists, otherwise null |
| | | */ |
| | | @Override |
| | | protected List<Change> getJournalImpl(RepositoryModel repository, long ticketId) { |
| | | Repository db = repositoryManager.getRepository(repository.name); |
| | | try { |
| | | List<Change> changes = getJournal(db, ticketId); |
| | | if (ArrayUtils.isEmpty(changes)) { |
| | | log.warn("Empty journal for {}:{}", repository, ticketId); |
| | | return null; |
| | | } |
| | | return changes; |
| | | } finally { |
| | | db.close(); |
| | | } |
| | |
| | | @Override |
| | | protected boolean deleteAllImpl(RepositoryModel repository) { |
| | | Repository db = repositoryManager.getRepository(repository.name); |
| | | if (db == null) { |
| | | // the tickets no longer exist because the db no longer exists |
| | | return true; |
| | | } |
| | | try { |
| | | File dir = new File(db.getDirectory(), TICKETS_PATH); |
| | | return FileUtils.delete(dir); |