Package org.openmhealth.reference.util

Source Code of org.openmhealth.reference.util.OmhObjectMapper$ExtendableSerializeExceptFilter

package org.openmhealth.reference.util;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashSet;

import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ser.BeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter.SerializeExceptFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;

/**
* <p>
* A custom ObjectMapper for Open mHealth that adds functionality like
* filtering fields on HTTP-level serialization.
* </p>
*
* @author John Jenkins
*/
public class OmhObjectMapper extends ObjectMapper {
  /**
   * <p>
   * A custom annotation for fields that should not be serialized by Jackson
   * when their encapsulating object is being serialized by Spring.
   * </p>
   *
   * @author John Jenkins
   */
  @Documented
  @Target(ElementType.FIELD)
  @Retention(RetentionPolicy.RUNTIME)
  public static @interface JacksonFieldFilter {   
    /**
     * The filter group to which the field belongs. All fields that belong
     * to the same class should have the same filter group name and that
     * class should be annotated with {@link JsonFilter}, which specifies
     * the same group name.
     *
     * @return The filter group to which the field belongs.
     */
    String value();
  }
 
  /**
   * <p>
   * The custom filter that allows for the addition of new field names.
   * </p>
   *
   * @author John Jenkins
   */
  private static class ExtendableSerializeExceptFilter
    extends SerializeExceptFilter {
   
    /**
     * Creates a new filter with the field name.
     *
     * @param fieldName
     *        The first field for this filter.
     */
    public ExtendableSerializeExceptFilter(final String fieldName) {
      super(new HashSet<String>(Arrays.asList(fieldName)));
    }
   
    /**
     * Adds another field to this filter.
     *
     * @param fieldName
     *        The new field.
     */
    public void addField(final String fieldName) {
      _propertiesToExclude.add(fieldName);
    }
  }
   
  /**
     * A default version UID to use when serializing an instance of this class.
     */
    private static final long serialVersionUID = 1L;
   
    /**
     * The set of private fields that should never be serialized.
     */
    private static final SimpleFilterProvider FILTER_PROVIDER =
      new SimpleFilterProvider();

    /**
     * Creates the object mapper and initializes the filters. This is private
     * as it should only ever be called by Spring via reflection.
     */
    private OmhObjectMapper() {
      // Ensure that unknown fields are ignored.
      FILTER_PROVIDER.setFailOnUnknownId(false);
     
      // Save the FilterProvider in this ObjectMapper.
        setFilters(FILTER_PROVIDER);
    }
   
    /**
   * Registers a new field filter and ensures that its desired fields are
   * never serialized.
   *
   * @param filter
   *        The filter to add to this ObjectMapper.
   */
    public static synchronized void register(final Class<?> filterClass) {
      // Sanitize the input.
      if(filterClass == null) {
        throw new IllegalArgumentException("The filter class is null.");
      }
     
      // Cycle through each of the class's fields.
      for(Field field : filterClass.getFields()) {
        // Determine if that field has a JacksonFieldFilter annotation.
        JacksonFieldFilter filter =
          field.getAnnotation(JacksonFieldFilter.class);
       
        // If it does have the annotation.
        if(filter != null) {
          // Get the serialized field name.
          String fieldName;
          JsonProperty jsonProperty =
            field.getAnnotation(JsonProperty.class);
          if(jsonProperty == null) {
            fieldName = field.getName();
          }
          else {
            fieldName = jsonProperty.value();
          }
         
          // Get the given group name.
          String filterGroup = filter.value();
         
          // Get the existing filter, if one exists.
          BeanPropertyFilter propertyFilter =
            FILTER_PROVIDER.findFilter(filterGroup);
         
          // If no such filter exists, update the filter provider with a
          // new one.
          if(propertyFilter == null) {
            FILTER_PROVIDER
              .addFilter(
                filterGroup,
                new ExtendableSerializeExceptFilter(fieldName));
          }
          else {
            // Safely cast the filter as we are the only maintainers of
            // it, and this is the only type of filter we use.
            ExtendableSerializeExceptFilter amenableFilter =
              (ExtendableSerializeExceptFilter) propertyFilter;
           
            // Add the field.
            amenableFilter.addField(fieldName);
          }
        }
      }
    }
}
TOP

Related Classes of org.openmhealth.reference.util.OmhObjectMapper$ExtendableSerializeExceptFilter

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.