@Override public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { return null; } TypeDescriptor elementDesc = targetType.getElementTypeDescriptor(); Collection<Object> target = CollectionFactory.createCollection(targetType.getType(), (elementDesc != null ? elementDesc.getType() : null), 1); if (elementDesc == null || elementDesc.isCollection()) { target.add(source); } else { Object singleElement = this.conversionService.convert(source, sourceType, elementDesc); target.add(singleElement); } return target; }
/** * Populates the property on the other side of the relationship. * * @param relationship the relationship on the wrapped data object for which to populate the inverse relationship. * @param propertyValue the value of the property. */ protected void populateInverseRelationship(MetadataChild relationship, Object propertyValue) { if (propertyValue != null) { MetadataChild inverseRelationship = relationship.getInverseRelationship(); if (inverseRelationship != null) { DataObjectWrapper<?> wrappedRelationship = dataObjectService.wrap(propertyValue); if (inverseRelationship instanceof DataObjectCollection) { DataObjectCollection collectionRelationship = (DataObjectCollection)inverseRelationship; String colRelName = inverseRelationship.getName(); Collection<Object> collection = (Collection<Object>)wrappedRelationship.getPropertyValue(colRelName); if (collection == null) { // if the collection is null, let's instantiate an empty one collection = CollectionFactory.createCollection(wrappedRelationship.getPropertyType(colRelName), 1); wrappedRelationship.setPropertyValue(colRelName, collection); } collection.add(getWrappedInstance()); } } } }
/** * @param path * @param collectionType * @param valueType * @param source * @return */ private Collection<?> readCollectionOfComplexTypes(String path, Class<?> collectionType, Class<?> valueType, RedisData source) { Collection<Object> target = CollectionFactory.createCollection(collectionType, valueType, 10); Set<byte[]> values = getKeysStartingWith(toBytes(path + ".["), source); for (byte[] value : values) { RedisData newPartialSource = new RedisData(extractDataStartingWith(value, source)); byte[] typeInfo = source.getDataForKey(ByteUtils.concat(value, toBytes("._class"))); if (typeInfo != null && typeInfo.length > 0) { newPartialSource.addDataEntry(toBytes("_class"), typeInfo); } Object o = readInternal(fromBytes(value, String.class), valueType, newPartialSource); target.add(o); } return target; }
/** * @param path * @param mapType * @param keyType * @param valueType * @param source * @return */ private Map<?, ?> readMapOfSimpleTypes(String path, Class<?> mapType, Class<?> keyType, Class<?> valueType, RedisData source) { Map<Object, Object> target = CollectionFactory.createMap(mapType, 10); byte[] prefix = toBytes(path + ".["); byte[] postfix = toBytes("]"); Map<byte[], byte[]> values = extractDataStartingWith(toBytes(path + ".["), source); for (Entry<byte[], byte[]> entry : values.entrySet()) { byte[] binKey = ByteUtils.extract(entry.getKey(), prefix, postfix); Object key = fromBytes(binKey, keyType); target.put(key, fromBytes(entry.getValue(), valueType)); } return target; }
private Object readCollection(Collection<?> source, TypeInformation<?> type, Object parent) { Assert.notNull(type); Class<?> collectionType = type.getType(); if (CollectionUtils.isEmpty(source)) { return source; } collectionType = Collection.class.isAssignableFrom(collectionType) ? collectionType : List.class; Collection<Object> items; if (type.getType().isArray()) { items = new ArrayList<Object>(); } else { items = CollectionFactory.createCollection(collectionType, source.size()); } TypeInformation<?> componentType = type.getComponentType(); Iterator<?> it = source.iterator(); while (it.hasNext()) { items.add(readValue(it.next(), componentType, parent)); } return type.getType().isArray() ? convertItemsToArrayOfType(type, items) : items; }
@SuppressWarnings("unchecked") private Object readCollection(Collection<?> source, TypeInformation<?> type, Object parent) { Assert.notNull(type); Class<?> collectionType = type.getType(); if (CollectionUtils.isEmpty(source)) { return source; } collectionType = Collection.class.isAssignableFrom(collectionType) ? collectionType : List.class; Collection<Object> items = type.getType().isArray() ? new ArrayList<Object>() : CollectionFactory .createCollection(collectionType, source.size()); TypeInformation<?> componentType = type.getComponentType(); Iterator<?> it = source.iterator(); while (it.hasNext()) { items.add(readValue(it.next(), componentType, parent)); } return type.getType().isArray() ? convertItemsToArrayOfType(type, items) : items; }
private Object readCollectionOrArray(Path path, Class<?> collectionType, Class<?> valueType, Tuple tuple) { List<Path> keys = new ArrayList<>(tuple.extractAllKeysFor(path)); boolean isArray = collectionType.isArray(); Class<?> collectionTypeToUse = isArray ? ArrayList.class : collectionType; Collection<Object> target = CollectionFactory.createCollection(collectionTypeToUse, valueType, keys.size()); for (Path key : keys) { // if (key.endsWith(TYPE_HINT_ALIAS)) { // continue; // } // Tuple elementData = tuple.extract(key); // byte[] typeInfo = elementData.get(key + "." + TYPE_HINT_ALIAS); // if (typeInfo != null && typeInfo.length > 0) { // elementData.put(TYPE_HINT_ALIAS, typeInfo); // } Class<?> typeToUse = getTypeHint(key, tuple, valueType); if (isTarantoolNativeType(valueType)) { target.add(fromTarantoolNativeType(elementData.get(key), typeToUse)); } else { target.add(readInternal(key, valueType, new TarantoolData(elementData))); } } return isArray ? toArray(target, collectionType, valueType) : target; }
private Collection<?> convertDataArrayToTargetCollection(Object[] array, Class<?> collectionType, Class<?> elementType) throws NoSuchMethodException { Method fromMethod = elementType.getMethod("from", array.getClass().getComponentType()); Collection<Object> resultColl = CollectionFactory.createCollection(collectionType, Array.getLength(array)); for (int i = 0; i < array.length; i++) { resultColl.add(ReflectionUtils.invokeMethod(fromMethod, null, array[i])); } return resultColl; }
private Object newValue(Class<?> type, String name) { try { if (type.isArray()) { Class<?> componentType = type.getComponentType(); // TODO - only handles 2-dimensional arrays if (componentType.isArray()) { Object array = Array.newInstance(componentType, 1); Array.set(array, 0, Array.newInstance(componentType.getComponentType(), 0)); return array; } else { return Array.newInstance(componentType, 0); } } else if (Collection.class.isAssignableFrom(type)) { return CollectionFactory.createCollection(type, 16); } else if (Map.class.isAssignableFrom(type)) { return CollectionFactory.createMap(type, 16); } else { return type.newInstance(); } } catch (Exception ex) { // TODO Root cause exception context is lost here... should we throw another exception type that preserves context instead? throw new NullValueInNestedPathException(getRootClass(), this.nestedPath + name, "Could not instantiate property type [" + type.getName() + "] to auto-grow nested property path: " + ex); } }
@Override public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { return null; } Collection<?> sourceCollection = (Collection<?>) source; // Shortcut if possible... boolean copyRequired = !targetType.getType().isInstance(source); if (!copyRequired && sourceCollection.isEmpty()) { return source; } TypeDescriptor elementDesc = targetType.getElementTypeDescriptor(); if (elementDesc == null && !copyRequired) { return source; } // At this point, we need a collection copy in any case, even if just for finding out about element copies... Collection<Object> target = CollectionFactory.createCollection(targetType.getType(), (elementDesc != null ? elementDesc.getType() : null), sourceCollection.size()); if (elementDesc == null) { target.addAll(sourceCollection); } else { for (Object sourceElement : sourceCollection) { Object targetElement = this.conversionService.convert(sourceElement, sourceType.elementTypeDescriptor(sourceElement), elementDesc); target.add(targetElement); if (sourceElement != targetElement) { copyRequired = true; } } } return (copyRequired ? target : source); }
private Object newValue(Class<?> type, TypeDescriptor desc, String name) { try { if (type.isArray()) { Class<?> componentType = type.getComponentType(); // TODO - only handles 2-dimensional arrays if (componentType.isArray()) { Object array = Array.newInstance(componentType, 1); Array.set(array, 0, Array.newInstance(componentType.getComponentType(), 0)); return array; } else { return Array.newInstance(componentType, 0); } } else if (Collection.class.isAssignableFrom(type)) { TypeDescriptor elementDesc = (desc != null ? desc.getElementTypeDescriptor() : null); return CollectionFactory.createCollection(type, (elementDesc != null ? elementDesc.getType() : null), 16); } else if (Map.class.isAssignableFrom(type)) { TypeDescriptor keyDesc = (desc != null ? desc.getMapKeyTypeDescriptor() : null); return CollectionFactory.createMap(type, (keyDesc != null ? keyDesc.getType() : null), 16); } else { return BeanUtils.instantiate(type); } } catch (Exception ex) { // TODO: Root cause exception context is lost here; just exception message preserved. // Should we throw another exception type that preserves context instead? throw new NullValueInNestedPathException(getRootClass(), this.nestedPath + name, "Could not instantiate property type [" + type.getName() + "] to auto-grow nested property path: " + ex); } }
/** * Reads the given {@link List} into a collection of the given {@link TypeInformation} * . * * @param targetType must not be {@literal null}. * @param sourceValue must not be {@literal null}. * @return the converted {@link Collection} or array, will never be {@literal null}. */ @Nullable @SuppressWarnings({ "rawtypes", "unchecked" }) private Object readCollectionOrArray(TypeInformation<?> targetType, List sourceValue) { Assert.notNull(targetType, "Target type must not be null!"); Class<?> collectionType = targetType.getType(); TypeInformation<?> componentType = targetType.getComponentType() != null ? targetType .getComponentType() : ClassTypeInformation.OBJECT; Class<?> rawComponentType = componentType.getType(); collectionType = Collection.class.isAssignableFrom(collectionType) ? collectionType : List.class; Collection<Object> items = targetType.getType().isArray() ? new ArrayList<>( sourceValue.size()) : CollectionFactory.createCollection(collectionType, rawComponentType, sourceValue.size()); if (sourceValue.isEmpty()) { return getPotentiallyConvertedSimpleRead(items, collectionType); } for (Object obj : sourceValue) { if (obj instanceof Map) { items.add(read(componentType, (Map) obj)); } else if (obj instanceof List) { items.add(readCollectionOrArray(ClassTypeInformation.OBJECT, (List) obj)); } else { items.add(getPotentiallyConvertedSimpleRead(obj, rawComponentType)); } } return getPotentiallyConvertedSimpleRead(items, targetType.getType()); }
/** * @param path * @param collectionType * @param valueType * @param source * @return */ private Collection<?> readCollectionOfSimpleTypes(String path, Class<?> collectionType, Class<?> valueType, RedisData source) { Collection<Object> target = CollectionFactory.createCollection(collectionType, valueType, 10); Map<byte[], byte[]> values = extractDataStartingWith(toBytes(path + ".["), source); for (byte[] value : values.values()) { target.add(fromBytes(value, valueType)); } return target; }
/** * @param path * @param mapType * @param keyType * @param valueType * @param source * @return */ private Map<?, ?> readMapOfComplexTypes(String path, Class<?> mapType, Class<?> keyType, Class<?> valueType, RedisData source) { Map<Object, Object> target = CollectionFactory.createMap(mapType, 10); byte[] prefix = toBytes(path + ".["); byte[] postfix = toBytes("]"); Set<byte[]> keys = getKeysStartingWith(prefix, source); for (byte[] fullKey : keys) { byte[] binKey = ByteUtils.extract(fullKey, prefix, postfix); Object key = fromBytes(binKey, keyType); RedisData newPartialSource = new RedisData(extractDataStartingWith(fullKey, source)); byte[] typeInfo = source.getDataForKey(ByteUtils.concat(fullKey, toBytes("._class"))); if (typeInfo != null && typeInfo.length > 0) { newPartialSource.addDataEntry(toBytes("_class"), typeInfo); } Object o = readInternal(fromBytes(fullKey, String.class), valueType, newPartialSource); target.put(key, o); } return target; }
@SuppressWarnings("unchecked") private Collection convertDataArrayToTargetCollection(Object[] array, Class collectionType, Class elementType) throws NoSuchMethodException { Method fromMethod = elementType.getMethod("from", array.getClass().getComponentType()); Collection resultColl = CollectionFactory.createCollection(collectionType, Array.getLength(array)); for (int i = 0; i < array.length; i++) { resultColl.add(ReflectionUtils.invokeMethod(fromMethod, null, array[i])); } return resultColl; }
@SuppressWarnings("unchecked") public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { return null; } Collection<?> sourceCollection = (Collection<?>) source; // Shortcut if possible... boolean copyRequired = !targetType.getType().isInstance(source); if (!copyRequired && sourceCollection.isEmpty()) { return source; } TypeDescriptor elementDesc = targetType.getElementTypeDescriptor(); if (elementDesc == null && !copyRequired) { return source; } // At this point, we need a collection copy in any case, even if just for finding out about element copies... Collection<Object> target = CollectionFactory.createCollection(targetType.getType(), sourceCollection.size()); if (elementDesc == null) { target.addAll(sourceCollection); } else { for (Object sourceElement : sourceCollection) { Object targetElement = this.conversionService.convert(sourceElement, sourceType.elementTypeDescriptor(sourceElement), elementDesc); target.add(targetElement); if (sourceElement != targetElement) { copyRequired = true; } } } return (copyRequired ? target : source); }
@SuppressWarnings("unchecked") public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { return null; } Collection<Object> target = CollectionFactory.createCollection(targetType.getType(), 1); if (targetType.getElementTypeDescriptor() == null || targetType.getElementTypeDescriptor().isCollection()) { target.add(source); } else { Object singleElement = this.conversionService.convert(source, sourceType, targetType.getElementTypeDescriptor()); target.add(singleElement); } return target; }
/** * Reads the given {@link Map} 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 Map}. * @param sourceMap must not be {@literal null} * @return */ @SuppressWarnings("unchecked") protected Map<Object, Object> readMap(TypeInformation<?> type, Map<String, Object> sourceMap) { Assert.notNull(sourceMap, "Source map must not be null!"); Class<?> mapType = typeMapper.readType(sourceMap, type).getType(); TypeInformation<?> keyType = type.getComponentType(); TypeInformation<?> valueType = type.getMapValueType(); Class<?> rawKeyType = keyType != null ? keyType.getType() : null; Class<?> rawValueType = valueType != null ? valueType.getType() : null; Map<Object, Object> map = CollectionFactory.createMap(mapType, rawKeyType, sourceMap.keySet().size()); for (Entry<String, Object> entry : sourceMap.entrySet()) { if (typeMapper.isTypeKey(entry.getKey())) { continue; } Object key = entry.getKey(); if (rawKeyType != null && !rawKeyType.isAssignableFrom(key.getClass())) { key = conversionService.convert(key, rawKeyType); } Object value = entry.getValue(); TypeInformation<?> defaultedValueType = valueType != null ? valueType : ClassTypeInformation.OBJECT; if (value instanceof Map) { map.put(key, read(defaultedValueType, (Map) value)); } else if (value instanceof List) { map.put(key, readCollectionOrArray(valueType != null ? valueType : ClassTypeInformation.LIST, (List) value)); } else { map.put(key, getPotentiallyConvertedSimpleRead(value, rawValueType)); } } return map; }
/** * Before call to {@link ObjectMapper#readValue(java.io.InputStream, Class)} * creates a {@link ServletRequestDataBinder} and put it to current Thread * in order to be used by the {@link DataBinderDeserializer}. * <p/> * Ref: <a href= * "http://java.dzone.com/articles/java-thread-local-%E2%80%93-how-use">When * to use Thread Local?</a> * * @param javaType * @param inputMessage * @return */ private Object readJavaType(JavaType javaType, HttpInputMessage inputMessage) { try { Object target = null; String objectName = null; // CRear el DataBinder con un target object en funcion del javaType, // ponerlo en el thread local Class<?> clazz = javaType.getRawClass(); if (Collection.class.isAssignableFrom(clazz)) { Class<?> contentClazz = javaType.getContentType().getRawClass(); target = new DataBinderList<Object>(contentClazz); objectName = "list"; } else if (Map.class.isAssignableFrom(clazz)) { // TODO Class<?> contentClazz = // javaType.getContentType().getRawClass(); target = CollectionFactory.createMap(clazz, 0); objectName = "map"; } else { target = BeanUtils.instantiateClass(clazz); objectName = "bean"; } WebDataBinder binder = new ServletRequestDataBinder(target, objectName); binder.setConversionService(this.conversionService); binder.setAutoGrowNestedPaths(true); binder.setValidator(validator); ThreadLocalUtil.setThreadVariable( BindingResult.MODEL_KEY_PREFIX.concat("JSON_DataBinder"), binder); Object value = getObjectMapper().readValue(inputMessage.getBody(), javaType); return value; } catch (IOException ex) { throw new HttpMessageNotReadableException( "Could not read JSON: ".concat(ex.getMessage()), ex); } }
private void addMapForKeySpace(String keyspace) { store.put(keyspace, CollectionFactory.createMap(keySpaceMapType, 1000)); }
/** * Creates a new {@link MapKeyValueAdapter} using the given {@link Map} as backing store. * * @param mapType must not be {@literal null}. */ @SuppressWarnings("rawtypes") public MapKeyValueAdapter(Class<? extends Map> mapType) { this(CollectionFactory.createMap(mapType, 100), mapType); }