001/* 002 * Copyright 2002-2018 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.expression.common; 018 019import org.springframework.core.convert.TypeDescriptor; 020import org.springframework.expression.EvaluationContext; 021import org.springframework.expression.EvaluationException; 022import org.springframework.expression.Expression; 023import org.springframework.expression.TypedValue; 024import org.springframework.lang.Nullable; 025 026/** 027 * Represents a template expression broken into pieces. Each piece will be an Expression 028 * but pure text parts to the template will be represented as LiteralExpression objects. 029 * An example of a template expression might be: 030 * 031 * <pre class="code"> 032 * "Hello ${getName()}" 033 * </pre> 034 * 035 * which will be represented as a CompositeStringExpression of two parts. The first part 036 * being a LiteralExpression representing 'Hello ' and the second part being a real 037 * expression that will call {@code getName()} when invoked. 038 * 039 * @author Andy Clement 040 * @author Juergen Hoeller 041 * @since 3.0 042 */ 043public class CompositeStringExpression implements Expression { 044 045 private final String expressionString; 046 047 /** The array of expressions that make up the composite expression. */ 048 private final Expression[] expressions; 049 050 051 public CompositeStringExpression(String expressionString, Expression[] expressions) { 052 this.expressionString = expressionString; 053 this.expressions = expressions; 054 } 055 056 057 @Override 058 public final String getExpressionString() { 059 return this.expressionString; 060 } 061 062 public final Expression[] getExpressions() { 063 return this.expressions; 064 } 065 066 @Override 067 public String getValue() throws EvaluationException { 068 StringBuilder sb = new StringBuilder(); 069 for (Expression expression : this.expressions) { 070 String value = expression.getValue(String.class); 071 if (value != null) { 072 sb.append(value); 073 } 074 } 075 return sb.toString(); 076 } 077 078 @Override 079 @Nullable 080 public <T> T getValue(@Nullable Class<T> expectedResultType) throws EvaluationException { 081 Object value = getValue(); 082 return ExpressionUtils.convertTypedValue(null, new TypedValue(value), expectedResultType); 083 } 084 085 @Override 086 public String getValue(@Nullable Object rootObject) throws EvaluationException { 087 StringBuilder sb = new StringBuilder(); 088 for (Expression expression : this.expressions) { 089 String value = expression.getValue(rootObject, String.class); 090 if (value != null) { 091 sb.append(value); 092 } 093 } 094 return sb.toString(); 095 } 096 097 @Override 098 @Nullable 099 public <T> T getValue(@Nullable Object rootObject, @Nullable Class<T> desiredResultType) throws EvaluationException { 100 Object value = getValue(rootObject); 101 return ExpressionUtils.convertTypedValue(null, new TypedValue(value), desiredResultType); 102 } 103 104 @Override 105 public String getValue(EvaluationContext context) throws EvaluationException { 106 StringBuilder sb = new StringBuilder(); 107 for (Expression expression : this.expressions) { 108 String value = expression.getValue(context, String.class); 109 if (value != null) { 110 sb.append(value); 111 } 112 } 113 return sb.toString(); 114 } 115 116 @Override 117 @Nullable 118 public <T> T getValue(EvaluationContext context, @Nullable Class<T> expectedResultType) 119 throws EvaluationException { 120 121 Object value = getValue(context); 122 return ExpressionUtils.convertTypedValue(context, new TypedValue(value), expectedResultType); 123 } 124 125 @Override 126 public String getValue(EvaluationContext context, @Nullable Object rootObject) throws EvaluationException { 127 StringBuilder sb = new StringBuilder(); 128 for (Expression expression : this.expressions) { 129 String value = expression.getValue(context, rootObject, String.class); 130 if (value != null) { 131 sb.append(value); 132 } 133 } 134 return sb.toString(); 135 } 136 137 @Override 138 @Nullable 139 public <T> T getValue(EvaluationContext context, @Nullable Object rootObject, @Nullable Class<T> desiredResultType) 140 throws EvaluationException { 141 142 Object value = getValue(context,rootObject); 143 return ExpressionUtils.convertTypedValue(context, new TypedValue(value), desiredResultType); 144 } 145 146 @Override 147 public Class<?> getValueType() { 148 return String.class; 149 } 150 151 @Override 152 public Class<?> getValueType(EvaluationContext context) { 153 return String.class; 154 } 155 156 @Override 157 public Class<?> getValueType(@Nullable Object rootObject) throws EvaluationException { 158 return String.class; 159 } 160 161 @Override 162 public Class<?> getValueType(EvaluationContext context, @Nullable Object rootObject) throws EvaluationException { 163 return String.class; 164 } 165 166 @Override 167 public TypeDescriptor getValueTypeDescriptor() { 168 return TypeDescriptor.valueOf(String.class); 169 } 170 171 @Override 172 public TypeDescriptor getValueTypeDescriptor(@Nullable Object rootObject) throws EvaluationException { 173 return TypeDescriptor.valueOf(String.class); 174 } 175 176 @Override 177 public TypeDescriptor getValueTypeDescriptor(EvaluationContext context) { 178 return TypeDescriptor.valueOf(String.class); 179 } 180 181 @Override 182 public TypeDescriptor getValueTypeDescriptor(EvaluationContext context, @Nullable Object rootObject) 183 throws EvaluationException { 184 185 return TypeDescriptor.valueOf(String.class); 186 } 187 188 @Override 189 public boolean isWritable(@Nullable Object rootObject) throws EvaluationException { 190 return false; 191 } 192 193 @Override 194 public boolean isWritable(EvaluationContext context) { 195 return false; 196 } 197 198 @Override 199 public boolean isWritable(EvaluationContext context, @Nullable Object rootObject) throws EvaluationException { 200 return false; 201 } 202 203 @Override 204 public void setValue(@Nullable Object rootObject, @Nullable Object value) throws EvaluationException { 205 throw new EvaluationException(this.expressionString, "Cannot call setValue on a composite expression"); 206 } 207 208 @Override 209 public void setValue(EvaluationContext context, @Nullable Object value) throws EvaluationException { 210 throw new EvaluationException(this.expressionString, "Cannot call setValue on a composite expression"); 211 } 212 213 @Override 214 public void setValue(EvaluationContext context, @Nullable Object rootObject, @Nullable Object value) throws EvaluationException { 215 throw new EvaluationException(this.expressionString, "Cannot call setValue on a composite expression"); 216 } 217 218}