Example #1
0
  public static <T> T createFromArg(Class<T> clz, Object value) {
    if (value == null) {
      return null;
    }
    ClassMeta meta = ClassMeta.classMeta(clz);
    List<ConstructorAccess> constructors = meta.oneArgumentConstructors();

    if (constructors.size() == 0) {
      return null;
    } else if (constructors.size() == 1) {
      ConstructorAccess constructorAccess = constructors.get(0);
      Class<?> arg1Type = constructorAccess.parameterTypes()[0];
      if (arg1Type.isInstance(value)) {
        return (T) constructorAccess.create(value);
      } else {
        return (T) constructorAccess.create(coerce(arg1Type, value));
      }
    } else {
      for (ConstructorAccess c : constructors) {
        Class<?> arg1Type = c.parameterTypes()[0];
        if (arg1Type.isInstance(value)) {
          return (T) c.create(value);
        }
      }

      for (ConstructorAccess c : constructors) {
        Class<?> arg1Type = c.parameterTypes()[0];
        if (arg1Type.isAssignableFrom(value.getClass())) {
          return (T) c.create(value);
        }
      }
    }
    return null;
  }
Example #2
0
  /**
   * @param c Class instance
   * @return ClassMeta which contains fields of class and customer write/read methods if they exist.
   *     The results are cached internally for performance when called again with same Class.
   */
  static ClassMeta getDeepDeclaredFields(Class c) {
    ClassMeta classInfo = _classMetaCache.get(c.getName());
    if (classInfo != null) {
      return classInfo;
    }

    classInfo = new ClassMeta();
    Class curr = c;

    while (curr != null) {
      try {
        Field[] local = curr.getDeclaredFields();

        for (Field field : local) {
          if (!field.isAccessible()) {
            try {
              field.setAccessible(true);
            } catch (Exception ignored) {
            }
          }

          if ((field.getModifiers() & Modifier.STATIC)
              == 0) { // speed up: do not process static fields.
            classInfo.put(field.getName(), field);
          }
        }
      } catch (ThreadDeath t) {
        throw t;
      } catch (Throwable ignored) {
      }

      curr = curr.getSuperclass();
    }

    try {
      classInfo._writeMethod = c.getDeclaredMethod("_writeJson", new Class[] {Writer.class});
    } catch (Exception ignored) {
    }

    try {
      classInfo._readMethod = c.getDeclaredMethod("_readJson", new Class[] {Map.class});
    } catch (Exception ignored) {
    }

    _classMetaCache.put(c.getName(), classInfo);
    return classInfo;
  }
Example #3
0
  private void traceFields(LinkedList<Object> stack, Object obj) {
    ClassMeta fields = getDeepDeclaredFields(obj.getClass());

    for (Field field : fields.values()) {
      try {
        if (isPrimitiveWrapper(
            field
                .getType())) { // speed up: primitives & primitive wrappers cannot reference another
          // object
          continue;
        }

        Object o = field.get(obj);
        if (o != null) {
          stack.addFirst(o);
        }
      } catch (IllegalAccessException ignored) {
      }
    }
  }
Example #4
0
  private void hasOneInstantiatorDefinitionWithEmptyConstructorOnImpl(
      ClassMeta<?> classMeta, Class<?> impl) throws NoSuchMethodException {
    assertTrue(classMeta instanceof ArrayClassMeta);
    final List<InstantiatorDefinition> instantiatorDefinitions =
        classMeta.getInstantiatorDefinitions();

    assertEquals(1, instantiatorDefinitions.size());
    final ExecutableInstantiatorDefinition instantiatorDefinition =
        (ExecutableInstantiatorDefinition) instantiatorDefinitions.get(0);

    assertEquals(0, instantiatorDefinition.getParameters().length);
    assertEquals(impl.getDeclaredConstructor(), instantiatorDefinition.getExecutable());
  }
