001/*
002 * (C) Copyright 2015 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Florent Guillaume
018 */
019package org.nuxeo.ecm.platform.groups.audit.service.acl.job;
020
021import java.io.File;
022import java.io.IOException;
023
024import org.apache.commons.logging.Log;
025import org.apache.commons.logging.LogFactory;
026import org.nuxeo.ecm.core.api.Blob;
027import org.nuxeo.ecm.core.api.Blobs;
028import org.nuxeo.ecm.core.api.DocumentModel;
029import org.nuxeo.ecm.core.api.IdRef;
030import org.nuxeo.ecm.core.api.impl.blob.FileBlob;
031import org.nuxeo.ecm.core.work.AbstractWork;
032import org.nuxeo.ecm.platform.groups.audit.service.acl.AclExcelLayoutBuilder;
033import org.nuxeo.ecm.platform.groups.audit.service.acl.IAclExcelLayoutBuilder;
034import org.nuxeo.ecm.platform.groups.audit.service.acl.ReportLayoutSettings;
035import org.nuxeo.ecm.platform.groups.audit.service.acl.filter.IContentFilter;
036import org.nuxeo.ecm.platform.groups.audit.service.acl.job.publish.IResultPublisher;
037import org.nuxeo.runtime.api.Framework;
038import org.nuxeo.runtime.transaction.TransactionHelper;
039
040public class AclAuditWork extends AbstractWork {
041
042    private static final long serialVersionUID = 1L;
043
044    private final static Log log = LogFactory.getLog(AclAuditWork.class);
045
046    public static final String PROPERTY_ACL_AUDIT_TIMEOUT = "nuxeo.audit.acl.timeout";
047
048    public static final int DEFAULT_TIMEOUT = 1200; // 20 min
049
050    public static final int UNDEFINED_TIMEOUT = -1;
051
052    protected String name;
053
054    protected int timeout;
055
056    protected IResultPublisher publisher;
057
058    protected File out;
059
060    /**
061     * Initialize a runnable Acl Audit process, and register this process in the {@link Work} instance that will execute
062     * it.
063     */
064    public AclAuditWork(String name, String repositoryName, String rootId, File out, IResultPublisher publisher) {
065        this(name, repositoryName, rootId, out, publisher, getAclAuditTimeoutFromProperties());
066    }
067
068    public static int getAclAuditTimeoutFromProperties() {
069        String v = Framework.getProperty(PROPERTY_ACL_AUDIT_TIMEOUT, UNDEFINED_TIMEOUT + "");
070        try {
071            return Integer.parseInt(v);
072        } catch (NumberFormatException e) {
073            return UNDEFINED_TIMEOUT;
074        }
075    }
076
077    /**
078     * Initialize a runnable Acl Audit process, and register this process in the {@link Work} instance that will execute
079     * it.
080     */
081    public AclAuditWork(String name, String repositoryName, String rootId, File out, IResultPublisher publisher,
082            int timeout) {
083        super(repositoryName + ':' + rootId + ":aclAudit");
084        setDocument(repositoryName, rootId, true);
085        this.name = name;
086        this.out = out;
087        this.publisher = publisher;
088        if (timeout == UNDEFINED_TIMEOUT) {
089            timeout = DEFAULT_TIMEOUT;
090        }
091        this.timeout = timeout;
092    }
093
094    @Override
095    public String getTitle() {
096        return name;
097    }
098
099    @Override
100    public void work() {
101        // use an explicit transaction timeout
102        if (TransactionHelper.isTransactionActiveOrMarkedRollback()) {
103            TransactionHelper.commitOrRollbackTransaction();
104            TransactionHelper.startTransaction(timeout);
105        }
106        setProgress(Progress.PROGRESS_0_PC);
107        openSystemSession();
108        doAudit();
109        onAuditDone();
110        setProgress(Progress.PROGRESS_100_PC);
111    }
112
113    public void doAudit() {
114        // setup
115        ReportLayoutSettings s = AclExcelLayoutBuilder.defaultLayout();
116        s.setPageSize(1000);
117        IContentFilter filter = null;
118
119        // generate XLS report
120        log.debug("Start audit");
121        IAclExcelLayoutBuilder v = new AclExcelLayoutBuilder(s, filter);
122        DocumentModel root = session.getDocument(new IdRef(docId));
123        v.renderAudit(session, root, true, timeout);
124        log.debug("End audit");
125
126        // save
127        try {
128            v.getExcel().save(out);
129            log.debug("End save");
130        } catch (IOException e) {
131            throw new RuntimeException(e);
132        }
133    }
134
135    public void onAuditDone() {
136        try {
137            // content to send
138            Blob fb = Blobs.createBlob(getOutputFile(), "application/xls");
139            // do publish
140            publisher.publish(fb);
141        } catch (IOException e) {
142            log.error(e, e);
143        }
144    }
145
146    public File getOutputFile() {
147        return out;
148    }
149}