001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.beanutils2.expression; 018 019/** 020 * Property Name Expression Resolver. 021 * <p> 022 * Methods such as PropertyUtilsBean's {@code setNestedProperty()} method use a {@code Resolver} to process a <em>property name</em> expression and resolve 023 * <em>nested</em>, <em>indexed</em> and <em>mapped</em> property names. The following code provides an example usage demonstrating all the methods: 024 * 025 * <pre> 026 * // Iterate through a nested property expression 027 * while (resolver.hasNested(name)) { 028 * 029 * // isolate a single property from a nested expression 030 * String next = resolver.next(name); 031 * 032 * // Process... 033 * String property = resolver.getProperty(next); 034 * if (resolver.isIndexed(next)) { 035 * 036 * int index = resolver.getIndex(next); 037 * bean = getIndexedProperty(bean, property, index); 038 * 039 * } else if (resolver.isMapped(next)) { 040 * 041 * String key = resolver.getKey(next); 042 * bean = getMappedProperty(bean, property, key); 043 * 044 * } else { 045 * 046 * bean = getSimpleProperty(bean, property); 047 * 048 * } 049 * 050 * // remove the processed property from the expression 051 * name = resolver.remove(name); 052 * } 053 * </pre> 054 * 055 * In order to create an implementation, it is important to understand how BeanUtils/PropertyUtils uses the {@code resolver}. The following are the main methods 056 * that use it: 057 * <ul> 058 * <li>{@link org.apache.commons.beanutils2.PropertyUtilsBean} 059 * <ul> 060 * <li>{@link org.apache.commons.beanutils2.PropertyUtilsBean#getIndexedProperty(Object, String)}</li> 061 * <li>{@link org.apache.commons.beanutils2.PropertyUtilsBean#getMappedProperty(Object, String)}</li> 062 * <li>{@link org.apache.commons.beanutils2.PropertyUtilsBean#getNestedProperty(Object, String)}</li> 063 * <li>{@link org.apache.commons.beanutils2.PropertyUtilsBean#getPropertyDescriptor(Object, String)}</li> 064 * <li>{@link org.apache.commons.beanutils2.PropertyUtilsBean#getSimpleProperty(Object, String)}</li> 065 * <li>{@link org.apache.commons.beanutils2.PropertyUtilsBean#setIndexedProperty(Object, String, Object)}</li> 066 * <li>{@link org.apache.commons.beanutils2.PropertyUtilsBean#setMappedProperty(Object, String, Object)}</li> 067 * <li>{@link org.apache.commons.beanutils2.PropertyUtilsBean#setNestedProperty(Object, String, Object)}</li> 068 * <li>{@link org.apache.commons.beanutils2.PropertyUtilsBean#setSimpleProperty(Object, String, Object)}</li> 069 * </ul> 070 * </li> 071 * <li>{@link org.apache.commons.beanutils2.BeanUtilsBean} 072 * <ul> 073 * <li>{@link org.apache.commons.beanutils2.BeanUtilsBean#copyProperty(Object, String, Object)}</li> 074 * <li>{@link org.apache.commons.beanutils2.BeanUtilsBean#setProperty(Object, String, Object)}</li> 075 * </ul> 076 * </li> 077 * <li>{@link org.apache.commons.beanutils2.locale.LocaleBeanUtilsBean} 078 * <ul> 079 * <li>{@link org.apache.commons.beanutils2.locale.LocaleBeanUtilsBean#setProperty(Object, String, Object, String)}</li> 080 * </ul> 081 * </li> 082 * </ul> 083 * 084 * @see org.apache.commons.beanutils2.PropertyUtilsBean#setResolver(Resolver) 085 * @since 1.8.0 086 */ 087public interface Resolver { 088 089 /** 090 * Extract the index value from the property expression or -1. 091 * 092 * @param expression The property expression 093 * @return The index value or -1 if the property is not indexed 094 * @throws IllegalArgumentException If the indexed property is illegally formed or has an invalid (non-numeric) value 095 */ 096 int getIndex(String expression); 097 098 /** 099 * Extract the map key from the property expression or {@code null}. 100 * 101 * @param expression The property expression 102 * @return The index value 103 * @throws IllegalArgumentException If the mapped property is illegally formed 104 */ 105 String getKey(String expression); 106 107 /** 108 * Gets the property name from the property expression. 109 * 110 * @param expression The property expression 111 * @return The property name 112 */ 113 String getProperty(String expression); 114 115 /** 116 * Indicates whether or not the expression contains nested property expressions or not. 117 * 118 * @param expression The property expression 119 * @return The next property expression 120 */ 121 boolean hasNested(String expression); 122 123 /** 124 * Indicate whether the expression is for an indexed property or not. 125 * 126 * @param expression The property expression 127 * @return {@code true} if the expression is indexed, otherwise {@code false} 128 */ 129 boolean isIndexed(String expression); 130 131 /** 132 * Indicate whether the expression is for a mapped property or not. 133 * 134 * @param expression The property expression 135 * @return {@code true} if the expression is mapped, otherwise {@code false} 136 */ 137 boolean isMapped(String expression); 138 139 /** 140 * Extract the next property expression from the current expression. 141 * 142 * @param expression The property expression 143 * @return The next property expression 144 */ 145 String next(String expression); 146 147 /** 148 * Remove the last property expression from the current expression. 149 * 150 * @param expression The property expression 151 * @return The new expression value, with first property expression removed - null if there are no more expressions 152 */ 153 String remove(String expression); 154 155}