001package org.nuxeo.segment.io;
002
003import java.io.Serializable;
004import java.math.BigDecimal;
005import java.util.Collection;
006import java.util.Date;
007import java.util.HashMap;
008import java.util.Map;
009import org.apache.commons.lang.ClassUtils;
010import org.apache.commons.logging.Log;
011import org.apache.commons.logging.LogFactory;
012
013import org.nuxeo.ecm.core.api.NuxeoPrincipal;
014
015import com.github.segmentio.models.Props;
016
017public class SegmentIODataWrapper {
018
019    public static final String LOGIN_KEY = "login";
020
021    public static final String PRINCIPAL_KEY = "principal";
022
023    public static final String GROUP_KEY_PREFIX = "group_";
024
025    protected static final Log log = LogFactory.getLog(SegmentIODataWrapper.class);
026
027    protected String userId;
028    protected Map<String, Serializable> metadata;
029
030    public SegmentIODataWrapper(NuxeoPrincipal principal, Map<String, Serializable> metadata) {
031        if (metadata == null) {
032            metadata = new HashMap<>();
033        }
034
035        if (metadata.containsKey(PRINCIPAL_KEY) && metadata.get(PRINCIPAL_KEY)!=null) {
036            principal = (NuxeoPrincipal) metadata.get(PRINCIPAL_KEY);
037        }
038
039        userId = principal.getName();
040        if (!metadata.containsKey("email")) {
041            metadata.put("email", principal.getEmail());
042        }
043        if (!metadata.containsKey("firstName")) {
044            metadata.put("firstName", principal.getFirstName());
045        }
046        if (!metadata.containsKey("lastName")) {
047            metadata.put("lastName", principal.getLastName());
048        }
049
050        // allow override
051        if (metadata.containsKey(LOGIN_KEY)) {
052            userId = (String) metadata.get(LOGIN_KEY);
053        }
054
055        this.metadata = metadata;
056    }
057
058    public String getUserId() {
059        return userId;
060    }
061
062    // code copied from com.github.segmentio.models.Props
063    private boolean isPrimitive (Object value) {
064        boolean primitive = false;
065        if (value != null) {
066            Class<?> clazz = value.getClass();
067            // http://stackoverflow.com/questions/709961/determining-if-an-object-is-of-primitive-type
068            primitive = clazz.isPrimitive() || ClassUtils.wrapperToPrimitive(clazz) != null;
069        }
070        return primitive;
071    }
072
073    // code copied from com.github.segmentio.models.Props
074    protected boolean isAllowed(Object value) {
075        if (isPrimitive(value) ||
076            value instanceof String ||
077            value instanceof Date ||
078            value instanceof Props ||
079            value instanceof BigDecimal ||
080            value instanceof Collection ||
081            value instanceof Map ||
082            value instanceof Object[]) {
083            return true;
084        } else {
085            return false;
086        }
087    }
088
089    public Map<String, Serializable> getMetadata() {
090        Map<String, Serializable> map = new HashMap<>();
091        for (String key : metadata.keySet()) {
092            if (!key.startsWith(GROUP_KEY_PREFIX)) {
093                Serializable value = metadata.get(key);
094                if (value!=null) {
095                    if ( isAllowed(value)) {
096                        map.put(key, value);
097                    } else {
098                        map.put(key, value.toString());
099                    }
100                } else {
101                    log.debug("Skip null value for key " + key);
102                }
103            }
104        }
105        return map;
106    }
107
108    public Map<String, Serializable> getGroupMetadata() {
109        Map<String, Serializable> map = new HashMap<>();
110        for (String key : metadata.keySet()) {
111            if (key.startsWith(GROUP_KEY_PREFIX)) {
112                String gKey = key.substring(GROUP_KEY_PREFIX.length());
113                Serializable value = metadata.get(key);
114                if (value!=null) {
115                    if ( isAllowed(value)) {
116                        map.put(gKey, value);
117                    } else {
118                        map.put(gKey, value.toString());
119                    }
120                } else {
121                    log.debug("Skip null value for key " + key);
122                }
123            }
124        }
125        return map;
126    }
127
128
129}