/**
   * Writes the given {@link Map} to the given {@link DBObject} considering the given {@link
   * TypeInformation}.
   *
   * @param obj must not be {@literal null}.
   * @param dbo must not be {@literal null}.
   * @param propertyType must not be {@literal null}.
   * @return
   */
  protected DBObject writeMapInternal(
      Map<Object, Object> obj, DBObject dbo, TypeInformation<?> propertyType) {

    for (Map.Entry<Object, Object> entry : obj.entrySet()) {

      Object key = entry.getKey();
      Object val = entry.getValue();

      if (conversions.isSimpleType(key.getClass())) {

        String simpleKey = prepareMapKey(key);
        if (val == null || conversions.isSimpleType(val.getClass())) {
          writeSimpleInternal(val, dbo, simpleKey);
        } else if (val instanceof Collection || val.getClass().isArray()) {
          dbo.put(
              simpleKey,
              writeCollectionInternal(
                  asCollection(val), propertyType.getMapValueType(), new BasicDBList()));
        } else {
          DBObject newDbo = new BasicDBObject();
          TypeInformation<?> valueTypeInfo =
              propertyType.isMap() ? propertyType.getMapValueType() : ClassTypeInformation.OBJECT;
          writeInternal(val, newDbo, valueTypeInfo);
          dbo.put(simpleKey, newDbo);
        }
      } else {
        throw new MappingException("Cannot use a complex object as a key value.");
      }
    }

    return dbo;
  }
 /**
  * Creates a new {@link Neo4jPersistentEntityImpl} instance.
  *
  * @param information must not be {@literal null}.
  */
 public Neo4jPersistentEntityImpl(TypeInformation<T> information) {
   super(information);
   for (Annotation annotation : information.getType().getAnnotations()) {
     annotations.put(annotation.annotationType(), annotation);
   }
   managed = ManagedEntity.class.isAssignableFrom(information.getType());
   shouldUseShortNames = shouldUseShortNames();
 }
  /**
   * Adds custom type information to the given {@link DBObject} if necessary. That is if the value
   * is not the same as the one given. This is usually the case if you store a subtype of the actual
   * declared type of the property.
   *
   * @param type
   * @param value must not be {@literal null}.
   * @param dbObject must not be {@literal null}.
   */
  protected void addCustomTypeKeyIfNecessary(
      TypeInformation<?> type, Object value, DBObject dbObject) {

    TypeInformation<?> actualType = type != null ? type.getActualType() : null;
    Class<?> reference = actualType == null ? Object.class : actualType.getType();
    Class<?> valueType = ClassUtils.getUserClass(value.getClass());

    boolean notTheSameClass = !valueType.equals(reference);
    if (notTheSameClass) {
      typeMapper.writeType(valueType, dbObject);
    }
  }
 @Override
 protected CassandraPersistentEntity<?> addPersistentEntity(TypeInformation<?> typeInformation) {
   if (!typeInformation.getType().isInterface()) {
     return super.addPersistentEntity(typeInformation);
   }
   return null;
 }
Exemplo n.º 5
0
    JsonSchemaProperty with(TypeInformation<?> type, String reference) {

      if (type.isCollectionLike()) {

        if (Set.class.equals(type.getType())) {
          this.uniqueItems = true;
        }

        this.type = toJsonSchemaType(type);
        this.items = Collections.singletonMap("$ref", reference);

        return this;

      } else {
        this.reference = reference;
        return this;
      }
    }
    private boolean isEnclosingClassParameter() {

      if (enclosingClassCache == null) {
        Class<T> owningType = entity.getType();
        this.enclosingClassCache =
            owningType.isMemberClass() && type.getType().equals(owningType.getEnclosingClass());
      }

      return enclosingClassCache;
    }
  public QuerydslBindings createBindingsFor(
      Class<? extends QuerydslBinderCustomizer> customizer, TypeInformation<?> domainType) {

    EntityPath<?> path = verifyEntityPathPresent(domainType);

    QuerydslBindings bindings = new QuerydslBindings();
    findCustomizerForDomainType(customizer, domainType.getType()).customize(bindings, path);

    return bindings;
  }
