Package org.springframework.core.convert

Examples of org.springframework.core.convert.TypeDescriptor


  @Override
  public TypedValue getValueInternal(ExpressionState state) throws EvaluationException {
    TypedValue context = state.getActiveContextObject();
    Object targetObject = context.getValue();
    TypeDescriptor targetObjectTypeDescriptor = context.getTypeDescriptor();
    TypedValue indexValue = null;
    Object index = null;
   
    // This first part of the if clause prevents a 'double dereference' of the property (SPR-5847)
    if (targetObject instanceof Map && (children[0] instanceof PropertyOrFieldReference)) {
      PropertyOrFieldReference reference = (PropertyOrFieldReference)children[0];
      index = reference.getName();
      indexValue = new TypedValue(index);
    }
    else {
      // In case the map key is unqualified, we want it evaluated against the root object so
      // temporarily push that on whilst evaluating the key
      try {
        state.pushActiveContextObject(state.getRootContextObject());
        indexValue = children[0].getValueInternal(state);
        index = indexValue.getValue();
      }
      finally {
        state.popActiveContextObject();
      }
    }

    // Indexing into a Map
    if (targetObject instanceof Map) {
      Object key = index;
      if (targetObjectTypeDescriptor.getMapKeyTypeDescriptor() != null) {
        key = state.convertValue(key, targetObjectTypeDescriptor.getMapKeyTypeDescriptor());
      }
      Object value = ((Map<?, ?>) targetObject).get(key);
      return new TypedValue(value, targetObjectTypeDescriptor.getMapValueTypeDescriptor(value));
    }
   
    if (targetObject == null) {
      throw new SpelEvaluationException(getStartPosition(),SpelMessage.CANNOT_INDEX_INTO_NULL_VALUE);
    }
   
    // if the object is something that looks indexable by an integer, attempt to treat the index value as a number
    if (targetObject instanceof Collection || targetObject.getClass().isArray() || targetObject instanceof String) {
      int idx = (Integer) state.convertValue(index, TypeDescriptor.valueOf(Integer.class));   
      if (targetObject.getClass().isArray()) {
        Object arrayElement = accessArrayElement(targetObject, idx);
        return new TypedValue(arrayElement, targetObjectTypeDescriptor.elementTypeDescriptor(arrayElement));
      } else if (targetObject instanceof Collection) {
        Collection c = (Collection) targetObject;
        if (idx >= c.size()) {
          if (!growCollection(state, targetObjectTypeDescriptor, idx, c)) {
            throw new SpelEvaluationException(getStartPosition(),SpelMessage.COLLECTION_INDEX_OUT_OF_BOUNDS, c.size(), idx);
          }
        }
        int pos = 0;
        for (Object o : c) {
          if (pos == idx) {
            return new TypedValue(o, targetObjectTypeDescriptor.elementTypeDescriptor(o));
          }
          pos++;
        }
      } else if (targetObject instanceof String) {
        String ctxString = (String) targetObject;
        if (idx >= ctxString.length()) {
          throw new SpelEvaluationException(getStartPosition(),SpelMessage.STRING_INDEX_OUT_OF_BOUNDS, ctxString.length(), idx);
        }
        return new TypedValue(String.valueOf(ctxString.charAt(idx)));
      }
    }
   
    // Try and treat the index value as a property of the context object
    // TODO could call the conversion service to convert the value to a String   
    if (indexValue.getTypeDescriptor().getType()==String.class) {
      Class<?> targetObjectRuntimeClass = getObjectClass(targetObject);
      String name = (String)indexValue.getValue();
      EvaluationContext eContext = state.getEvaluationContext();

      try {
        if (cachedReadName!=null && cachedReadName.equals(name) && cachedReadTargetType!=null && cachedReadTargetType.equals(targetObjectRuntimeClass)) {
          // it is OK to use the cached accessor
          return cachedReadAccessor.read(eContext, targetObject, name);
        }
       
        List<PropertyAccessor> accessorsToTry = AstUtils.getPropertyAccessorsToTry(targetObjectRuntimeClass, state);
   
        if (accessorsToTry != null) {     
          for (PropertyAccessor accessor : accessorsToTry) {
              if (accessor.canRead(eContext, targetObject, name)) {
                if (accessor instanceof ReflectivePropertyAccessor) {
                  accessor = ((ReflectivePropertyAccessor)accessor).createOptimalAccessor(eContext, targetObject, name);
                }
                this.cachedReadAccessor = accessor;
                this.cachedReadName = name;
                this.cachedReadTargetType = targetObjectRuntimeClass;
                return accessor.read(eContext, targetObject, name);
              }
          }
        }
      } catch (AccessException e) {
        throw new SpelEvaluationException(getStartPosition(), e, SpelMessage.INDEXING_NOT_SUPPORTED_FOR_TYPE, targetObjectTypeDescriptor.toString());
      }
    }
     
    throw new SpelEvaluationException(getStartPosition(),SpelMessage.INDEXING_NOT_SUPPORTED_FOR_TYPE, targetObjectTypeDescriptor.toString());
  }
