org.alfresco.rest.framework.jacksonextensions.JacksonHelper.java Source code

Java tutorial

Introduction

Here is the source code for org.alfresco.rest.framework.jacksonextensions.JacksonHelper.java

Source

/*
 * #%L
 * Alfresco Remote API
 * %%
 * Copyright (C) 2005 - 2016 Alfresco Software Limited
 * %%
 * This file is part of the Alfresco software. 
 * If the software was purchased under a paid Alfresco license, the terms of 
 * the paid license agreement will prevail.  Otherwise, the software is 
 * provided under the following open source license terms:
 * 
 * Alfresco is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Alfresco is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
 * #L%
 */
package org.alfresco.rest.framework.jacksonextensions;

import java.io.IOException;
import java.io.OutputStream;
import java.io.Reader;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.TimeZone;

import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.jackson.JsonEncoding;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.Module;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.ObjectReader;
import org.codehaus.jackson.map.SerializationConfig;
import org.codehaus.jackson.map.SerializerProvider;
import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion;
import org.codehaus.jackson.map.ser.BeanPropertyFilter;
import org.codehaus.jackson.map.ser.BeanPropertyWriter;
import org.codehaus.jackson.map.type.TypeFactory;
import org.springframework.beans.factory.InitializingBean;

/**
 * Helper Class for outputting Jackson content, makes use of the
 * RestJsonModule (main Jackson config).
 * Default settings : Date format is ISO8601, only serializes
 * non-empty / non-null values.
 *
 * @author Gethin James
 */
public class JacksonHelper implements InitializingBean {
    private static Log logger = LogFactory.getLog(JacksonHelper.class);

    Module module;
    private ObjectMapper objectMapper = null;
    private JsonEncoding encoding = JsonEncoding.UTF8;
    public static final String DEFAULT_FILTER_NAME = "defaultFilterName";

    /**
     * Sets the Jackson Module to be used.
     * 
     * @param module Module
     */
    public void setModule(Module module) {
        this.module = module;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        //Configure the objectMapper ready for use
        objectMapper = new ObjectMapper();
        objectMapper.registerModule(module);
        objectMapper.setSerializationInclusion(Inclusion.NON_EMPTY); //or NON_EMPTY?
        objectMapper.configure(SerializationConfig.Feature.WRITE_NULL_MAP_VALUES, false);
        objectMapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false);
        DateFormat DATE_FORMAT_ISO8601 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
        DATE_FORMAT_ISO8601.setTimeZone(TimeZone.getTimeZone("UTC"));
        objectMapper.setDateFormat(DATE_FORMAT_ISO8601);
        objectMapper.configure(DeserializationConfig.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);

    }

    /**
     * A callback so a JsonGenerator can be used inline but exception are handled here
     * @param outStream OutputStream
     * @param writer The writer interface
     * @throws IOException
     */
    public void withWriter(OutputStream outStream, Writer writer) throws IOException {
        try {
            JsonGenerator generator = objectMapper.getJsonFactory().createJsonGenerator(outStream, encoding);
            writer.writeContents(generator, objectMapper);
        } catch (JsonMappingException error) {
            logger.error("Failed to write Json output", error);
        } catch (JsonGenerationException generror) {
            logger.error("Failed to write Json output", generror);
        }
    }

    /**
     * Constructs the object based on the content.
     * @param content Reader
     * @return T
     * @throws IOException
     */
    public <T> T construct(Reader content, Class<T> requiredType)
            throws IOException, JsonMappingException, JsonParseException {
        ObjectReader reader = objectMapper.reader(requiredType);
        try {
            return reader.readValue(content);
        } catch (IOException error) {
            throw new InvalidArgumentException(
                    "Could not read content from HTTP request body: " + error.getMessage());
        }
    }

    /**
     * Constructs the object based on the content as a List, the JSON can be an array or just a single value without the [] symbols
     * @param content Reader
     * @return A collection of the specified type
     * @throws IOException
     */
    public <T> List<T> constructList(Reader content, Class<T> requiredType)
            throws IOException, JsonMappingException, JsonParseException {
        ObjectReader reader = objectMapper
                .reader(TypeFactory.defaultInstance().constructParametricType(List.class, requiredType));
        try {
            List<T> toReturn = reader.readValue(content);
            if (toReturn == null || toReturn.isEmpty()) {
                throw new InvalidArgumentException(
                        "Could not read content from HTTP request body, the list is empty");
            }
            return toReturn;
        } catch (IOException error) {
            throw new InvalidArgumentException(
                    "Could not read content from HTTP request body: " + error.getMessage());
        }
    }

    /**
     * A callback interface for use with the withWriter() method
     */
    public static interface Writer {
        public void writeContents(JsonGenerator generator, ObjectMapper objectMapper)
                throws JsonGenerationException, JsonMappingException, IOException;
    }

    /*
     * Always returns all properties
     */
    public static class ReturnAllBeanProperties implements BeanPropertyFilter {

        @Override
        public void serializeAsField(Object bean, JsonGenerator jgen, SerializerProvider provider,
                BeanPropertyWriter writer) throws Exception {
            writer.serializeAsField(bean, jgen, provider);
        }

    }
}