Package com.zenesis.qx.remote

Source Code of com.zenesis.qx.remote.ProxyObjectMapper$FileDeserializer

/**
* ************************************************************************
*
*    server-objects - a contrib to the Qooxdoo project that makes server
*    and client objects operate seamlessly; like Qooxdoo, server objects
*    have properties, events, and methods all of which can be access from
*    either server or client, regardless of where the original object was
*    created.
*
*    http://qooxdoo.org
*
*    Copyright:
*      2010 Zenesis Limited, http://www.zenesis.com
*
*    License:
*      LGPL: http://www.gnu.org/licenses/lgpl.html
*      EPL: http://www.eclipse.org/org/documents/epl-v10.php
*     
*      This software is provided under the same licensing terms as Qooxdoo,
*      please see the LICENSE file in the Qooxdoo project's top-level directory
*      for details.
*
*    Authors:
*      * John Spackman (john.spackman@zenesis.com)
*
* ************************************************************************
*/
package com.zenesis.qx.remote;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

import org.apache.log4j.Logger;

import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.core.io.CharTypes;
import com.fasterxml.jackson.core.json.JsonWriteContext;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;

/**
* Simple wrapper for Jackson ObjectMapper that uses our custom de/serialisation factories and adds a few helper
* methods.
*
* @author <a href="mailto:john.spackman@zenesis.com">John Spackman</a>
*/
public class ProxyObjectMapper extends ObjectMapper {
 
  @SuppressWarnings("unused")
  private static final Logger log = Logger.getLogger(ProxyObjectMapper.class);
 
  private static final SimpleDateFormat DF = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
 
  /*
   * Serialises a Date as the JS equivelant
   */
  private static final class DateSerializer extends JsonSerializer<Date> {

    /* (non-Javadoc)
     * @see com.fasterxml.jackson.databind.JsonSerializer#serialize(java.lang.Object, com.fasterxml.jackson.core.JsonGenerator, com.fasterxml.jackson.databind.SerializerProvider)
     */
    @Override
    public void serialize(Date value, JsonGenerator gen, SerializerProvider sp) throws IOException, JsonProcessingException {
      if (value == null)
        gen.writeNull();
      else
        gen.writeRawValue("new Date(\"" + DF.format(value) + "\")");
    }
  }
 
  /*
   * Serialises a string, encoding unicode characters
   */
  private static final class StringSerializer extends JsonSerializer<String> {

    final char[] HEX_CHARS = "0123456789ABCDEF".toCharArray();
    final int[] ESCAPE_CODES = CharTypes.get7BitOutputEscapes();

    /* (non-Javadoc)
     * @see com.fasterxml.jackson.databind.JsonSerializer#serialize(java.lang.Object, com.fasterxml.jackson.core.JsonGenerator, com.fasterxml.jackson.databind.SerializerProvider)
     */
    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider sp) throws IOException, JsonProcessingException {
      int status = ((JsonWriteContext) gen.getOutputContext()).writeValue();
      switch (status) {
      case JsonWriteContext.STATUS_OK_AFTER_COLON:
        gen.writeRaw(':');
        break;
       
      case JsonWriteContext.STATUS_OK_AFTER_COMMA:
        gen.writeRaw(',');
        break;
       
      case JsonWriteContext.STATUS_EXPECT_NAME:
        throw new JsonGenerationException("Can not write string value here");
      }
      gen.writeRaw('"');
      for (char c : value.toCharArray()) {
        if (c >= 0x80)
          writeUnicodeEscape(gen, c); // use generic escaping for all
                        // non US-ASCII characters
        else {
          // use escape table for first 128 characters
          int code = (c < ESCAPE_CODES.length ? ESCAPE_CODES[c] : 0);
          if (code == 0)
            gen.writeRaw(c); // no escaping
          else if (code < 0)
            writeUnicodeEscape(gen, (char) (-code - 1)); // generic escaping
          else
            writeShortEscape(gen, (char) code); // short escaping (\n \t ...)
        }
      }
      gen.writeRaw('"');
    }
   