View Full Code Here


  @SuppressWarnings("unchecked")
  @Override
  public void setValue(ExpressionState state, Object newValue) throws EvaluationException {
    TypedValue contextObject = state.getActiveContextObject();
    Object targetObject = contextObject.getValue();
    TypeDescriptor targetObjectTypeDescriptor = contextObject.getTypeDescriptor();
    TypedValue index = children[0].getValueInternal(state);

    if (targetObject == null) {
      throw new SpelEvaluationException(SpelMessage.CANNOT_INDEX_INTO_NULL_VALUE);
    }
    // Indexing into a Map
    if (targetObject instanceof Map) {
      Map map = (Map) targetObject;
      Object key = index.getValue();
      if (targetObjectTypeDescriptor.getMapKeyTypeDescriptor() != null) {
        key = state.convertValue(index, targetObjectTypeDescriptor.getMapKeyTypeDescriptor());
      }
      if (targetObjectTypeDescriptor.getMapValueTypeDescriptor() != null) {
        newValue = state.convertValue(newValue, targetObjectTypeDescriptor.getMapValueTypeDescriptor());       
      }
      map.put(key, newValue);
      return;
    }

    if (targetObjectTypeDescriptor.isArray()) {
      int idx = (Integer)state.convertValue(index, TypeDescriptor.valueOf(Integer.class));
      setArrayElement(state, contextObject.getValue(), idx, newValue, targetObjectTypeDescriptor.getElementTypeDescriptor().getType());
      return;
    }
    else if (targetObject instanceof Collection) {
      int idx = (Integer) state.convertValue(index, TypeDescriptor.valueOf(Integer.class));
      Collection c = (Collection) targetObject;
      if (idx >= c.size()) {
        if (!growCollection(state, targetObjectTypeDescriptor, idx, c)) {
          throw new SpelEvaluationException(getStartPosition(),SpelMessage.COLLECTION_INDEX_OUT_OF_BOUNDS, c.size(), idx);
        }
      }
      if (targetObject instanceof List) {
        List list = (List) targetObject;
        if (targetObjectTypeDescriptor.getElementTypeDescriptor() != null) {
          newValue = state.convertValue(newValue, targetObjectTypeDescriptor.getElementTypeDescriptor());
        }
        list.set(idx, newValue);
        return;
      }
      else {
        throw new SpelEvaluationException(getStartPosition(),SpelMessage.INDEXING_NOT_SUPPORTED_FOR_TYPE, targetObjectTypeDescriptor.toString());
      }
    }
   
    // Try and treat the index value as a property of the context object   
    // TODO could call the conversion service to convert the value to a String   
    if (index.getTypeDescriptor().getType() == String.class) {
      Class<?> contextObjectClass = getObjectClass(contextObject.getValue());
      String name = (String)index.getValue();
      EvaluationContext eContext = state.getEvaluationContext();
      try {
        if (cachedWriteName!=null && cachedWriteName.equals(name) && cachedWriteTargetType!=null && cachedWriteTargetType.equals(contextObjectClass)) {
          // it is OK to use the cached accessor
          cachedWriteAccessor.write(eContext, targetObject, name,newValue);
          return;
        }
 
        List<PropertyAccessor> accessorsToTry = AstUtils.getPropertyAccessorsToTry(contextObjectClass, state);
        if (accessorsToTry != null) {
            for (PropertyAccessor accessor : accessorsToTry) {
              if (accessor.canWrite(eContext, contextObject.getValue(), name)) {
                this.cachedWriteName = name;
                this.cachedWriteTargetType = contextObjectClass;
                this.cachedWriteAccessor = accessor;
                accessor.write(eContext, contextObject.getValue(), name, newValue);
                return;
              }
            }
        }
      } catch (AccessException ae) {
        throw new SpelEvaluationException(getStartPosition(), ae, SpelMessage.EXCEPTION_DURING_PROPERTY_WRITE,
            name, ae.getMessage());
      }

    }
   
    throw new SpelEvaluationException(getStartPosition(),SpelMessage.INDEXING_NOT_SUPPORTED_FOR_TYPE, targetObjectTypeDescriptor.toString());
  }
