Package org.jasig.portal.dao.usertype

Source Code of org.jasig.portal.dao.usertype.JacksonColumnMapper$JsonWrapper

/**
* Licensed to Jasig under one or more contributor license
* agreements. See the NOTICE file distributed with this work
* for additional information regarding copyright ownership.
* Jasig licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a
* copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.jasig.portal.dao.usertype;

import java.io.IOException;

import org.jadira.usertype.spi.shared.AbstractStringColumnMapper;
import org.jasig.portal.spring.beans.factory.ObjectMapperFactoryBean;

import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;

/**
* Mapper that read/writes objects to JSON. Uses a 2 step serialization/deserialization process so the
* object's type can be recorded in the JSON data
*
* @author Eric Dalquist
*/
public class JacksonColumnMapper extends AbstractStringColumnMapper<Object> {
    private static final long serialVersionUID = 1L;
   
    private final LoadingCache<Class<?>, ObjectWriter> typedObjectWriters = CacheBuilder.newBuilder()
            .build(new CacheLoader<Class<?>, ObjectWriter>() {
                @Override
                public ObjectWriter load(Class<?> key) throws Exception {
                    return objectWriter.withType(key);
                }
            });
    private final LoadingCache<Class<?>, ObjectReader> typedObjectReaders = CacheBuilder.newBuilder()
            .build(new CacheLoader<Class<?>, ObjectReader>() {
                @Override
                public ObjectReader load(Class<?> key) throws Exception {
                    return objectReader.withType(key);
                }
            });
   
    private final ObjectWriter objectWriter;
    private final ObjectReader objectReader;
   
    public JacksonColumnMapper() {
        final ObjectMapper mapper;
        try {
            final ObjectMapperFactoryBean omfb = new ObjectMapperFactoryBean();
            omfb.afterPropertiesSet();
            mapper = omfb.getObject();
        }
        catch (Exception e) {
            throw new RuntimeException("Failed to create ObjectMapper", e);
        }

        customizeObjectMapper(mapper);
       
        this.objectWriter = this.createObjectWriter(mapper).withType(JsonWrapper.class);
        this.objectReader = this.createObjectReader(mapper).withType(JsonWrapper.class);
    }

    protected void customizeObjectMapper(ObjectMapper mapper) {
    }
   
    protected ObjectWriter createObjectWriter(ObjectMapper mapper) {
        return mapper.writer();
    }
   
    protected ObjectReader createObjectReader(ObjectMapper mapper) {
        return mapper.reader();
    }

    @Override
    public final Object fromNonNullValue(String s) {
        try {
            final JsonWrapper jsonWrapper = objectReader.readValue(s);
            final ObjectReader typeReader = typedObjectReaders.getUnchecked(jsonWrapper.getType());
            return typeReader.readValue(jsonWrapper.getValue());
        }
        catch (JsonProcessingException e) {
            throw new IllegalArgumentException("Could not read from JSON: " + s, e);
        }
        catch (IOException e) {
            throw new IllegalArgumentException("Could not read from JSON: " + s, e);
        }
    }

    @Override
    public final String toNonNullValue(Object value) {
        try {
            final Class<? extends Object> type = value.getClass();
            final ObjectWriter typeWriter = typedObjectWriters.getUnchecked(type);
            final String valueAsString = typeWriter.writeValueAsString(value);
           
            return objectWriter.writeValueAsString(new JsonWrapper(type, valueAsString));
        }
        catch (JsonGenerationException e) {
            throw new IllegalArgumentException("Could not write to JSON: " + value, e);
        }
        catch (JsonMappingException e) {
            throw new IllegalArgumentException("Could not write to JSON: " + value, e);
        }
        catch (IOException e) {
            throw new IllegalArgumentException("Could not write to JSON: " + value, e);
        }
    }
   
    public static final class JsonWrapper {
        private Class<?> t;
        private String v;
       
        public JsonWrapper() {
        }
       
        public JsonWrapper(Class<?> type, String value) {
            this.t = type;
            this.v = value;
        }
       
        public Class<?> getType() {
            return t;
        }
        public void setType(Class<?> type) {
            this.t = type;
        }
        public String getValue() {
            return v;
        }
        public void setValue(String value) {
            this.v = value;
        }
        @Override
        public String toString() {
            return "JsonWrapper [type=" + t + ", value=" + v + "]";
        }
    }
}
TOP

Related Classes of org.jasig.portal.dao.usertype.JacksonColumnMapper$JsonWrapper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.