All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.getperka.flatpack.codexes.DefaultCodexMapper Maven / Gradle / Ivy

There is a newer version: 2.21.0
Show newest version
/*
 * #%L
 * FlatPack serialization code
 * %%
 * Copyright (C) 2012 Perka Inc.
 * %%
 * Licensed 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.
 * #L%
 */
package com.getperka.flatpack.codexes;

import static com.getperka.flatpack.util.FlatPackTypes.BOXED_TYPES;
import static com.getperka.flatpack.util.FlatPackTypes.PRIMITIVE_TYPES;
import static com.getperka.flatpack.util.FlatPackTypes.box;
import static com.getperka.flatpack.util.FlatPackTypes.erase;
import static com.getperka.flatpack.util.FlatPackTypes.getParameterization;
import static com.getperka.flatpack.util.FlatPackTypes.getSingleParameterization;

import java.lang.reflect.Constructor;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Map;
import java.util.UUID;

import org.joda.time.DateTimeZone;

import com.getperka.flatpack.HasUuid;
import com.getperka.flatpack.ext.Codex;
import com.getperka.flatpack.ext.CodexMapper;
import com.getperka.flatpack.ext.TypeContext;
import com.getperka.flatpack.ext.TypeHint;
import com.google.gson.JsonElement;

/**
 * Support for all built-in types.
 */
public class DefaultCodexMapper implements CodexMapper {

  @Override
  @SuppressWarnings({ "unchecked", "rawtypes" })
  public Codex getCodex(TypeContext context, Type type) {
    Codex toReturn = null;
    Class erased = erase(type);

    // Collections and collection-like objects
    if (Collection.class.isAssignableFrom(erased)) {
      Type valueType = getSingleParameterization(type, Collection.class);
      toReturn = new CollectionCodex(erased, context.getCodex(valueType));
    } else if (erased.isArray()) {
      // Treat an array like a list
      Class valueType = erased.getComponentType();
      toReturn = new ArrayCodex(valueType, context.getCodex(valueType));
    } else if (Map.class.isAssignableFrom(erased)) {
      // Maps can be  or 
      Type[] params = getParameterization(Map.class, type);
      if (HasUuid.class.isAssignableFrom(erase(params[0]))) {
        toReturn = new EntityMapCodex((EntityCodex) context.getCodex(params[0]),
            context.getCodex(params[1]));
      } else {
        toReturn = new StringMapCodex(context.getCodex(params[1]));
      }
      // Scalar types below here
    } else if (Boolean.class.equals(erased) || boolean.class.equals(erased)) {
      toReturn = new BooleanCodex();
    } else if (CharSequence.class.isAssignableFrom(erased)) {
      toReturn = new StringCodex();
    } else if (Class.class.equals(erased)) {
      toReturn = new HasUuidClassCodex();
    } else if (DateTimeZone.class.isAssignableFrom(erased)) {
      toReturn = new DateTimeZoneCodex();
    } else if (Enum.class.isAssignableFrom(erased)) {
      toReturn = new EnumCodex(erased);
    } else if (HasUuid.class.isAssignableFrom(erased)) {
      toReturn = new EntityCodex(erased);
    } else if (JsonElement.class.isAssignableFrom(erased)) {
      toReturn = new JsonElementCodex();
    } else if (TypeHint.class.isAssignableFrom(erased)) {
      toReturn = new TypeHintCodex();
    } else if (UUID.class.equals(erased)) {
      toReturn = new UUIDCodex();
    } else if (Void.class.equals(erased) || void.class.equals(erased)) {
      toReturn = new VoidCodex();
    } else if (BOXED_TYPES.contains(erased)) {
      toReturn = new NumberCodex(erased);
    } else if (PRIMITIVE_TYPES.contains(erased)) {
      toReturn = new NumberCodex(box(erased));
    } else {
      /*
       * Try to find a one-arg String or Object constructor. This is kind of shady, but it works for
       * a number of the auxiliary value types used in the model classes, mainly joda-time.
       */
      try {
        Constructor constructor = erased.getConstructor(String.class);
        toReturn = new ToStringCodex(constructor);
      } catch (NoSuchMethodException expected) {}
      try {
        Constructor constructor = erased.getConstructor(Object.class);
        toReturn = new ToStringCodex(constructor);
      } catch (NoSuchMethodException expected) {}
    }
    return toReturn;
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy