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