001package org.nuxeo.ecm.platform.groups.audit.service.acl.job;
002
003import java.io.File;
004import java.io.IOException;
005
006import org.apache.commons.logging.Log;
007import org.apache.commons.logging.LogFactory;
008import org.nuxeo.ecm.core.api.Blob;
009import org.nuxeo.ecm.core.api.Blobs;
010import org.nuxeo.ecm.core.api.DocumentModel;
011import org.nuxeo.ecm.core.api.IdRef;
012import org.nuxeo.ecm.core.api.impl.blob.FileBlob;
013import org.nuxeo.ecm.core.work.AbstractWork;
014import org.nuxeo.ecm.platform.groups.audit.service.acl.AclExcelLayoutBuilder;
015import org.nuxeo.ecm.platform.groups.audit.service.acl.IAclExcelLayoutBuilder;
016import org.nuxeo.ecm.platform.groups.audit.service.acl.ReportLayoutSettings;
017import org.nuxeo.ecm.platform.groups.audit.service.acl.filter.IContentFilter;
018import org.nuxeo.ecm.platform.groups.audit.service.acl.job.publish.IResultPublisher;
019import org.nuxeo.runtime.api.Framework;
020import org.nuxeo.runtime.transaction.TransactionHelper;
021
022public class AclAuditWork extends AbstractWork {
023
024    private static final long serialVersionUID = 1L;
025
026    private final static Log log = LogFactory.getLog(AclAuditWork.class);
027
028    public static final String PROPERTY_ACL_AUDIT_TIMEOUT = "nuxeo.audit.acl.timeout";
029
030    public static final int DEFAULT_TIMEOUT = 1200; // 20 min
031
032    public static final int UNDEFINED_TIMEOUT = -1;
033
034    protected String name;
035
036    protected int timeout;
037
038    protected IResultPublisher publisher;
039
040    protected File out;
041
042    /**
043     * Initialize a runnable Acl Audit process, and register this process in the {@link Work} instance that will execute
044     * it.
045     */
046    public AclAuditWork(String name, String repositoryName, String rootId, File out, IResultPublisher publisher) {
047        this(name, repositoryName, rootId, out, publisher, getAclAuditTimeoutFromProperties());
048    }
049
050    public static int getAclAuditTimeoutFromProperties() {
051        String v = Framework.getProperty(PROPERTY_ACL_AUDIT_TIMEOUT, UNDEFINED_TIMEOUT + "");
052        try {
053            return Integer.parseInt(v);
054        } catch (NumberFormatException e) {
055            return UNDEFINED_TIMEOUT;
056        }
057    }
058
059    /**
060     * Initialize a runnable Acl Audit process, and register this process in the {@link Work} instance that will execute
061     * it.
062     */
063    public AclAuditWork(String name, String repositoryName, String rootId, File out, IResultPublisher publisher,
064            int timeout) {
065        super(repositoryName + ':' + rootId + ":aclAudit");
066        setDocument(repositoryName, rootId, true);
067        this.name = name;
068        this.out = out;
069        this.publisher = publisher;
070        if (timeout == UNDEFINED_TIMEOUT) {
071            timeout = DEFAULT_TIMEOUT;
072        }
073        this.timeout = timeout;
074    }
075
076    @Override
077    public String getTitle() {
078        return name;
079    }
080
081    @Override
082    public void work() {
083        // use an explicit transaction timeout
084        if (TransactionHelper.isTransactionActiveOrMarkedRollback()) {
085            TransactionHelper.commitOrRollbackTransaction();
086            TransactionHelper.startTransaction(timeout);
087        }
088        setProgress(Progress.PROGRESS_0_PC);
089        initSession();
090        doAudit();
091        onAuditDone();
092        setProgress(Progress.PROGRESS_100_PC);
093    }
094
095    public void doAudit() {
096        // setup
097        ReportLayoutSettings s = AclExcelLayoutBuilder.defaultLayout();
098        s.setPageSize(1000);
099        IContentFilter filter = null;
100
101        // generate XLS report
102        log.debug("Start audit");
103        IAclExcelLayoutBuilder v = new AclExcelLayoutBuilder(s, filter);
104        DocumentModel root = session.getDocument(new IdRef(docId));
105        v.renderAudit(session, root, true, timeout);
106        log.debug("End audit");
107
108        // save
109        try {
110            v.getExcel().save(out);
111            log.debug("End save");
112        } catch (IOException e) {
113            throw new RuntimeException(e);
114        }
115    }
116
117    public void onAuditDone() {
118        try {
119            // content to send
120            Blob fb = Blobs.createBlob(getOutputFile(), "application/xls");
121            // do publish
122            publisher.publish(fb);
123        } catch (IOException e) {
124            log.error(e, e);
125        }
126    }
127
128    public File getOutputFile() {
129        return out;
130    }
131}