001/*
002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 *
009 * Contributors:
010 *     bstefanescu
011 */
012package org.nuxeo.ecm.automation.core.operations.services;
013
014import java.sql.Date;
015import java.sql.Timestamp;
016import java.util.List;
017import java.util.Map;
018
019import javax.persistence.EntityManager;
020import javax.persistence.Query;
021
022import net.sf.json.JSONArray;
023import net.sf.json.JSONObject;
024
025import org.nuxeo.ecm.automation.OperationContext;
026import org.nuxeo.ecm.automation.core.Constants;
027import org.nuxeo.ecm.automation.core.annotations.Context;
028import org.nuxeo.ecm.automation.core.annotations.Operation;
029import org.nuxeo.ecm.automation.core.annotations.OperationMethod;
030import org.nuxeo.ecm.automation.core.annotations.Param;
031import org.nuxeo.ecm.core.api.Blob;
032import org.nuxeo.ecm.core.api.Blobs;
033import org.nuxeo.ecm.core.persistence.PersistenceProvider;
034import org.nuxeo.ecm.core.persistence.PersistenceProvider.RunCallback;
035import org.nuxeo.ecm.core.persistence.PersistenceProviderFactory;
036import org.nuxeo.ecm.platform.audit.api.AuditReader;
037import org.nuxeo.ecm.platform.audit.api.LogEntry;
038import org.nuxeo.runtime.api.Framework;
039
040/**
041 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
042 */
043@Operation(id = AuditQuery.ID, category = Constants.CAT_SERVICES, label = "Query Audit Service", description = "Execute a JPA query against the Audit Service. This is returning a blob with the query result. The result is a serialized JSON array. You can use the context to set query variables but you must prefix using 'audit.query.' the context variable keys that match the ones in the query.", addToStudio = false)
044public class AuditQuery {
045
046    public static final String ID = "Audit.Query";
047
048    @Context
049    protected AuditReader audit;
050
051    @Context
052    protected OperationContext ctx;
053
054    @Param(name = "query", required = true, widget = Constants.W_MULTILINE_TEXT)
055    protected String query;
056
057    @Param(name = "pageNo", required = false)
058    protected int pageNo = 1;
059
060    @Param(name = "maxResults", required = false)
061    protected int maxResults;
062
063    @OperationMethod
064    public Blob run() {
065        List<LogEntry> result = query();
066        JSONArray rows = new JSONArray();
067        for (LogEntry entry : result) {
068            JSONObject obj = new JSONObject();
069            obj.element("eventId", entry.getEventId());
070            obj.element("category", entry.getCategory());
071            obj.element("eventDate", entry.getEventDate().getTime());
072            obj.element("principal", entry.getPrincipalName());
073            obj.element("docUUID", entry.getDocUUID());
074            obj.element("docType", entry.getDocType());
075            obj.element("docPath", entry.getDocPath());
076            obj.element("docLifeCycle", entry.getDocLifeCycle());
077            obj.element("repoId", entry.getRepositoryId());
078            obj.element("comment", entry.getComment());
079            // Map<String, ExtendedInfo> info = entry.getExtendedInfos();
080            // if (info != null) {
081            // info.get
082            // }
083            rows.add(obj);
084        }
085        return Blobs.createBlob(rows.toString(), "application/json");
086    }
087
088    public List<LogEntry> query() {
089        PersistenceProviderFactory pf = Framework.getService(PersistenceProviderFactory.class);
090        PersistenceProvider provider = pf.newProvider("nxaudit-logs");
091        return provider.run(false, new RunCallback<List<LogEntry>>() {
092            @Override
093            @SuppressWarnings("unchecked")
094            public List<LogEntry> runWith(EntityManager em) {
095                Query q = em.createQuery(query);
096                if (maxResults > 0) {
097                    q.setMaxResults(maxResults);
098                    q.setFirstResult((pageNo - 1) * maxResults);
099                }
100                for (Map.Entry<String, Object> entry : ctx.entrySet()) {
101                    String key = entry.getKey();
102                    if (key.startsWith("audit.query.")) {
103                        setQueryParam(q, key.substring("audit.query.".length()), entry.getValue());
104                    }
105                }
106                return q.getResultList();
107            }
108        });
109
110    }
111
112    protected void setQueryParam(Query q, String key, Object value) {
113        if (value instanceof String) {
114            String v = (String) value;
115            if (v.startsWith("{d ") && v.endsWith("}")) {
116                v = v.substring(3, v.length() - 1).trim();
117                int i = v.indexOf(' ');
118                if (i == -1) {
119                    Date date = Date.valueOf(v);
120                    q.setParameter(key, date);
121                } else {
122                    Timestamp ts = Timestamp.valueOf(v);
123                    q.setParameter(key, ts);
124                }
125            } else {
126                q.setParameter(key, v);
127            }
128        } else {
129            q.setParameter(key, value);
130        }
131    }
132}