View Full Code Here

      Collection collection) {
    if (state.getConfiguration().isAutoGrowCollections()) {
      if (targetType.getElementTypeDescriptor() == null) {
        throw new SpelEvaluationException(getStartPosition(), SpelMessage.UNABLE_TO_GROW_COLLECTION_UNKNOWN_ELEMENT_TYPE);       
      }
      TypeDescriptor elementType = targetType.getElementTypeDescriptor();
      Object newCollectionElement = null;
      try {
        int newElements = index - collection.size();
        while (newElements>0) {
          collection.add(elementType.getType().newInstance());
          newElements--;
        }
        newCollectionElement = elementType.getType().newInstance();
      }
      catch (Exception ex) {
        throw new SpelEvaluationException(getStartPosition(), ex, SpelMessage.UNABLE_TO_GROW_COLLECTION);
      }
      collection.add(newCollectionElement);
View Full Code Here

        }
        if (method.getName().equals(name)) {
          Class[] paramTypes = method.getParameterTypes();
          List<TypeDescriptor> paramDescriptors = new ArrayList<TypeDescriptor>(paramTypes.length);
          for (int i = 0; i < paramTypes.length; i++) {
            paramDescriptors.add(new TypeDescriptor(new MethodParameter(method, i)));
          }
          ReflectionHelper.ArgumentsMatchInfo matchInfo = null;
          if (method.isVarArgs() && argumentTypes.size() >= (paramTypes.length - 1)) {
            // *sigh* complicated
            matchInfo = ReflectionHelper.compareArgumentsVarargs(paramDescriptors, argumentTypes, typeConverter);
View Full Code Here

    TypedValue result = readProperty(state, this.name);
   
    // Dynamically create the objects if the user has requested that optional behaviour
    if (result.getValue() == null && state.getConfiguration().isAutoGrowNullReferences() &&
        nextChildIs(Indexer.class, PropertyOrFieldReference.class)) {
      TypeDescriptor resultDescriptor = result.getTypeDescriptor();
      // Creating lists and maps
      if ((resultDescriptor.getType().equals(List.class) || resultDescriptor.getType().equals(Map.class))) {
        // Create a new collection or map ready for the indexer
        if (resultDescriptor.getType().equals(List.class)) {
          try {
            if (isWritable(state)) {
              List newList = ArrayList.class.newInstance();
              writeProperty(state, this.name, newList);
              result = readProperty(state, this.name);
View Full Code Here

    Method method = findGetterForProperty(name, type, target instanceof Class);
    if (method != null) {
      // Treat it like a property
      // The readerCache will only contain gettable properties (let's not worry about setters for now)
      Property property = new Property(type, method, null);
      TypeDescriptor typeDescriptor = new TypeDescriptor(property);
      this.readerCache.put(cacheKey, new InvokerPair(method, typeDescriptor));
      this.typeDescriptorCache.put(cacheKey, typeDescriptor);
      return true;
    }
    else {
      Field field = findField(name, type, target instanceof Class);
      if (field != null) {
        TypeDescriptor typeDescriptor = new TypeDescriptor(field);
        this.readerCache.put(cacheKey, new InvokerPair(field,typeDescriptor))
        this.typeDescriptorCache.put(cacheKey, typeDescriptor);
        return true;
      }
    }
View Full Code Here

        if (method != null) {
          // TODO remove the duplication here between canRead and read
          // Treat it like a property
          // The readerCache will only contain gettable properties (let's not worry about setters for now)
          Property property = new Property(type, method, null);
          TypeDescriptor typeDescriptor = new TypeDescriptor(property);
          invoker = new InvokerPair(method, typeDescriptor);
          this.readerCache.put(cacheKey, invoker);
        }
      }
      if (method != null) {
        try {
          ReflectionUtils.makeAccessible(method);
          Object value = method.invoke(target);
          return new TypedValue(value, invoker.typeDescriptor.narrow(value));
        }
        catch (Exception ex) {
          throw new AccessException("Unable to access property '" + name + "' through getter", ex);
        }
      }
    }

    if (invoker == null || invoker.member instanceof Field) {
      Field field = (Field) (invoker == null ? null : invoker.member);
      if (field == null) {
        field = findField(name, type, target instanceof Class);
        if (field != null) {
          invoker = new InvokerPair(field, new TypeDescriptor(field));
          this.readerCache.put(cacheKey, invoker);
        }
      }
      if (field != null) {
        try {
View Full Code Here

    }
    Method method = findSetterForProperty(name, type, target instanceof Class);
    if (method != null) {
      // Treat it like a property
      Property property = new Property(type, null, method);
      TypeDescriptor typeDescriptor = new TypeDescriptor(property);
      this.writerCache.put(cacheKey, method);
      this.typeDescriptorCache.put(cacheKey, typeDescriptor);
      return true;
    }
    else {
      Field field = findField(name, type, target instanceof Class);
      if (field != null) {
        this.writerCache.put(cacheKey, field);
        this.typeDescriptorCache.put(cacheKey, new TypeDescriptor(field));
        return true;
      }
    }
    return false;
  }
View Full Code Here

      throw new AccessException("Cannot write property on null target");
    }
    Class<?> type = (target instanceof Class ? (Class<?>) target : target.getClass());

    Object possiblyConvertedNewValue = newValue;
    TypeDescriptor typeDescriptor = getTypeDescriptor(context, target, name);
    if (typeDescriptor != null) {
      try {
        possiblyConvertedNewValue = context.getTypeConverter().convertValue(
            newValue, TypeDescriptor.forObject(newValue), typeDescriptor);
      }
View Full Code Here

    if (type.isArray() && name.equals("length")) {
      return TypeDescriptor.valueOf(Integer.TYPE);
    }
    CacheKey cacheKey = new CacheKey(type, name);
    TypeDescriptor typeDescriptor =  this.typeDescriptorCache.get(cacheKey);
    if (typeDescriptor == null) {
      // attempt to populate the cache entry
      try {
        if (canRead(context, target, name)) {
          typeDescriptor =  this.typeDescriptorCache.get(cacheKey);
View Full Code Here

TOP

Related Classes of org.springframework.core.convert.TypeDescriptor

Copyright © 2018 www.massapicom. 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.