Exemplo n.º 8
0
  /**
   * Turns the given {@link TypeInformation} into a JSON Schema type string.
   *
   * @param typeInformation
   * @return
   * @see http://json-schema.org/latest/json-schema-core.html#anchor8
   */
  private static String toJsonSchemaType(TypeInformation<?> typeInformation) {

    Class<?> type = typeInformation.getType();

    if (type == null) {
      return null;
    } else if (typeInformation.isCollectionLike()) {
      return "array";
    } else if (Boolean.class.equals(type) || boolean.class.equals(type)) {
      return "boolean";
    } else if (String.class.equals(type) || isDate(typeInformation) || type.isEnum()) {
      return "string";
    } else if (INTEGER_TYPES.contains(type)) {
      return "integer";
    } else if (ClassUtils.isAssignable(Number.class, type)) {
      return "number";
    } else {
      return "object";
    }
  }
Exemplo n.º 9
0
    /**
     * Configures the {@link JsonSchemaProperty} to reflect the given type.
     *
     * @param type must not be {@literal null}.
     * @return
     */
    public JsonSchemaProperty with(TypeInformation<?> type) {

      Assert.notNull(type, "Type must not be null!");
      this.type = toJsonSchemaType(type);

      if (isDate(type)) {
        return withFormat(JsonSchemaFormat.DATE_TIME);
      }

      if (type.isCollectionLike()) {

        if (Set.class.equals(type.getType())) {
          this.uniqueItems = true;
        }

        this.items = Collections.singletonMap("type", toJsonSchemaType(type.getActualType()));
      }

      return this;
    }
  @SuppressWarnings("unchecked")
  private <S extends Object> S read(TypeInformation<S> type, DBObject dbo, ObjectPath path) {

    if (null == dbo) {
      return null;
    }

    TypeInformation<? extends S> typeToUse = typeMapper.readType(dbo, type);
    Class<? extends S> rawType = typeToUse.getType();

    if (conversions.hasCustomReadTarget(dbo.getClass(), rawType)) {
      return conversionService.convert(dbo, rawType);
    }

    if (DBObject.class.isAssignableFrom(rawType)) {
      return (S) dbo;
    }

    if (typeToUse.isCollectionLike() && dbo instanceof BasicDBList) {
      return (S) readCollectionOrArray(typeToUse, (BasicDBList) dbo, path);
    }

    if (typeToUse.isMap()) {
      return (S) readMap(typeToUse, dbo, path);
    }

    if (dbo instanceof BasicDBList) {
      throw new MappingException(
          String.format(INCOMPATIBLE_TYPES, dbo, BasicDBList.class, typeToUse.getType(), path));
    }

    // Retrieve persistent entity info
    MongoPersistentEntity<S> persistentEntity =
        (MongoPersistentEntity<S>) mappingContext.getPersistentEntity(typeToUse);
    if (persistentEntity == null) {
      throw new MappingException("No mapping metadata found for " + rawType.getName());
    }

    return read(persistentEntity, dbo, path);
  }
  /**
   * Tries to detect a Querydsl query type for the given domain type candidate via the configured
   * {@link EntityPathResolver}.
   *
   * @param candidate must not be {@literal null}.
   * @throws IllegalStateException to indicate the query type can't be found and manual
   *     configuration is necessary.
   */
  private EntityPath<?> verifyEntityPathPresent(TypeInformation<?> candidate) {

    EntityPath<?> path = entityPaths.get(candidate);

    if (path != null) {
      return path;
    }

    Class<?> type = candidate.getType();

    try {
      path = entityPathResolver.createPath(type);
    } catch (IllegalArgumentException o_O) {
      throw new IllegalStateException(
          String.format(
              INVALID_DOMAIN_TYPE, candidate.getType(), QuerydslPredicate.class.getSimpleName()),
          o_O);
    }

    entityPaths.put(candidate, path);
    return path;
  }
 private static boolean isEntity(java.lang.reflect.Field field) {
   TypeInformation typeInformation = ClassTypeInformation.from(field.getType());
   TypeInformation<?> actualType = typeInformation.getActualType();
   boolean isComplexType =
       actualType == null ? false : !SIMPLE_TYPE_HOLDER.isSimpleType(actualType.getType());
   return isComplexType
       && !actualType.isCollectionLike()
       && !Map.class.isAssignableFrom(typeInformation.getType());
 }