Example #5
0
  public static <T> T coerceWithFlag(
      TypeType coerceTo, Class<T> clz, boolean[] flag, Object value) {

    flag[0] = true;
    if (value == null) {
      return null;
    }

    if (clz.isInstance(value)) {
      return (T) value;
    }

    switch (coerceTo) {
      case STRING:
      case CHAR_SEQUENCE:
        return (T) value.toString();

      case INT:
      case INTEGER_WRAPPER:
        Integer i = toInt(value);
        if (i == Integer.MIN_VALUE) {
          flag[0] = false;
        }
        return (T) i;

      case SHORT:
      case SHORT_WRAPPER:
        Short s = toShort(value);
        if (s == Short.MIN_VALUE) {
          flag[0] = false;
        }
        return (T) s;

      case BYTE:
      case BYTE_WRAPPER:
        Byte by = toByte(value);
        if (by == Byte.MIN_VALUE) {
          flag[0] = false;
        }
        return (T) by;

      case CHAR:
      case CHAR_WRAPPER:
        Character ch = toChar(value);
        if (ch == (char) 0) {
          flag[0] = false;
        }
        return (T) ch;

      case LONG:
      case LONG_WRAPPER:
        Long l = toLong(value);
        if (l == Long.MIN_VALUE) {
          flag[0] = false;
        }

        return (T) l;

      case DOUBLE:
      case DOUBLE_WRAPPER:
        Double d = toDouble(value);
        if (d == Double.MIN_VALUE) {
          flag[0] = false;
        }

        return (T) d;

      case FLOAT:
      case FLOAT_WRAPPER:
        Float f = toFloat(value);
        if (f == Float.MIN_VALUE) {
          flag[0] = false;
        }
        return (T) f;

      case DATE:
        return (T) toDate(value);

      case BIG_DECIMAL:
        return (T) toBigDecimal(value);

      case BIG_INT:
        return (T) toBigInteger(value);

      case CALENDAR:
        return (T) toCalendar(toDate(value));

      case BOOLEAN:
      case BOOLEAN_WRAPPER:
        return (T) (Boolean) toBooleanOrDie(value);

      case MAP:
        return (T) toMap(value);

      case ARRAY:
      case ARRAY_INT:
      case ARRAY_BYTE:
      case ARRAY_SHORT:
      case ARRAY_FLOAT:
      case ARRAY_DOUBLE:
      case ARRAY_LONG:
      case ARRAY_STRING:
      case ARRAY_OBJECT:
        return toPrimitiveArrayIfPossible(clz, value);

      case COLLECTION:
        return toCollection(clz, value);

      case INSTANCE:
        if (value instanceof Map) {
          return MapObjectConversion.fromMap((Map<String, Object>) value, clz);
        } else if (value instanceof List) {
          return MapObjectConversion.fromList((List<Object>) value, clz);
        } else if (clz.isInstance(value)) {
          return (T) value;
        } else {
          ClassMeta meta = ClassMeta.classMeta(clz);
          List<ConstructorAccess> constructors = meta.oneArgumentConstructors();

          if (constructors.size() == 0) {
            return null;
          } else if (constructors.size() == 1) {
            ConstructorAccess constructorAccess = constructors.get(0);
            Class<?> arg1Type = constructorAccess.parameterTypes()[0];
            if (arg1Type.isInstance(value)) {
              return (T) constructorAccess.create(value);
            } else {
              return (T) constructorAccess.create(coerce(arg1Type, value));
            }
          } else {
            for (ConstructorAccess c : constructors) {
              Class<?> arg1Type = c.parameterTypes()[0];
              if (arg1Type.isInstance(value)) {
                return (T) c.create(value);
              }
            }

            for (ConstructorAccess c : constructors) {
              Class<?> arg1Type = c.parameterTypes()[0];
              if (arg1Type.isAssignableFrom(value.getClass())) {
                return (T) c.create(value);
              }
            }

            flag[0] = false;
            break;
          }
        }

      case ENUM:
        return (T) toEnum((Class<? extends Enum>) clz, value);

      case CLASS:
        return (T) toClass(value);

      case TIME_ZONE:
        return (T) toTimeZone(flag, value);

      case UUID:
        return (T) toUUID(flag, value);

      case CURRENCY:
        return (T) toCurrency(value);

      case OBJECT:
        return (T) value;

      default:
        flag[0] = false;
        break;
    }
    return null;
  }
  public void visitFieldInsn(int opcode, String owner, String name, String desc) {

    if (transientAnnotation) {
      // The whole method is left as is
      super.visitFieldInsn(opcode, owner, name, desc);
      return;
    }

    if (opcode == Opcodes.GETSTATIC || opcode == Opcodes.PUTSTATIC) {
      if (meta.isLog(3)) {
        meta.log(" ... info: skip static field " + owner + " " + name + " in " + methodDescription);
      }
      super.visitFieldInsn(opcode, owner, name, desc);
      return;
    }

    if (isNonPersistentField(owner, name)) {
      if (meta.isLog(3)) {
        meta.log(
            " ... info: non-persistent field " + owner + " " + name + " in " + methodDescription);
      }
      super.visitFieldInsn(opcode, owner, name, desc);
      return;
    }

    // every basicField has a special set of field interception methods
    if (opcode == Opcodes.GETFIELD) {
      String methodName = "_ebean_get_" + name;
      String methodDesc = "()" + desc;
      if (meta.isLog(4)) {
        meta.log(
            "GETFIELD method:"
                + methodDescription
                + " field:"
                + name
                + " > "
                + methodName
                + " "
                + methodDesc);
      }
      super.visitMethodInsn(INVOKEVIRTUAL, className, methodName, methodDesc, false);

    } else if (opcode == Opcodes.PUTFIELD) {
      String methodName = "_ebean_set_" + name;
      String methodDesc = "(" + desc + ")V";
      if (meta.isLog(4)) {
        meta.log(
            "PUTFIELD method:"
                + methodDescription
                + " field:"
                + name
                + " > "
                + methodName
                + " "
                + methodDesc);
      }
      super.visitMethodInsn(INVOKEVIRTUAL, className, methodName, methodDesc, false);

    } else {
      meta.log(
          "Warning adapting method:"
              + methodDescription
              + "; unexpected static access to a persistent field?? "
              + name
              + " opCode not GETFIELD or PUTFIELD??  opCode:"
              + opcode
              + "");

      super.visitFieldInsn(opcode, owner, name, desc);
    }
  }
 public MethodFieldAdapter(MethodVisitor mv, ClassMeta meta, String methodDescription) {
   super(Opcodes.ASM5, mv);
   this.meta = meta;
   this.className = meta.getClassName();
   this.methodDescription = methodDescription;
 }
 /** Return true if the field is non-persistent and hence should not be intercepted. */
 private boolean isNonPersistentField(String owner, String name) {
   return !isSameOwner(owner) || !meta.isFieldPersistent(name);
 }
