001/* 002 * Copyright 2002-2017 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; 024 025/** 026 * Represents a template expression broken into pieces. Each piece will be an Expression 027 * but pure text parts to the template will be represented as LiteralExpression objects. 028 * An example of a template expression might be: 029 * 030 * <pre class="code"> 031 * "Hello ${getName()}" 032 * </pre> 033 * 034 * which will be represented as a CompositeStringExpression of two parts. The first part 035 * being a LiteralExpression representing 'Hello ' and the second part being a real 036 * expression that will call {@code getName()} when invoked. 037 * 038 * @author Andy Clement 039 * @author Juergen Hoeller 040 * @since 3.0 041 */ 042public class CompositeStringExpression implements Expression { 043 044 private final String expressionString; 045 046 /** The array of expressions that make up the composite expression */ 047 private final Expression[] expressions; 048 049 050 public CompositeStringExpression(String expressionString, Expression[] expressions) { 051 this.expressionString = expressionString; 052 this.expressions = expressions; 053 } 054 055 056 @Override 057 public final String getExpressionString() { 058 return this.expressionString; 059 } 060 061 public final Expression[] getExpressions() { 062 return this.expressions; 063 } 064 065 @Override 066 public String getValue() throws EvaluationException { 067 StringBuilder sb = new StringBuilder(); 068 for (Expression expression : this.expressions) { 069 String value = expression.getValue(String.class); 070 if (value != null) { 071 sb.append(value); 072 } 073 } 074 return sb.toString(); 075 } 076 077 @Override 078 public <T> T getValue(Class<T> expectedResultType) throws EvaluationException { 079 Object value = getValue(); 080 return ExpressionUtils.convertTypedValue(null, new TypedValue(value), expectedResultType); 081 } 082 083 @Override 084 public String getValue(Object rootObject) throws EvaluationException { 085 StringBuilder sb = new StringBuilder(); 086 for (Expression expression : this.expressions) { 087 String value = expression.getValue(rootObject, String.class); 088 if (value != null) { 089 sb.append(value); 090 } 091 } 092 return sb.toString(); 093 } 094 095 @Override 096 public <T> T getValue(Object rootObject, Class<T> desiredResultType) throws EvaluationException { 097 Object value = getValue(rootObject); 098 return ExpressionUtils.convertTypedValue(null, new TypedValue(value), desiredResultType); 099 } 100 101 @Override 102 public String getValue(EvaluationContext context) throws EvaluationException { 103 StringBuilder sb = new StringBuilder(); 104 for (Expression expression : this.expressions) { 105 String value = expression.getValue(context, String.class); 106 if (value != null) { 107 sb.append(value); 108 } 109 } 110 return sb.toString(); 111 } 112 113 @Override 114 public <T> T getValue(EvaluationContext context, Class<T> expectedResultType) 115 throws EvaluationException { 116 117 Object value = getValue(context); 118 return ExpressionUtils.convertTypedValue(context, new TypedValue(value), expectedResultType); 119 } 120 121 @Override 122 public String getValue(EvaluationContext context, Object rootObject) throws EvaluationException { 123 StringBuilder sb = new StringBuilder(); 124 for (Expression expression : this.expressions) { 125 String value = expression.getValue(context, rootObject, String.class); 126 if (value != null) { 127 sb.append(value); 128 } 129 } 130 return sb.toString(); 131 } 132 133 @Override 134 public <T> T getValue(EvaluationContext context, Object rootObject, Class<T> desiredResultType) 135 throws EvaluationException { 136 137 Object value = getValue(context,rootObject); 138 return ExpressionUtils.convertTypedValue(context, new TypedValue(value), desiredResultType); 139 } 140 141 @Override 142 public Class<?> getValueType() { 143 return String.class; 144 } 145 146 @Override 147 public Class<?> getValueType(EvaluationContext context) { 148 return String.class; 149 } 150 151 @Override 152 public Class<?> getValueType(Object rootObject) throws EvaluationException { 153 return String.class; 154 } 155 156 @Override 157 public Class<?> getValueType(EvaluationContext context, Object rootObject) throws EvaluationException { 158 return String.class; 159 } 160 161 @Override 162 public TypeDescriptor getValueTypeDescriptor() { 163 return TypeDescriptor.valueOf(String.class); 164 } 165 166 @Override 167 public TypeDescriptor getValueTypeDescriptor(Object rootObject) throws EvaluationException { 168 return TypeDescriptor.valueOf(String.class); 169 } 170 171 @Override 172 public TypeDescriptor getValueTypeDescriptor(EvaluationContext context) { 173 return TypeDescriptor.valueOf(String.class); 174 } 175 176 @Override 177 public TypeDescriptor getValueTypeDescriptor(EvaluationContext context, Object rootObject) 178 throws EvaluationException { 179 180 return TypeDescriptor.valueOf(String.class); 181 } 182 183 @Override 184 public boolean isWritable(Object rootObject) throws EvaluationException { 185 return false; 186 } 187 188 @Override 189 public boolean isWritable(EvaluationContext context) { 190 return false; 191 } 192 193 @Override 194 public boolean isWritable(EvaluationContext context, Object rootObject) throws EvaluationException { 195 return false; 196 } 197 198 @Override 199 public void setValue(Object rootObject, Object value) throws EvaluationException { 200 throw new EvaluationException(this.expressionString, "Cannot call setValue on a composite expression"); 201 } 202 203 @Override 204 public void setValue(EvaluationContext context, 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, Object rootObject, Object value) throws EvaluationException { 210 throw new EvaluationException(this.expressionString, "Cannot call setValue on a composite expression"); 211 } 212 213}