Class PropertyPath

java.lang.Object
org.springframework.beans.PropertyPath

public final class PropertyPath extends Object
A parsed bean property path, such as "person.addresses[1].city".

Parses bean property paths for property access: it decides whether a given string is a well-formed property path (see grammar) and where each path segment begins and ends. The canonical form is used for policy matching and error reporting. The structured segment list is used for property navigation within beans.

The grammar is:

PropertyPath := Segment ('.' Segment)*
Segment      := Name Index*                  -- Name may be empty only if at least one Index follows
Name         := char* excluding '.', '[', ']'
Index        := '[' Key ']'
Key          := QuotedKey | RawKey
QuotedKey    := "'" [^']* "'"  |  '"' [^"]* '"'
RawKey       := char* excluding quote characters, with balanced '[' / ']' nesting

The parse methods reject a path that does not match this grammar, or whose nesting depth exceeds the configured maximum, with an InvalidPropertyPathException.

Since:
7.1
Author:
Brian Clozel, Sam Brannen
  • Method Details

    • parse

      public static PropertyPath parse(String path) throws InvalidPropertyPathException
      Parse the given property path, without any limit on its nesting depth.

      Intended for paths supplied by the application itself, such as configured field names. Use parse(String, Options) with a maximum nesting depth for paths from external input, such as request parameter names.

      Parameters:
      path - the property path to parse; an empty string is a valid path with no segments
      Returns:
      the parsed property path
      Throws:
      InvalidPropertyPathException - if the given path is not a well-formed property path
      See Also:
    • parse

      public static PropertyPath parse(String path, PropertyPath.Options options) throws InvalidPropertyPathException
      Parse the given property path, rejecting it if its nesting depth exceeds the maximum configured in the given options.

      The maximum nesting depth is enforced while parsing: a path that exceeds it is rejected once the first segment beyond that depth has been read, without parsing the remainder of the path.

      Parameters:
      path - the property path to parse; an empty string is a valid path with no segments
      options - the parsing options to apply
      Returns:
      the parsed property path
      Throws:
      InvalidPropertyPathException - if the given path is not a well-formed property path, or if its nesting depth exceeds the maximum configured in the given options
    • canonicalNameOrOriginal

      public static String canonicalNameOrOriginal(@Nullable String path)
      path's canonical form, or path itself if it is not a well-formed property path (including a null path, for which this returns an empty string).

      A convenience for callers with nothing better to fall back to than the original string, such as canonicalizing a user-supplied field name for display, comparison, or configuration matching, as opposed to parse(String) itself, whose non-throwing behavior would be the wrong default for a caller that is about to navigate an object graph.

      Parameters:
      path - the property path to canonicalize, possibly null
      Returns:
      the canonical form of path, or path unchanged (or an empty string, if path is null) if it is not a well-formed property path
      Since:
      7.1
    • canonicalName

      public String canonicalName()
      Return the canonical string form of this path.

      Unnecessary surrounding quotes are removed from keys: map['key'].name → map[key].name.

    • segments

      public List<PropertyPath.Segment> segments()
      Return the segments of this path, in order, as an unmodifiable list.
    • subPath

      public PropertyPath subPath(int fromIndex)
      Return the sub-path made up of this path's segments from the given index to the end, such as the "country.name" sub-path of "address.country.name" from index 1.
      Parameters:
      fromIndex - the index of the first segment to include (inclusive)
      Returns:
      the sub-path starting at fromIndex
      Throws:
      IndexOutOfBoundsException - if fromIndex is negative
      IllegalArgumentException - if fromIndex is greater than segments().size()
    • equals

      public boolean equals(@Nullable Object other)
      Overrides:
      equals in class Object
    • hashCode

      public int hashCode()
      Overrides:
      hashCode in class Object
    • toString

      public String toString()
      Overrides:
      toString in class Object