Example #9
0
  /**
   * String, Date, and Class have been written before calling this method, strictly for performance.
   *
   * @param obj Object to be written in JSON format
   * @param showType boolean true means show the "@type" field, false eliminates it. Many times the
   *     type can be dropped because it can be inferred from the field or array type.
   * @throws IOException if an error occurs writing to the output stream.
   */
  private void writeObject(Object obj, boolean showType) throws IOException {
    if (obj instanceof String) {
      writeJsonUtf8String((String) obj);
      return;
    } else if (obj.getClass().equals(Date.class)) {
      writeDate(obj, showType);
      return;
    } else if (obj instanceof Class) {
      writeClass(obj, showType);
      return;
    }

    if (writeOptionalReference(obj)) {
      return;
    }

    if (obj instanceof Calendar) {
      Calendar cal = (Calendar) obj;
      _dateFormat.setTimeZone(cal.getTimeZone());
      String date = _dateFormat.format(cal.getTime());
      writeSpecial(obj, showType, date);
      return;
    } else if (obj instanceof BigDecimal) {
      writeSpecial(obj, showType, ((BigDecimal) obj).toPlainString());
      return;
    } else if (obj instanceof BigInteger) {
      writeSpecial(obj, showType, obj.toString());
      return;
    } else if (obj instanceof java.sql.Date) {
      writeSpecial(obj, showType, obj.toString());
      return;
    }

    _out.write('{');
    boolean referenced = _objsReferenced.containsKey(obj);
    if (referenced) {
      writeId(getId(obj));
    }

    ClassMeta classInfo = getDeepDeclaredFields(obj.getClass());
    if (classInfo._writeMethod
        != null) { // Must show type when class has custom _writeJson() method on it.
      // The JsonReader uses this to know it is dealing with an object
      // that has custom json io methods on it.
      showType = true;
    }

    if (referenced && showType) {
      _out.write(',');
    }

    if (showType) {
      writeType(obj);
    }

    boolean first = !showType;
    if (referenced && !showType) {
      first = false;
    }

    if (classInfo._writeMethod == null) {
      for (Field field : classInfo.values()) {
        if (_prettyMode
            && (field.getModifiers() & Modifier.TRANSIENT)
                != 0) { // Skip transient fields when in 'prettyMode'
          continue;
        }

        if (first) {
          first = false;
        } else {
          _out.write(',');
        }

        writeJsonUtf8String(field.getName());
        _out.write(':');

        Object o;
        try {
          o = field.get(obj);
        } catch (IllegalAccessException e) {
          o = null;
        }

        if (o == null) { // don't quote null
          _out.write("null");
          continue;
        }

        Class type = field.getType();
        boolean forceType =
            o.getClass() != type; // If types are not exactly the same, write "@type" field

        if (isPrimitiveWrapper(type)) {
          writePrimitive(o);
        } else {
          writeImpl(o, forceType);
        }
      }
    } else { // Invoke custom _writeJson() method.
      _out.write(',');
      try {
        classInfo._writeMethod.invoke(obj, _out);
      } catch (Exception e) {
        throw new IOException("Error invoking " + obj.getClass() + "._jsonWrite()", e);
      }
    }

    _out.write('}');
  }