001/* 002 * (C) Copyright 2015-2017 Nuxeo (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 * Nicolas Chapurlat <nchapurlat@nuxeo.com> 018 */ 019 020package org.nuxeo.ecm.platform.audit.io; 021 022import static org.nuxeo.ecm.core.io.registry.reflect.Instantiations.SINGLETON; 023import static org.nuxeo.ecm.core.io.registry.reflect.Priorities.REFERENCE; 024import static org.nuxeo.ecm.platform.audit.api.BuiltinLogEntryData.LOG_CATEGORY; 025import static org.nuxeo.ecm.platform.audit.api.BuiltinLogEntryData.LOG_COMMENT; 026import static org.nuxeo.ecm.platform.audit.api.BuiltinLogEntryData.LOG_DOC_LIFE_CYCLE; 027import static org.nuxeo.ecm.platform.audit.api.BuiltinLogEntryData.LOG_DOC_PATH; 028import static org.nuxeo.ecm.platform.audit.api.BuiltinLogEntryData.LOG_DOC_TYPE; 029import static org.nuxeo.ecm.platform.audit.api.BuiltinLogEntryData.LOG_DOC_UUID; 030import static org.nuxeo.ecm.platform.audit.api.BuiltinLogEntryData.LOG_EVENT_DATE; 031import static org.nuxeo.ecm.platform.audit.api.BuiltinLogEntryData.LOG_EVENT_ID; 032import static org.nuxeo.ecm.platform.audit.api.BuiltinLogEntryData.LOG_EXTENDED; 033import static org.nuxeo.ecm.platform.audit.api.BuiltinLogEntryData.LOG_ID; 034import static org.nuxeo.ecm.platform.audit.api.BuiltinLogEntryData.LOG_LOG_DATE; 035import static org.nuxeo.ecm.platform.audit.api.BuiltinLogEntryData.LOG_PRINCIPAL_NAME; 036import static org.nuxeo.ecm.platform.audit.api.BuiltinLogEntryData.LOG_REPOSITORY_ID; 037 038import java.io.IOException; 039import java.io.Serializable; 040import java.util.Date; 041import java.util.Map; 042 043import org.joda.time.DateTime; 044import org.joda.time.format.DateTimeFormatter; 045import org.joda.time.format.ISODateTimeFormat; 046import org.nuxeo.ecm.core.io.marshallers.json.ExtensibleEntityJsonWriter; 047import org.nuxeo.ecm.core.io.marshallers.json.enrichers.AbstractJsonEnricher; 048import org.nuxeo.ecm.core.io.registry.reflect.Setup; 049import org.nuxeo.ecm.platform.audit.api.ExtendedInfo; 050import org.nuxeo.ecm.platform.audit.api.LogEntry; 051 052import com.fasterxml.jackson.core.JsonGenerator; 053 054/** 055 * Convert {@link LogEntry} to Json. 056 * <p> 057 * This marshaller is enrichable: register class implementing {@link AbstractJsonEnricher} and managing {@link LogEntry} 058 * . 059 * </p> 060 * <p> 061 * This marshaller is also extensible: extend it and simply override 062 * {@link ExtensibleEntityJsonWriter#extend(Object, JsonGenerator)}. 063 * </p> 064 * <p> 065 * Format is: 066 * 067 * <pre> 068 * {@code 069 * { 070 * "entity-type":"logEntry", 071 * "category": "LOG_ENTRY_CATEGORY", 072 * "principalName": "LOG_ENTRY_PRINCIPAL", 073 * "comment": "LOG_ENTRY_COMMENT", 074 * "docLifeCycle": "DOC_LIFECYCLE", 075 * "docPath": "DOC_PATH", 076 * "docType": "DOC_TYPE", 077 * "docUUID": "DOC_UUID", 078 * "eventId": "EVENT_ID", 079 * "repositoryId": "REPO_ID", 080 * "eventDate": "LOG_EVENT_DATE", 081 * "logDate": "LOG_DATE" 082 * <-- contextParameters if there are enrichers activated 083 * <-- additional property provided by extend() method 084 * } 085 * </pre> 086 * 087 * </p> 088 * 089 * @since 7.2 090 */ 091@Setup(mode = SINGLETON, priority = REFERENCE) 092public class LogEntryJsonWriter extends ExtensibleEntityJsonWriter<LogEntry> { 093 094 public static final String ENTITY_TYPE = "logEntry"; 095 096 public LogEntryJsonWriter() { 097 super(ENTITY_TYPE, LogEntry.class); 098 } 099 100 @Override 101 protected void writeEntityBody(LogEntry logEntry, JsonGenerator jg) throws IOException { 102 jg.writeNumberField(LOG_ID, logEntry.getId()); 103 jg.writeStringField(LOG_CATEGORY, logEntry.getCategory()); 104 jg.writeStringField(LOG_PRINCIPAL_NAME, logEntry.getPrincipalName()); 105 jg.writeStringField(LOG_COMMENT, logEntry.getComment()); 106 jg.writeStringField(LOG_DOC_LIFE_CYCLE, logEntry.getDocLifeCycle()); 107 jg.writeStringField(LOG_DOC_PATH, logEntry.getDocPath()); 108 jg.writeStringField(LOG_DOC_TYPE, logEntry.getDocType()); 109 jg.writeStringField(LOG_DOC_UUID, logEntry.getDocUUID()); 110 jg.writeStringField(LOG_EVENT_ID, logEntry.getEventId()); 111 jg.writeStringField(LOG_REPOSITORY_ID, logEntry.getRepositoryId()); 112 DateTimeFormatter dateTime = ISODateTimeFormat.dateTime(); 113 jg.writeStringField(LOG_EVENT_DATE, dateTime.print(new DateTime(logEntry.getEventDate()))); 114 jg.writeStringField(LOG_LOG_DATE, dateTime.print(new DateTime(logEntry.getLogDate()))); 115 writeExtendedInfos(jg, logEntry); 116 } 117 118 protected void writeExtendedInfos(JsonGenerator jg, LogEntry logEntry) throws IOException { 119 Map<String, ExtendedInfo> extended = logEntry.getExtendedInfos(); 120 jg.writeObjectFieldStart(LOG_EXTENDED); 121 for (String key : extended.keySet()) { 122 ExtendedInfo ei = extended.get(key); 123 if (ei != null && ei.getSerializableValue() != null) { 124 writeExtendedInfo(jg, key, ei.getSerializableValue()); 125 } else { 126 jg.writeNullField(key); 127 } 128 } 129 jg.writeEndObject(); 130 } 131 132 protected void writeExtendedInfo(JsonGenerator jg, String key, Serializable value) throws IOException { 133 Class<?> clazz = value.getClass(); 134 if (Long.class.isAssignableFrom(clazz)) { 135 jg.writeNumberField(key, (Long) value); 136 } else if (Integer.class.isAssignableFrom(clazz)) { 137 jg.writeNumberField(key, (Integer) value); 138 } else if (Double.class.isAssignableFrom(clazz)) { 139 jg.writeNumberField(key, (Double) value); 140 } else if (Date.class.isAssignableFrom(clazz)) { 141 jg.writeStringField(key, ISODateTimeFormat.dateTime().print(new DateTime(value))); 142 } else if (String.class.isAssignableFrom(clazz)) { 143 jg.writeStringField(key, (String) value); 144 } else if (Boolean.class.isAssignableFrom(clazz)) { 145 jg.writeBooleanField(key, (Boolean) value); 146 } else { 147 jg.writeStringField(key, value.toString()); 148 } 149 } 150 151}