001/*
002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Julien Anguenot
016 *     Thierry Delprat
017 *     Florent Guillaume
018 */
019
020package org.nuxeo.ecm.platform.audit.impl;
021
022import java.util.Date;
023import java.util.HashMap;
024import java.util.Map;
025
026import javax.persistence.CascadeType;
027import javax.persistence.Column;
028import javax.persistence.Entity;
029import javax.persistence.GeneratedValue;
030import javax.persistence.GenerationType;
031import javax.persistence.Id;
032import javax.persistence.JoinColumn;
033import javax.persistence.JoinTable;
034import javax.persistence.MapKey;
035import javax.persistence.NamedQueries;
036import javax.persistence.NamedQuery;
037import javax.persistence.OneToMany;
038import javax.persistence.Table;
039import javax.persistence.Temporal;
040import javax.persistence.TemporalType;
041import javax.persistence.Transient;
042
043import org.apache.commons.lang.builder.ToStringBuilder;
044import org.nuxeo.ecm.core.api.DocumentRef;
045import org.nuxeo.ecm.platform.audit.api.ExtendedInfo;
046import org.nuxeo.ecm.platform.audit.api.LogEntry;
047import org.nuxeo.ecm.platform.audit.api.comment.UIAuditComment;
048
049/**
050 * Log entry implementation.
051 */
052@Entity(name = "LogEntry")
053@NamedQueries({
054        @NamedQuery(name = "LogEntry.removeByEventIdAndPath", query = "delete LogEntry log where log.eventId = :eventId and log.docPath like :pathPattern"),
055        @NamedQuery(name = "LogEntry.findByDocument", query = "from LogEntry log where log.docUUID=:docUUID ORDER BY log.eventDate DESC"),
056        @NamedQuery(name = "LogEntry.findAll", query = "from LogEntry log order by log.eventDate DESC"),
057        @NamedQuery(name = "LogEntry.findByEventIdAndPath", query = "from LogEntry log where log.eventId=:eventId and log.docPath LIKE :pathPattern"),
058        @NamedQuery(name = "LogEntry.findByHavingExtendedInfo", query = "from LogEntry log where log.extendedInfos['one'] is not null order by log.eventDate DESC"),
059        @NamedQuery(name = "LogEntry.countEventsById", query = "select count(log.eventId) from LogEntry log where log.eventId=:eventId"),
060        @NamedQuery(name = "LogEntry.findEventIds", query = "select distinct log.eventId from LogEntry log") })
061@Table(name = "NXP_LOGS")
062public class LogEntryImpl implements LogEntry {
063
064    private static final long serialVersionUID = 3037187381843636097L;
065
066    private long id;
067
068    private String principalName;
069
070    private String eventId;
071
072    private Date eventDate;
073
074    private Date logDate;
075
076    private String docUUID;
077
078    private String docType;
079
080    private String docPath;
081
082    private String category;
083
084    private String comment;
085
086    private String docLifeCycle;
087
088    private String repositoryId;
089
090    protected transient UIAuditComment uiComment;
091
092    private Map<String, ExtendedInfoImpl> extendedInfos = new HashMap<String, ExtendedInfoImpl>();
093
094    /**
095     * @return the log identifier
096     */
097    @Override
098    @Id
099    @GeneratedValue(strategy = GenerationType.AUTO)
100    @Column(name = "LOG_ID", nullable = false, columnDefinition = "integer")
101    public long getId() {
102        return id;
103    }
104
105    @Override
106    public void setId(long id) {
107        this.id = id;
108    }
109
110    /**
111     * Returns the name of the principal who originated the log entry.
112     *
113     * @return the name of the principal who originated the log entry
114     */
115    @Override
116    @Column(name = "LOG_PRINCIPAL_NAME")
117    public String getPrincipalName() {
118        return principalName;
119    }
120
121    @Override
122    public void setPrincipalName(String principalName) {
123        this.principalName = principalName;
124    }
125
126    /**
127     * Returns the identifier of the event that originated the log entry.
128     *
129     * @return the identifier of the event that originated the log entry
130     */
131    @Override
132    @Column(name = "LOG_EVENT_ID", nullable = false)
133    @MapKey(name = "logKey")
134    public String getEventId() {
135        return eventId;
136    }
137
138    @Override
139    public void setEventId(String eventId) {
140        this.eventId = eventId;
141    }
142
143    /**
144     * Returns the date of the event that originated the log entry.
145     *
146     * @return the date of the event that originated the log entry
147     */
148    @Override
149    @Temporal(TemporalType.TIMESTAMP)
150    @Column(name = "LOG_EVENT_DATE")
151    public Date getEventDate() {
152        return eventDate;
153    }
154
155    @Override
156    public void setEventDate(Date eventDate) {
157        this.eventDate = eventDate;
158    }
159
160    /**
161     * @return the date of the log insertion: this up to max transaction timeout later than eventDate. This date is
162     *         useful for services such as Nuxeo Drive that need fine grained incremental near-monotonic access to the
163     *         audit log.
164     * @since 5.7
165     * @since 5.6-HF16
166     */
167    @Override
168    @Temporal(TemporalType.TIMESTAMP)
169    @Column(name = "LOG_DATE")
170    public Date getLogDate() {
171        return logDate;
172    }
173
174    @Override
175    public void setLogDate(Date logDate) {
176        this.logDate = logDate;
177    }
178
179    /**
180     * Returns the doc UUID related to the log entry.
181     * <p>
182     * It might be null if the event that originated the event is noe bound to any document.
183     *
184     * @return the doc UUID related to the log entry.
185     */
186    @Override
187    @Column(name = "LOG_DOC_UUID")
188    public String getDocUUID() {
189        return docUUID;
190    }
191
192    @Override
193    public void setDocUUID(String docUUID) {
194        this.docUUID = docUUID;
195    }
196
197    @Override
198    public void setDocUUID(DocumentRef docRef) {
199        if (docRef.type() != DocumentRef.ID) {
200            throw new IllegalArgumentException("not an id reference " + docRef);
201        }
202        docUUID = (String) docRef.reference();
203    }
204
205    /**
206     * Returns the doc path related to the log entry.
207     * <p>
208     * It might be null if the event that originated the event is noe bound to any document.
209     *
210     * @return the doc path related to the log entry.
211     */
212    @Override
213    @Column(name = "LOG_DOC_PATH", length = 1024)
214    public String getDocPath() {
215        return docPath;
216    }
217
218    @Override
219    public void setDocPath(String docPath) {
220        this.docPath = docPath;
221    }
222
223    /**
224     * Returns the doc type related to the log entry.
225     * <p>
226     * It might be null if the event that originated the event is not bound to any document.
227     *
228     * @return the doc type related to the log entry.
229     */
230    @Override
231    @Column(name = "LOG_DOC_TYPE")
232    public String getDocType() {
233        return docType;
234    }
235
236    @Override
237    public void setDocType(String docType) {
238        this.docType = docType;
239    }
240
241    /**
242     * Returns the category for this log entry.
243     * <p>
244     * This is defined at client level. Categories are not restricted in any ways.
245     *
246     * @return the category for this log entry.
247     */
248    @Override
249    @Column(name = "LOG_EVENT_CATEGORY")
250    public String getCategory() {
251        return category;
252    }
253
254    @Override
255    public void setCategory(String category) {
256        this.category = category;
257    }
258
259    /**
260     * Returns the associated comment for this log entry.
261     *
262     * @return the associated comment for this log entry
263     */
264    @Override
265    @Column(name = "LOG_EVENT_COMMENT", length = 1024)
266    public String getComment() {
267        return comment;
268    }
269
270    @Override
271    public void setComment(String comment) {
272        this.comment = comment;
273    }
274
275    /**
276     * Return the life cycle if the document related to the log entry.
277     * <p>
278     * It might be null if the event that originated the event is noe bound to any document.
279     *
280     * @return the life cycle if the document related to the log entry.
281     */
282    @Override
283    @Column(name = "LOG_DOC_LIFE_CYCLE")
284    public String getDocLifeCycle() {
285        return docLifeCycle;
286    }
287
288    @Override
289    public void setDocLifeCycle(String docLifeCycle) {
290        this.docLifeCycle = docLifeCycle;
291    }
292
293    /**
294     * Returns the repository id related to the log entry.
295     *
296     * @return the repository id
297     */
298    @Override
299    @Column(name = "LOG_REPO_ID")
300    public String getRepositoryId() {
301        return repositoryId;
302    }
303
304    @Override
305    public void setRepositoryId(String repositoryId) {
306        this.repositoryId = repositoryId;
307    }
308
309    // public Map<String, ExtendedInfoImpl> getExtendedInfosImpl() {
310    // return extendedInfos;
311    // }
312    //
313    // public void setExtendedInfosImpl(Map<String, ExtendedInfoImpl> infos) {
314    // extendedInfos = infos;
315    // }
316
317    @Override
318    @OneToMany(cascade = CascadeType.ALL, targetEntity = ExtendedInfoImpl.class)
319    @JoinTable(name = "NXP_LOGS_MAPEXTINFOS", joinColumns = { @JoinColumn(name = "LOG_FK") }, inverseJoinColumns = { @JoinColumn(name = "INFO_FK") })
320    @org.hibernate.annotations.MapKey(columns = { @Column(name = "mapkey", nullable = false) })
321    public Map<String, ExtendedInfo> getExtendedInfos() {
322        return (Map) extendedInfos;
323        // return (Map)getExtendedInfosImpl();
324    }
325
326    @Override
327    public void setExtendedInfos(Map<String, ExtendedInfo> infos) {
328        extendedInfos = (Map) infos;
329        // setExtendedInfosImpl((Map)infos);
330    }
331
332    @Override
333    public String toString() {
334        return ToStringBuilder.reflectionToString(this);
335    }
336
337    @Transient
338    @Override
339    public UIAuditComment getPreprocessedComment() {
340        return uiComment;
341    }
342
343    @Override
344    public void setPreprocessedComment(UIAuditComment uiComment) {
345        this.uiComment = uiComment;
346    }
347
348}