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 * &quot;Hello ${getName()}&quot;
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}