001package org.nuxeo.elasticsearch.audit.io;
002
003import java.io.IOException;
004import java.util.HashMap;
005import java.util.Iterator;
006import java.util.Map;
007
008import org.codehaus.jackson.JsonFactory;
009import org.codehaus.jackson.JsonNode;
010import org.codehaus.jackson.JsonParser;
011import org.codehaus.jackson.JsonToken;
012import org.codehaus.jackson.map.ObjectMapper;
013import org.codehaus.jackson.map.module.SimpleModule;
014import org.joda.time.format.ISODateTimeFormat;
015import org.nuxeo.ecm.core.api.impl.blob.AbstractBlob;
016import org.nuxeo.ecm.platform.audit.api.ExtendedInfo;
017import org.nuxeo.ecm.platform.audit.api.LogEntry;
018import org.nuxeo.ecm.platform.audit.impl.ExtendedInfoImpl;
019import org.nuxeo.ecm.platform.audit.impl.LogEntryImpl;
020import org.nuxeo.elasticsearch.audit.io.AuditEntryJSONWriter.BinaryBlobEntrySerializer;
021import org.nuxeo.elasticsearch.audit.io.AuditEntryJSONWriter.MapEntrySerializer;
022
023public class AuditEntryJSONReader {
024
025    public static LogEntry read(String content) throws IOException {
026
027        ObjectMapper objectMapper = new ObjectMapper();
028        SimpleModule module = new SimpleModule("esAuditJson", org.codehaus.jackson.Version.unknownVersion());
029        module.addSerializer(Map.class, new MapEntrySerializer());
030        module.addSerializer(AbstractBlob.class, new BinaryBlobEntrySerializer());
031        objectMapper.registerModule(module);
032
033        JsonFactory factory = new JsonFactory();
034        factory.setCodec(objectMapper);
035        JsonParser jp = factory.createJsonParser(content);
036
037        JsonToken tok = jp.nextToken();
038
039        // skip {
040        if (jp.getCurrentToken() == JsonToken.START_OBJECT) {
041            tok = jp.nextToken();
042        }
043
044        LogEntryImpl entry = new LogEntryImpl();
045
046        while (tok != null && tok != JsonToken.END_OBJECT) {
047            String key = jp.getCurrentName();
048            JsonToken token = jp.nextToken();
049            if (token != JsonToken.VALUE_NULL) {
050                if ("category".equals(key)) {
051                    entry.setCategory(token == JsonToken.VALUE_NULL ? null : jp.getText());
052                } else if ("principalName".equals(key)) {
053                    entry.setPrincipalName(jp.getText());
054                } else if ("comment".equals(key)) {
055                    entry.setComment(jp.getText());
056                } else if ("docLifeCycle".equals(key)) {
057                    entry.setDocLifeCycle(jp.getText());
058                } else if ("docPath".equals(key)) {
059                    entry.setDocPath(jp.getText());
060                } else if ("docType".equals(key)) {
061                    entry.setDocType(jp.getText());
062                } else if ("docUUID".equals(key)) {
063                    entry.setDocUUID(jp.getText());
064                } else if ("eventId".equals(key)) {
065                    entry.setEventId(jp.getText());
066                } else if ("repositoryId".equals(key)) {
067                    entry.setRepositoryId(jp.getText());
068                } else if ("id".equals(key)) {
069                    entry.setId(jp.getLongValue());
070                } else if ("eventDate".equals(key)) {
071                    entry.setEventDate(ISODateTimeFormat.dateTime().parseDateTime(jp.getText()).toDate());
072                } else if ("logDate".equals(key)) {
073                    entry.setLogDate(ISODateTimeFormat.dateTime().parseDateTime(jp.getText()).toDate());
074                } else if ("extended".equals(key)) {
075                    entry.setExtendedInfos(readExtendedInfo(entry, jp, objectMapper));
076                }
077            }
078            tok = jp.nextToken();
079        }
080        return entry;
081    }
082
083    public static Map<String, ExtendedInfo> readExtendedInfo(LogEntryImpl entry, JsonParser jp,
084            ObjectMapper objectMapper) throws IOException {
085
086        Map<String, ExtendedInfo> info = new HashMap<String, ExtendedInfo>();
087
088        JsonNode node = jp.readValueAsTree();
089
090        Iterator<String> fieldsIt = node.getFieldNames();
091
092        while (fieldsIt.hasNext()) {
093            String fieldName = fieldsIt.next();
094
095            JsonNode field = node.get(fieldName);
096
097            ExtendedInfoImpl ei = null;
098            if (field.isObject() || field.isArray()) {
099                ei = ExtendedInfoImpl.createExtendedInfo(objectMapper.writeValueAsString(field));
100            } else {
101                if (field.isInt() || field.isLong()) {
102                    ei = ExtendedInfoImpl.createExtendedInfo(field.getLongValue());
103                } else {
104                    ei = ExtendedInfoImpl.createExtendedInfo(field.getTextValue());
105                }
106            }
107            info.put(fieldName, ei);
108        }
109        return info;
110    }
111
112}