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