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}