001package org.nuxeo.box.api.marshalling.jsonparsing;
002
003import com.fasterxml.jackson.annotation.JsonInclude.Include;
004import com.fasterxml.jackson.core.JsonFactory;
005import com.fasterxml.jackson.core.JsonParser;
006import com.fasterxml.jackson.databind.DeserializationFeature;
007import com.fasterxml.jackson.databind.ObjectMapper;
008import com.fasterxml.jackson.databind.jsontype.NamedType;
009
010import org.nuxeo.box.api.marshalling.exceptions.BoxJSONException;
011import org.nuxeo.box.api.marshalling.interfaces.IBoxJSONParser;
012import org.nuxeo.box.api.marshalling.interfaces.IBoxResourceHub;
013import org.nuxeo.box.api.marshalling.interfaces.IBoxType;
014
015import java.io.IOException;
016import java.io.InputStream;
017
018/**
019 * The json parser class wrapping Jackson JSON parser. For now, if user wants to remove jackson dependency(jackson
020 * jars), all the overriden methods and constructor of this class needs to be rewritten against the cusomized json
021 * parser. An alternative approach (not taken yet) requires user to implement a new IBoxJSONParser, in the meantime make
022 * all the jackson library related calls in this class reflection calls. However this is error prone if we need to
023 * update jackson. Since jackson is still the recommended way. We are not doing the reflection way yet.
024 */
025public class BoxJSONParser implements IBoxJSONParser {
026
027    private final ObjectMapper mObjectMapper;
028
029    public BoxJSONParser(final IBoxResourceHub hub) {
030        mObjectMapper = new ObjectMapper();
031        mObjectMapper.setSerializationInclusion(Include.NON_NULL);
032        mObjectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false);
033        mObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
034        for (IBoxType type : hub.getAllTypes()) {
035            mObjectMapper.registerSubtypes(new NamedType(hub.getClass(type), type.toString()));
036        }
037    }
038
039    protected ObjectMapper getObjectMapper() {
040        return mObjectMapper;
041    }
042
043    @Override
044    public String convertBoxObjectToJSONStringQuietly(final Object object) {
045        try {
046            return convertBoxObjectToJSONString(object);
047        } catch (BoxJSONException e) {
048            return null;
049        }
050    }
051
052    @Override
053    public <T> T parseIntoBoxObjectQuietly(final InputStream inputStream, final Class<T> theClass) {
054        try {
055            return parseIntoBoxObject(inputStream, theClass);
056        } catch (BoxJSONException e) {
057            return null;
058        }
059    }
060
061    @Override
062    public <T> T parseIntoBoxObjectQuietly(final String jsonString, final Class<T> theClass) {
063        try {
064            return parseIntoBoxObject(jsonString, theClass);
065        } catch (BoxJSONException e) {
066            return null;
067        }
068    }
069
070    @Override
071    public String convertBoxObjectToJSONString(Object object) throws BoxJSONException {
072        try {
073            return getObjectMapper().writeValueAsString(object);
074        } catch (IOException e) {
075            throw new BoxJSONException(e);
076        }
077    }
078
079    @Override
080    public <T> T parseIntoBoxObject(InputStream inputStream, Class<T> theClass) throws BoxJSONException {
081        try {
082            JsonFactory jsonFactory = new JsonFactory();
083            JsonParser jp = jsonFactory.createJsonParser(inputStream);
084            return getObjectMapper().readValue(jp, theClass);
085        } catch (IOException e) {
086            throw new BoxJSONException(e);
087        }
088    }
089
090    @Override
091    public <T> T parseIntoBoxObject(String jsonString, Class<T> theClass) throws BoxJSONException {
092        try {
093            JsonFactory jsonFactory = new JsonFactory();
094            JsonParser jp = jsonFactory.createJsonParser(jsonString);
095            return getObjectMapper().readValue(jp, theClass);
096        } catch (IOException e) {
097            throw new BoxJSONException(e);
098        }
099    }
100}