Exemplo n.º 13
0
  /**
   * Returns whether the given {@link TypeInformation} represents a date.
   *
   * @param type must not be {@literal null}.
   * @return
   */
  private static boolean isDate(TypeInformation<?> type) {

    Class<?> rawType = type.getType();

    if (Date.class.equals(rawType)) {
      return true;
    }

    for (String datePackage : Arrays.asList("java.time", "org.threeten.bp", "org.joda.time")) {
      if (rawType.getName().startsWith(datePackage)) {
        return true;
      }
    }

    return false;
  }
  @SuppressWarnings("unchecked")
  private <T> T readValue(Object value, TypeInformation<?> type, ObjectPath path) {

    Class<?> rawType = type.getType();

    if (conversions.hasCustomReadTarget(value.getClass(), rawType)) {
      return (T) conversionService.convert(value, rawType);
    } else if (value instanceof DBRef) {
      return potentiallyReadOrResolveDbRef((DBRef) value, type, path, rawType);
    } else if (value instanceof BasicDBList) {
      return (T) readCollectionOrArray(type, (BasicDBList) value, path);
    } else if (value instanceof DBObject) {
      return (T) read(type, (DBObject) value, path);
    } else {
      return (T) getPotentiallyConvertedSimpleRead(value, rawType);
    }
  }
  /**
   * Reads the given {@link DBObject} into a {@link Map}. will recursively resolve nested {@link
   * Map}s as well.
   *
   * @param type the {@link Map} {@link TypeInformation} to be used to unmarshall this {@link
   *     DBObject}.
   * @param dbObject must not be {@literal null}
   * @param path must not be {@literal null}
   * @return
   */
  @SuppressWarnings("unchecked")
  protected Map<Object, Object> readMap(
      TypeInformation<?> type, DBObject dbObject, ObjectPath path) {

    Assert.notNull(dbObject, "DBObject must not be null!");
    Assert.notNull(path, "Object path must not be null!");

    Class<?> mapType = typeMapper.readType(dbObject, type).getType();

    TypeInformation<?> keyType = type.getComponentType();
    Class<?> rawKeyType = keyType == null ? null : keyType.getType();

    TypeInformation<?> valueType = type.getMapValueType();
    Class<?> rawValueType = valueType == null ? null : valueType.getType();

    Map<Object, Object> map =
        CollectionFactory.createMap(mapType, rawKeyType, dbObject.keySet().size());
    Map<String, Object> sourceMap = dbObject.toMap();

    for (Entry<String, Object> entry : sourceMap.entrySet()) {
      if (typeMapper.isTypeKey(entry.getKey())) {
        continue;
      }

      Object key = potentiallyUnescapeMapKey(entry.getKey());

      if (rawKeyType != null) {
        key = conversionService.convert(key, rawKeyType);
      }

      Object value = entry.getValue();

      if (value instanceof DBObject) {
        map.put(key, read(valueType, (DBObject) value, path));
      } else if (value instanceof DBRef) {
        map.put(
            key,
            DBRef.class.equals(rawValueType) ? value : read(valueType, readRef((DBRef) value)));
      } else {
        Class<?> valueClass = valueType == null ? null : valueType.getType();
        map.put(key, getPotentiallyConvertedSimpleRead(value, valueClass));
      }
    }

    return map;
  }
  /*
   * (non-Javadoc)
   * @see org.springframework.data.convert.TypeInformationMapper#createAliasFor(org.springframework.data.util.TypeInformation)
   */
  public Object createAliasFor(TypeInformation<?> type) {

    CacheValue<Object> key = typeMap.get(type);

    if (key != null) {
      return key.getValue();
    }

    PersistentEntity<?, ?> entity = mappingContext.getPersistentEntity(type);

    if (entity == null) {
      return null;
    }

    Object alias = entity.getTypeAlias();
    safelyAddToCache(type.getRawTypeInformation(), alias);

    return alias;
  }
  /**
   * Populates the given {@link BasicDBList} with values from the given {@link Collection}.
   *
   * @param source the collection to create a {@link BasicDBList} for, must not be {@literal null}.
   * @param type the {@link TypeInformation} to consider or {@literal null} if unknown.
   * @param sink the {@link BasicDBList} to write to.
   * @return
   */
  private BasicDBList writeCollectionInternal(
      Collection<?> source, TypeInformation<?> type, BasicDBList sink) {

    TypeInformation<?> componentType = type == null ? null : type.getComponentType();

    for (Object element : source) {

      Class<?> elementType = element == null ? null : element.getClass();

      if (elementType == null || conversions.isSimpleType(elementType)) {
        sink.add(getPotentiallyConvertedSimpleWrite(element));
      } else if (element instanceof Collection || elementType.isArray()) {
        sink.add(writeCollectionInternal(asCollection(element), componentType, new BasicDBList()));
      } else {
        BasicDBObject propDbObj = new BasicDBObject();
        writeInternal(element, propDbObj, componentType);
        sink.add(propDbObj);
      }
    }

    return sink;
  }
  /**
   * Reads the given {@link BasicDBList} into a collection of the given {@link TypeInformation}.
   *
   * @param targetType must not be {@literal null}.
   * @param sourceValue must not be {@literal null}.
   * @param path must not be {@literal null}.
   * @return the converted {@link Collection} or array, will never be {@literal null}.
   */
  private Object readCollectionOrArray(
      TypeInformation<?> targetType, BasicDBList sourceValue, ObjectPath path) {

    Assert.notNull(targetType, "Target type must not be null!");
    Assert.notNull(path, "Object path must not be null!");

    Class<?> collectionType = targetType.getType();

    if (sourceValue.isEmpty()) {
      return getPotentiallyConvertedSimpleRead(new HashSet<Object>(), collectionType);
    }

    TypeInformation<?> componentType = targetType.getComponentType();
    Class<?> rawComponentType = componentType == null ? null : componentType.getType();

    collectionType =
        Collection.class.isAssignableFrom(collectionType) ? collectionType : List.class;
    Collection<Object> items =
        targetType.getType().isArray()
            ? new ArrayList<Object>()
            : CollectionFactory.createCollection(
                collectionType, rawComponentType, sourceValue.size());

    for (int i = 0; i < sourceValue.size(); i++) {

      Object dbObjItem = sourceValue.get(i);

      if (dbObjItem instanceof DBRef) {
        items.add(
            DBRef.class.equals(rawComponentType)
                ? dbObjItem
                : read(componentType, readRef((DBRef) dbObjItem), path));
      } else if (dbObjItem instanceof DBObject) {
        items.add(read(componentType, (DBObject) dbObjItem, path));
      } else {
        items.add(getPotentiallyConvertedSimpleRead(dbObjItem, rawComponentType));
      }
    }

    return getPotentiallyConvertedSimpleRead(items, targetType.getType());
  }
  /*
   * (non-Javadoc)
   * @see org.springframework.data.mongodb.core.convert.MongoWriter#convertToMongoType(java.lang.Object, org.springframework.data.util.TypeInformation)
   */
  @SuppressWarnings("unchecked")
  public Object convertToMongoType(Object obj, TypeInformation<?> typeInformation) {

    if (obj == null) {
      return null;
    }

    Class<?> target = conversions.getCustomWriteTarget(obj.getClass());
    if (target != null) {
      return conversionService.convert(obj, target);
    }

    if (conversions.isSimpleType(obj.getClass())) {
      // Doesn't need conversion
      return getPotentiallyConvertedSimpleWrite(obj);
    }

    TypeInformation<?> typeHint = typeInformation;

    if (obj instanceof BasicDBList) {
      return maybeConvertList((BasicDBList) obj, typeHint);
    }

    if (obj instanceof DBObject) {
      DBObject newValueDbo = new BasicDBObject();
      for (String vk : ((DBObject) obj).keySet()) {
        Object o = ((DBObject) obj).get(vk);
        newValueDbo.put(vk, convertToMongoType(o, typeHint));
      }
      return newValueDbo;
    }

    if (obj instanceof Map) {
      DBObject result = new BasicDBObject();
      for (Map.Entry<Object, Object> entry : ((Map<Object, Object>) obj).entrySet()) {
        result.put(entry.getKey().toString(), convertToMongoType(entry.getValue(), typeHint));
      }
      return result;
    }

    if (obj.getClass().isArray()) {
      return maybeConvertList(Arrays.asList((Object[]) obj), typeHint);
    }

    if (obj instanceof Collection) {
      return maybeConvertList((Collection<?>) obj, typeHint);
    }

    DBObject newDbo = new BasicDBObject();
    this.write(obj, newDbo);

    if (typeInformation == null) {
      return removeTypeInfo(newDbo, true);
    }

    if (typeInformation.getType().equals(NestedDocument.class)) {
      return removeTypeInfo(newDbo, false);
    }

    return !obj.getClass().equals(typeInformation.getType())
        ? newDbo
        : removeTypeInfo(newDbo, true);
  }
  @SuppressWarnings({"unchecked"})
  protected void writePropertyInternal(Object obj, DBObject dbo, MongoPersistentProperty prop) {

    if (obj == null) {
      return;
    }

    DBObjectAccessor accessor = new DBObjectAccessor(dbo);

    TypeInformation<?> valueType = ClassTypeInformation.from(obj.getClass());
    TypeInformation<?> type = prop.getTypeInformation();

    if (valueType.isCollectionLike()) {
      DBObject collectionInternal = createCollection(asCollection(obj), prop);
      accessor.put(prop, collectionInternal);
      return;
    }

    if (valueType.isMap()) {
      DBObject mapDbObj = createMap((Map<Object, Object>) obj, prop);
      accessor.put(prop, mapDbObj);
      return;
    }

    if (prop.isDbReference()) {

      DBRef dbRefObj = null;

      /*
       * If we already have a LazyLoadingProxy, we use it's cached DBRef value instead of
       * unnecessarily initializing it only to convert it to a DBRef a few instructions later.
       */
      if (obj instanceof LazyLoadingProxy) {
        dbRefObj = ((LazyLoadingProxy) obj).toDBRef();
      }

      dbRefObj = dbRefObj != null ? dbRefObj : createDBRef(obj, prop);

      if (null != dbRefObj) {
        accessor.put(prop, dbRefObj);
        return;
      }
    }

    /*
     * If we have a LazyLoadingProxy we make sure it is initialized first.
     */
    if (obj instanceof LazyLoadingProxy) {
      obj = ((LazyLoadingProxy) obj).getTarget();
    }

    // Lookup potential custom target type
    Class<?> basicTargetType = conversions.getCustomWriteTarget(obj.getClass(), null);

    if (basicTargetType != null) {
      accessor.put(prop, conversionService.convert(obj, basicTargetType));
      return;
    }

    Object existingValue = accessor.get(prop);
    BasicDBObject propDbObj =
        existingValue instanceof BasicDBObject
            ? (BasicDBObject) existingValue
            : new BasicDBObject();
    addCustomTypeKeyIfNecessary(ClassTypeInformation.from(prop.getRawType()), obj, propDbObj);

    MongoPersistentEntity<?> entity =
        isSubtype(prop.getType(), obj.getClass())
            ? mappingContext.getPersistentEntity(obj.getClass())
            : mappingContext.getPersistentEntity(type);

    writeInternal(obj, propDbObj, entity);
    accessor.put(prop, propDbObj);
  }
 /**
  * Returns the raw resolved type of the parameter.
  *
  * @return
  */
 public Class<T> getRawType() {
   return type.getType();
 }
  /**
   * Turn the given type information into the String representation that shall be stored. Default
   * implementation simply returns the fully-qualified class name.
   *
   * @param typeInformation must not be {@literal null}.
   * @return the String representation to be stored or {@literal null} if no type information shall
   *     be stored.
   */
  public String createAliasFor(TypeInformation<?> type) {

    return type == null ? null : type.getType().getName();
  }
Exemplo n.º 23
0
    /**
     * Creates a new {@link Item} for the given {@link TypeInformation} and properties.
     *
     * @param type must not be {@literal null}.
     * @param properties must not be {@literal null}.
     */
    public Item(TypeInformation<?> type, Collection<AbstractJsonSchemaProperty<?>> properties) {

      this.type = toJsonSchemaType(type.getActualType());
      this.properties = new PropertiesContainer(properties);
    }
Exemplo n.º 24
0
 static String typeKey(TypeInformation<?> type) {
   return StringUtils.uncapitalize(type.getActualType().getType().getSimpleName());
 }