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