    private void writeUnicodeEscape(JsonGenerator gen, char c)
        throws IOException {
      gen.writeRaw('\\');
      gen.writeRaw('u');
      gen.writeRaw(HEX_CHARS[(c >> 12) & 0xF]);
      gen.writeRaw(HEX_CHARS[(c >> 8) & 0xF]);
      gen.writeRaw(HEX_CHARS[(c >> 4) & 0xF]);
      gen.writeRaw(HEX_CHARS[c & 0xF]);
    }

    private void writeShortEscape(JsonGenerator gen, char c)
        throws IOException {
      gen.writeRaw('\\');
      gen.writeRaw(c);
    }
  }

  /*
   * Serialises enums in camelCase
   */
  private static final class EnumSerializer extends JsonSerializer<Enum> {
   
    /* (non-Javadoc)
     * @see org.codehaus.jackson.map.JsonSerializer#serialize(java.lang.Object, org.codehaus.jackson.JsonGenerator, org.codehaus.jackson.map.SerializerProvider)
     */
    @Override
    public void serialize(Enum value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
      if (value == null)
        jgen.writeNull();
      else
        jgen.writeString(enumToCamelCase(value));
    }

  };
 
/* 
  private static final class EnumDeserializer extends JsonDeserializer<Enum> {

    @Override
    public Enum deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
      String value = jp.getText();
      if (value == null || value.length() == 0)
        return null;
      return null;
    }
   
  }
*/
 
  /*
   * Serialises Maps
   */
  private static final class MapSerializer extends JsonSerializer<Map> {
   
    /* (non-Javadoc)
     * @see org.codehaus.jackson.map.JsonSerializer#serialize(java.lang.Object, org.codehaus.jackson.JsonGenerator, org.codehaus.jackson.map.SerializerProvider)
     */
    @Override
    public void serialize(Map map, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
      if (map == null)
        jgen.writeNull();
      else {
        jgen.writeStartObject();
        for (Object key : map.keySet()) {
          if (key == null)
            continue;
          if (key instanceof Enum)
            jgen.writeFieldName(enumToCamelCase((Enum)key));
          else
            jgen.writeFieldName(key.toString());
          Object value = map.get(key);
          if (value == null)
            jgen.writeNull();
          else
            jgen.writeObject(value);
        }
        jgen.writeEndObject();
      }
    }

  };
 
  /*
   * Serialises a file, but only showing the part of the path relative to the "root" dir of
   * the web application
   */
  public static final class FileSerializer extends JsonSerializer<File> {
   
    private final String localPrefix;
   
    public FileSerializer(File localDir) {
      this.localPrefix = localDir == null ? null : localDir.getAbsolutePath() + File.separatorChar;
    }

    /* (non-Javadoc)
     * @see com.fasterxml.jackson.databind.JsonSerializer#serialize(java.lang.Object, com.fasterxml.jackson.core.JsonGenerator, com.fasterxml.jackson.databind.SerializerProvider)
     */
    @Override
    public void serialize(File value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
      if (value == null)
        jgen.writeNull();
      else {
        String str = value.getAbsolutePath();
        if (localPrefix == null)
          jgen.writeString(str);
        else {
          int len = localPrefix.length();
          if (len < str.length() && str.substring(0, len).equalsIgnoreCase(localPrefix))
            jgen.writeString(str.substring(len));
          else
            jgen.writeString(str);
        }
      }
    }
  }
 
  /*
   * Deserialises a file, keeping it relative to the root of the web application
   */
  public static final class FileDeserializer extends JsonDeserializer<File> {
   
    private final File localDir;
   
    public FileDeserializer(File localDir) {
      this.localDir = localDir;
    }

    /* (non-Javadoc)
     * @see com.fasterxml.jackson.databind.JsonDeserializer#deserialize(com.fasterxml.jackson.core.JsonParser, com.fasterxml.jackson.databind.DeserializationContext)
     */
    @Override
    public File deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
      String value = jp.getText();
      if (value == null || value.length() == 0)
        return null;
      if (localDir == null)
        return new File(value);
      if (File.separatorChar == '/' && value.charAt(0) == '/')
        return new File(value);
      if (File.separatorChar == '\\' && value.length() > 1 && value.charAt(1) == ':')
        return new File(value);
      File file = new File(localDir, value);
      return file;
    }

  }
 
  /** the tracker */
  private final ProxySessionTracker tracker;

 
  /**
   * Constructor
   * @param tracker
   */
  public ProxyObjectMapper(ProxySessionTracker tracker) {
    this(tracker, true, new File("."));
  }
 
  /**
   * Constructor
   * @param tracker
   * @param indent whether to indent JSON
   */
  public ProxyObjectMapper(ProxySessionTracker tracker, boolean indent) {
    this(tracker, indent, new File("."));
  }
   
  /**
   * Constructor
   * @param tracker
   * @param indent whether to indent JSON
   * @param rootDir root directory to serialise all File's as relative to
   */
  public ProxyObjectMapper(ProxySessionTracker tracker, boolean indent, File rootDir) {
    super();
    this.tracker = tracker;
    SimpleModule module = new SimpleModule("ProxyObjectMapper", Version.unknownVersion());
    module.addSerializer(Proxied.class, new ProxiedSerializer());
    module.addDeserializer(Proxied.class, new ProxiedDeserializer());
    module.addSerializer(Date.class, new DateSerializer());
    module.addSerializer(String.class, new StringSerializer());
    module.addSerializer(Enum.class, new EnumSerializer());
    module.addSerializer(File.class, new FileSerializer(rootDir));
    module.addDeserializer(File.class, new FileDeserializer(rootDir));
    module.addSerializer(Map.class, new MapSerializer());
    registerModule(module);
  }

  /**
   * @return the tracker
   */
  public ProxySessionTracker getTracker() {
    return tracker;
  }

  /**
   * Enables or disabled quoted field names
   * @param set
   */
  public void setQuoteFieldNames(boolean set) {
    if (set)
      getJsonFactory().enable(JsonGenerator.Feature.QUOTE_FIELD_NAMES);
    else
      getJsonFactory().disable(JsonGenerator.Feature.QUOTE_FIELD_NAMES);
  }
 
  /**
   * Whether field names will be quoted
   * @return
   */
  public boolean isQuoteFieldNames() {
    return getJsonFactory().isEnabled(JsonGenerator.Feature.QUOTE_FIELD_NAMES);
  }

  private static String enumToCamelCase(Enum e) {
    if (e == null)
      return null;
    StringBuilder sb = new StringBuilder(e.toString());
    char lastC = 0;
    for (int i = 0; i < sb.length(); i++) {
      char c = sb.charAt(i);
      if (c == '_') {
        sb.deleteCharAt(i);
        i--;
      } else if (Character.isUpperCase(c) && lastC != '_')
        sb.setCharAt(i, Character.toLowerCase(c));
      else if (Character.isLowerCase(c) && lastC == '_')
        sb.setCharAt(i, Character.toUpperCase(c));
      lastC = c;
    }
    return sb.toString();
  }
 
  /*
  private static <T extends Enum> T camelCaseToEnum(String str, Class<T> clz) {
    str = camelCaseToEnumStr(str);
    if (str == null)
      return null;
    try {
      T value = (T)T.valueOf(clz, str);
      return value;
    }catch(IllegalArgumentException e) {
      return null;
    }
  }
 
  private static String camelCaseToEnumStr(String str) {
    if (str == null)
      return null;
    StringBuilder sb = new StringBuilder(str);
    char lastC = 0;
    for (int i = 0; i < sb.length(); i++) {
      char c = sb.charAt(i);
      if (Character.isUpperCase(c)) {
        if (lastC != 0 && Character.isLowerCase(lastC)) {
          sb.insert(i, '_');
          i++;
        }
      } else if (Character.isLowerCase(c))
        sb.setCharAt(i, Character.toUpperCase(c));
      lastC = c;
    }
    return sb.toString();
  }
*/ 
}
 
TOP

Related Classes of com.zenesis.qx.remote.ProxyObjectMapper$FileDeserializer

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.