1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.beanutils2.expression; 18 19 /** 20 * Property Name Expression Resolver. 21 * <p> 22 * Methods such as PropertyUtilsBean's {@code setNestedProperty()} method use a {@code Resolver} to process a <em>property name</em> expression and resolve 23 * <em>nested</em>, <em>indexed</em> and <em>mapped</em> property names. The following code provides an example usage demonstrating all the methods: 24 * 25 * <pre> 26 * // Iterate through a nested property expression 27 * while (resolver.hasNested(name)) { 28 * 29 * // isolate a single property from a nested expression 30 * String next = resolver.next(name); 31 * 32 * // Process... 33 * String property = resolver.getProperty(next); 34 * if (resolver.isIndexed(next)) { 35 * 36 * int index = resolver.getIndex(next); 37 * bean = getIndexedProperty(bean, property, index); 38 * 39 * } else if (resolver.isMapped(next)) { 40 * 41 * String key = resolver.getKey(next); 42 * bean = getMappedProperty(bean, property, key); 43 * 44 * } else { 45 * 46 * bean = getSimpleProperty(bean, property); 47 * 48 * } 49 * 50 * // remove the processed property from the expression 51 * name = resolver.remove(name); 52 * } 53 * </pre> 54 * 55 * In order to create an implementation, it is important to understand how BeanUtils/PropertyUtils uses the {@code resolver}. The following are the main methods 56 * that use it: 57 * <ul> 58 * <li>{@link org.apache.commons.beanutils2.PropertyUtilsBean} 59 * <ul> 60 * <li>{@link org.apache.commons.beanutils2.PropertyUtilsBean#getIndexedProperty(Object, String)}</li> 61 * <li>{@link org.apache.commons.beanutils2.PropertyUtilsBean#getMappedProperty(Object, String)}</li> 62 * <li>{@link org.apache.commons.beanutils2.PropertyUtilsBean#getNestedProperty(Object, String)}</li> 63 * <li>{@link org.apache.commons.beanutils2.PropertyUtilsBean#getPropertyDescriptor(Object, String)}</li> 64 * <li>{@link org.apache.commons.beanutils2.PropertyUtilsBean#getSimpleProperty(Object, String)}</li> 65 * <li>{@link org.apache.commons.beanutils2.PropertyUtilsBean#setIndexedProperty(Object, String, Object)}</li> 66 * <li>{@link org.apache.commons.beanutils2.PropertyUtilsBean#setMappedProperty(Object, String, Object)}</li> 67 * <li>{@link org.apache.commons.beanutils2.PropertyUtilsBean#setNestedProperty(Object, String, Object)}</li> 68 * <li>{@link org.apache.commons.beanutils2.PropertyUtilsBean#setSimpleProperty(Object, String, Object)}</li> 69 * </ul> 70 * </li> 71 * <li>{@link org.apache.commons.beanutils2.BeanUtilsBean} 72 * <ul> 73 * <li>{@link org.apache.commons.beanutils2.BeanUtilsBean#copyProperty(Object, String, Object)}</li> 74 * <li>{@link org.apache.commons.beanutils2.BeanUtilsBean#setProperty(Object, String, Object)}</li> 75 * </ul> 76 * </li> 77 * <li>{@link org.apache.commons.beanutils2.locale.LocaleBeanUtilsBean} 78 * <ul> 79 * <li>{@link org.apache.commons.beanutils2.locale.LocaleBeanUtilsBean#setProperty(Object, String, Object, String)}</li> 80 * </ul> 81 * </li> 82 * </ul> 83 * 84 * @see org.apache.commons.beanutils2.PropertyUtilsBean#setResolver(Resolver) 85 * @since 1.8.0 86 */ 87 public interface Resolver { 88 89 /** 90 * Extract the index value from the property expression or -1. 91 * 92 * @param expression The property expression 93 * @return The index value or -1 if the property is not indexed 94 * @throws IllegalArgumentException If the indexed property is illegally formed or has an invalid (non-numeric) value 95 */ 96 int getIndex(String expression); 97 98 /** 99 * 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 }