package uk.ac.ebi.fg.myequivalents.managers.impl.db; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.persistence.EntityManager; import javax.persistence.EntityTransaction; import uk.ac.ebi.fg.myequivalents.access_control.model.User.Role; import uk.ac.ebi.fg.myequivalents.dao.BackupDAO; import uk.ac.ebi.fg.myequivalents.managers.interfaces.BackupManager; import uk.ac.ebi.fg.myequivalents.managers.interfaces.EntityMappingSearchResult.Bundle; import uk.ac.ebi.fg.myequivalents.model.Describeable; /** * The implementation of {@link BackupManager} for the relational DB backend. * * @author brandizi * <dl><dt>Date:</dt><dd>20 Feb 2015</dd> * */ public class DbBackupManager extends DbMyEquivalentsManager implements BackupManager { /** * Wraps basic operations with transactional demarcation. */ protected static class TransactionalBackupDAO extends BackupDAO { public TransactionalBackupDAO ( EntityManager entityManager ) { super ( entityManager ); } /** * This initialises a JPA transaction, before invoking the superclass implementation. */ @Override public int upload ( InputStream input ) { EntityTransaction ts = this.entityManager.getTransaction (); ts.begin (); int result = super.upload ( input ); if ( ts.isActive () && !ts.getRollbackOnly () ) ts.commit (); return result; } /** * Calls {@link #commitCheckPoint(int)}. */ @Override protected void postUpload ( Describeable d, int itemCounter ) { commitCheckPoint ( itemCounter ); } /** * Calls {@link #commitCheckPoint(int)}. */ @Override protected void postUpload ( Bundle b, int itemCounter ) { commitCheckPoint ( itemCounter ); } /** * This commits the current transaction from time to time, and starts a new one afterwards. */ protected void commitCheckPoint ( int itemCounter ) { if ( itemCounter % 10000 == 0 ) { EntityTransaction ts = this.entityManager.getTransaction (); ts.commit (); ts.begin (); } } } protected BackupDAO bkpDao; protected DbBackupManager ( BackupDAO bkpDao, String email, String apiPassword ) { super ( bkpDao.getEntityManager (), email, apiPassword ); this.bkpDao = bkpDao; } public DbBackupManager ( EntityManager entityManager, String email, String apiPassword ) { this ( new TransactionalBackupDAO ( entityManager ), email, apiPassword ); } /** * Adds up root element tags for the output ( {@code <myequivalents-backup>} ). */ @Override public int dump ( OutputStream out, Integer offset, Integer limit ) { try { this.userDao.enforceRole ( Role.ADMIN ); out.write ( "<myequivalents-backup>\n".getBytes () ); int result = this.bkpDao.dump ( out, offset, limit ); out.write ( "</myequivalents-backup>\n".getBytes () ); return result; } catch ( IOException ex ) { throw new RuntimeException ( "Internal error: " + ex.getMessage (), ex ); } } /** * Checks that the current user is an {@link Role#ADMIN admin} and then invokes {@link TransactionalBackupDAO}. */ @Override public int upload ( InputStream in ) { this.userDao.enforceRole ( Role.ADMIN ); return this.bkpDao.upload ( in ); } }