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