001/*
002 * (C) Copyright 2006-2016 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 *     Thierry Delprat
018 */
019package org.nuxeo.ecm.platform.audit.service;
020
021import java.io.Serializable;
022import java.util.Date;
023import java.util.List;
024import java.util.Map;
025
026import javax.persistence.EntityManager;
027
028import org.nuxeo.ecm.core.persistence.PersistenceProvider;
029import org.nuxeo.ecm.core.persistence.PersistenceProvider.RunCallback;
030import org.nuxeo.ecm.core.persistence.PersistenceProvider.RunVoid;
031import org.nuxeo.ecm.core.persistence.PersistenceProviderFactory;
032import org.nuxeo.ecm.platform.audit.api.ExtendedInfo;
033import org.nuxeo.ecm.platform.audit.api.FilterMapEntry;
034import org.nuxeo.ecm.platform.audit.api.LogEntry;
035import org.nuxeo.ecm.platform.audit.impl.ExtendedInfoImpl;
036import org.nuxeo.ecm.platform.audit.service.extension.AuditBackendDescriptor;
037import org.nuxeo.runtime.api.Framework;
038import org.nuxeo.runtime.model.DefaultComponent;
039import org.nuxeo.runtime.transaction.TransactionHelper;
040
041/**
042 * Contains the Hibernate based (legacy) implementation
043 *
044 * @author tiry
045 */
046public class DefaultAuditBackend extends AbstractAuditBackend {
047
048    protected PersistenceProvider persistenceProvider;
049
050    public DefaultAuditBackend(NXAuditEventsService component, AuditBackendDescriptor config) {
051        super(component, config);
052        activatePersistenceProvider();
053    }
054
055    @Override
056    public int getApplicationStartedOrder() {
057        return ((DefaultComponent)Framework.getRuntime().getComponent("org.nuxeo.ecm.core.persistence.PersistenceComponent")).getApplicationStartedOrder()+1;
058    }
059
060    @Override
061    public void onApplicationStarted() {
062        activatePersistenceProvider();
063    }
064
065    @Override
066    public void onShutdown() {
067        try {
068            persistenceProvider.closePersistenceUnit();
069        } finally {
070            persistenceProvider = null;
071        }
072    }
073
074    // public for testing purpose !
075    public PersistenceProvider getOrCreatePersistenceProvider() {
076        if (persistenceProvider == null) {
077            activatePersistenceProvider();
078        }
079        return persistenceProvider;
080    }
081
082    protected void activatePersistenceProvider() {
083        Thread thread = Thread.currentThread();
084        ClassLoader last = thread.getContextClassLoader();
085        try {
086            thread.setContextClassLoader(PersistenceProvider.class.getClassLoader());
087            PersistenceProviderFactory persistenceProviderFactory = Framework.getLocalService(PersistenceProviderFactory.class);
088            persistenceProvider = persistenceProviderFactory.newProvider("nxaudit-logs");
089            persistenceProvider.openPersistenceUnit();
090        } finally {
091            thread.setContextClassLoader(last);
092        }
093    }
094
095    @Override
096    public void addLogEntries(final List<LogEntry> entries) {
097        if (entries.isEmpty()) {
098            return;
099        }
100        if (!TransactionHelper.isTransactionActiveOrMarkedRollback()) {
101            TransactionHelper.startTransaction();
102            try {
103                getOrCreatePersistenceProvider().run(true, new RunVoid() {
104                    @Override
105                    public void runWith(EntityManager em) {
106                        addLogEntries(em, entries);
107                    }
108                });
109            } finally {
110                TransactionHelper.commitOrRollbackTransaction();
111            }
112            return;
113        }
114        getOrCreatePersistenceProvider().run(true, new RunVoid() {
115            @Override
116            public void runWith(EntityManager em) {
117                addLogEntries(em, entries);
118            }
119        });
120    }
121
122    protected void addLogEntries(EntityManager em, List<LogEntry> entries) {
123        LogEntryProvider.createProvider(em).addLogEntries(entries);
124    }
125
126    @Override
127    public List<LogEntry> getLogEntriesFor(final String uuid) {
128        return getOrCreatePersistenceProvider().run(false, new RunCallback<List<LogEntry>>() {
129            @Override
130            public List<LogEntry> runWith(EntityManager em) {
131                return getLogEntriesFor(em, uuid);
132            }
133        });
134    }
135
136    protected List<LogEntry> getLogEntriesFor(EntityManager em, String uuid) {
137        return LogEntryProvider.createProvider(em).getLogEntriesFor(uuid);
138    }
139
140    @Override
141    public List<LogEntry> getLogEntriesFor(final String uuid, final Map<String, FilterMapEntry> filterMap,
142            final boolean doDefaultSort) {
143        return getOrCreatePersistenceProvider().run(false, new RunCallback<List<LogEntry>>() {
144            @Override
145            public List<LogEntry> runWith(EntityManager em) {
146                return getLogEntriesFor(em, uuid, filterMap, doDefaultSort);
147            }
148        });
149    }
150
151    protected List<LogEntry> getLogEntriesFor(EntityManager em, String uuid, Map<String, FilterMapEntry> filterMap,
152            boolean doDefaultSort) {
153        return LogEntryProvider.createProvider(em).getLogEntriesFor(uuid, filterMap, doDefaultSort);
154    }
155
156    @Override
157    public LogEntry getLogEntryByID(final long id) {
158        return getOrCreatePersistenceProvider().run(false, new RunCallback<LogEntry>() {
159            @Override
160            public LogEntry runWith(EntityManager em) {
161                return getLogEntryByID(em, id);
162            }
163        });
164    }
165
166    protected LogEntry getLogEntryByID(EntityManager em, long id) {
167        return LogEntryProvider.createProvider(em).getLogEntryByID(id);
168    }
169
170    @Override
171    public List<LogEntry> nativeQueryLogs(final String whereClause, final int pageNb, final int pageSize) {
172        return getOrCreatePersistenceProvider().run(false, new RunCallback<List<LogEntry>>() {
173            @Override
174            public List<LogEntry> runWith(EntityManager em) {
175                return nativeQueryLogs(em, whereClause, pageNb, pageSize);
176            }
177        });
178    }
179
180    protected List<LogEntry> nativeQueryLogs(EntityManager em, String whereClause, int pageNb, int pageSize) {
181        return LogEntryProvider.createProvider(em).nativeQueryLogs(whereClause, pageNb, pageSize);
182    }
183
184    @Override
185    public List<?> nativeQuery(final String query, final int pageNb, final int pageSize) {
186        return getOrCreatePersistenceProvider().run(false, new RunCallback<List<?>>() {
187            @Override
188            public List<?> runWith(EntityManager em) {
189                return nativeQuery(em, query, pageNb, pageSize);
190            }
191        });
192    }
193
194    protected List<?> nativeQuery(EntityManager em, String query, int pageNb, int pageSize) {
195        return LogEntryProvider.createProvider(em).nativeQuery(query, pageNb, pageSize);
196    }
197
198    @Override
199    public List<?> nativeQuery(final String query, final Map<String, Object> params, final int pageNb,
200            final int pageSize) {
201        return getOrCreatePersistenceProvider().run(false, new RunCallback<List<?>>() {
202            @Override
203            public List<?> runWith(EntityManager em) {
204                return nativeQuery(em, query, params, pageNb, pageSize);
205            }
206        });
207    }
208
209    protected List<?> nativeQuery(EntityManager em, String query, Map<String, Object> params, int pageNb, int pageSize) {
210        return LogEntryProvider.createProvider(em).nativeQuery(query, params, pageNb, pageSize);
211    }
212
213    @Override
214    public List<LogEntry> queryLogs(final String[] eventIds, final String dateRange) {
215        return getOrCreatePersistenceProvider().run(false, new RunCallback<List<LogEntry>>() {
216            @Override
217            public List<LogEntry> runWith(EntityManager em) {
218                return queryLogs(em, eventIds, dateRange);
219            }
220        });
221    }
222
223    protected List<LogEntry> queryLogs(EntityManager em, String[] eventIds, String dateRange) {
224        return LogEntryProvider.createProvider(em).queryLogs(eventIds, dateRange);
225    }
226
227    @Override
228    public List<LogEntry> queryLogsByPage(final String[] eventIds, final String dateRange, final String[] category,
229            final String path, final int pageNb, final int pageSize) {
230        return getOrCreatePersistenceProvider().run(false, new RunCallback<List<LogEntry>>() {
231            @Override
232            public List<LogEntry> runWith(EntityManager em) {
233                return queryLogsByPage(em, eventIds, dateRange, category, path, pageNb, pageSize);
234            }
235        });
236    }
237
238    protected List<LogEntry> queryLogsByPage(EntityManager em, String[] eventIds, String dateRange, String[] category,
239            String path, int pageNb, int pageSize) {
240        return LogEntryProvider.createProvider(em).queryLogsByPage(eventIds, dateRange, category, path, pageNb,
241                pageSize);
242    }
243
244    @Override
245    public List<LogEntry> queryLogsByPage(final String[] eventIds, final Date limit, final String[] category,
246            final String path, final int pageNb, final int pageSize) {
247        return getOrCreatePersistenceProvider().run(false, new RunCallback<List<LogEntry>>() {
248            @Override
249            public List<LogEntry> runWith(EntityManager em) {
250                return queryLogsByPage(em, eventIds, limit, category, path, pageNb, pageSize);
251            }
252        });
253    }
254
255    protected List<LogEntry> queryLogsByPage(EntityManager em, String[] eventIds, Date limit, String[] category,
256            String path, int pageNb, int pageSize) {
257        return LogEntryProvider.createProvider(em).queryLogsByPage(eventIds, limit, category, path, pageNb, pageSize);
258    }
259
260    @Override
261    public long syncLogCreationEntries(final String repoId, final String path, final Boolean recurs) {
262        return getOrCreatePersistenceProvider().run(true, new RunCallback<Long>() {
263            @Override
264            public Long runWith(EntityManager em) {
265                return syncLogCreationEntries(em, repoId, path, recurs);
266            }
267        });
268    }
269
270    protected long syncLogCreationEntries(EntityManager em, String repoId, String path, Boolean recurs) {
271        LogEntryProvider provider = LogEntryProvider.createProvider(em);
272        return syncLogCreationEntries(provider, repoId, path, recurs);
273    }
274
275    @Override
276    public Long getEventsCount(final String eventId) {
277        return getOrCreatePersistenceProvider().run(false, new RunCallback<Long>() {
278            @Override
279            public Long runWith(EntityManager em) {
280                return getEventsCount(em, eventId);
281            }
282
283        });
284    }
285
286    public Long getEventsCount(EntityManager em, String eventId) {
287        return LogEntryProvider.createProvider(em).countEventsById(eventId);
288    }
289
290    public List<String> getLoggedEventIds() {
291        return getOrCreatePersistenceProvider().run(false, new RunCallback<List<String>>() {
292            @Override
293            public List<String> runWith(EntityManager em) {
294                return getLoggedEventIds(em);
295            }
296
297        });
298    }
299
300    protected List<String> getLoggedEventIds(EntityManager em) {
301        return LogEntryProvider.createProvider(em).findEventIds();
302    }
303
304    // Compat APIs
305
306    protected List<LogEntry> queryLogsByPage(EntityManager em, String[] eventIds, String dateRange, String category,
307            String path, int pageNb, int pageSize) {
308        String[] categories = { category };
309        return queryLogsByPage(em, eventIds, dateRange, categories, path, pageNb, pageSize);
310    }
311
312    protected List<LogEntry> queryLogsByPage(EntityManager em, String[] eventIds, Date limit, String category,
313            String path, int pageNb, int pageSize) {
314        String[] categories = { category };
315        return queryLogsByPage(em, eventIds, limit, categories, path, pageNb, pageSize);
316    }
317
318    @Override
319    public ExtendedInfo newExtendedInfo(Serializable value) {
320        return ExtendedInfoImpl.createExtendedInfo(value);
321    }
322
323}