156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson/* 256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Copyright (C) 2010 Google Inc. 356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * 456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Licensed under the Apache License, Version 2.0 (the "License"); 556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * you may not use this file except in compliance with the License. 656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * You may obtain a copy of the License at 756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * 856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * http://www.apache.org/licenses/LICENSE-2.0 956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * 1056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Unless required by applicable law or agreed to in writing, software 1156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * distributed under the License is distributed on an "AS IS" BASIS, 1256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * See the License for the specific language governing permissions and 1456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * limitations under the License. 1556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */ 1656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 1756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonpackage com.google.clearsilver.jsilver.values; 1856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 1956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonimport com.google.clearsilver.jsilver.autoescape.EscapeMode; 2056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonimport com.google.clearsilver.jsilver.data.DataContext; 2156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 2256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonimport java.util.HashMap; 2356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonimport java.util.Map; 2456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 2556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson/** 2656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Dynamic typing system used by JSilver interpreter. A value (e.g. "2") can act as a string, 2756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * integer and boolean. Values can be literal or references to variables held elsewhere (e.g. in 2856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * external data structures such as HDF). 2956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */ 3056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonpublic abstract class Value { 3156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 3256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private static final Map<EscapeMode, Value> EMPTY_PART_ESCAPED; 3356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private static final Map<EscapeMode, Value> EMPTY_UNESCAPED; 3456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private static final Map<EscapeMode, Value> ZERO_PART_ESCAPED; 3556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private static final Map<EscapeMode, Value> ZERO_UNESCAPED; 3656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private static final Map<EscapeMode, Value> ONE_PART_ESCAPED; 3756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private static final Map<EscapeMode, Value> ONE_UNESCAPED; 3856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 3956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson static { 4056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // Currently a Value's EscapeMode is either ESCAPE_NONE (no escaping) or 4156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // ESCAPE_IS_CONSTANT (is a constant or has some escaping applied). 4256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // This may change in the future if we implement stricter auto escaping. 4356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // See EscapeMode.combineModes. 4456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson EMPTY_PART_ESCAPED = new HashMap<EscapeMode, Value>(2); 4556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson EMPTY_PART_ESCAPED.put(EscapeMode.ESCAPE_NONE, 4656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson new StringValue("", EscapeMode.ESCAPE_NONE, true)); 4756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson EMPTY_PART_ESCAPED.put(EscapeMode.ESCAPE_IS_CONSTANT, new StringValue("", 4856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson EscapeMode.ESCAPE_IS_CONSTANT, true)); 4956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 5056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson EMPTY_UNESCAPED = new HashMap<EscapeMode, Value>(2); 5156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson EMPTY_UNESCAPED.put(EscapeMode.ESCAPE_NONE, new StringValue("", EscapeMode.ESCAPE_NONE, false)); 5256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson EMPTY_UNESCAPED.put(EscapeMode.ESCAPE_IS_CONSTANT, new StringValue("", 5356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson EscapeMode.ESCAPE_IS_CONSTANT, false)); 5456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 5556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson ZERO_PART_ESCAPED = new HashMap<EscapeMode, Value>(2); 5656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson ZERO_PART_ESCAPED.put(EscapeMode.ESCAPE_NONE, new NumberValue(0, EscapeMode.ESCAPE_NONE, true)); 5756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson ZERO_PART_ESCAPED.put(EscapeMode.ESCAPE_IS_CONSTANT, new NumberValue(0, 5856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson EscapeMode.ESCAPE_IS_CONSTANT, true)); 5956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 6056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson ZERO_UNESCAPED = new HashMap<EscapeMode, Value>(2); 6156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson ZERO_UNESCAPED.put(EscapeMode.ESCAPE_NONE, new NumberValue(0, EscapeMode.ESCAPE_NONE, false)); 6256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson ZERO_UNESCAPED.put(EscapeMode.ESCAPE_IS_CONSTANT, new NumberValue(0, 6356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson EscapeMode.ESCAPE_IS_CONSTANT, false)); 6456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 6556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson ONE_PART_ESCAPED = new HashMap<EscapeMode, Value>(2); 6656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson ONE_PART_ESCAPED.put(EscapeMode.ESCAPE_NONE, new NumberValue(1, EscapeMode.ESCAPE_NONE, true)); 6756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson ONE_PART_ESCAPED.put(EscapeMode.ESCAPE_IS_CONSTANT, new NumberValue(1, 6856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson EscapeMode.ESCAPE_IS_CONSTANT, true)); 6956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 7056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson ONE_UNESCAPED = new HashMap<EscapeMode, Value>(2); 7156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson ONE_UNESCAPED.put(EscapeMode.ESCAPE_NONE, new NumberValue(1, EscapeMode.ESCAPE_NONE, false)); 7256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson ONE_UNESCAPED.put(EscapeMode.ESCAPE_IS_CONSTANT, new NumberValue(1, 7356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson EscapeMode.ESCAPE_IS_CONSTANT, false)); 7456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 7556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 7656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson /** 7756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * True if either the {@code Value} was escaped, or it was created from a combination of escaped 7856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * and unescaped values. 7956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */ 8056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private final boolean partiallyEscaped; 8156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private final EscapeMode escapeMode; 8256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 8356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public Value(EscapeMode escapeMode, boolean partiallyEscaped) { 8456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson this.escapeMode = escapeMode; 8556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson this.partiallyEscaped = partiallyEscaped; 8656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 8756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 8856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson /** 8956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Fetch value as boolean. All non empty strings and numbers != 0 are treated as true. 9056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */ 9156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public abstract boolean asBoolean(); 9256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 9356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson /** 9456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Fetch value as string. 9556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */ 9656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public abstract String asString(); 9756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 9856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson /** 9956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Fetch value as number. If number is not parseable, 0 is returned (this is consistent with 10056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * ClearSilver). 10156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */ 10256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public abstract int asNumber(); 10356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 10456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson /** 10556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Whether this value exists. Literals always return true, but variable references will return 10656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * false if the value behind it is null. 10756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */ 10856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public abstract boolean exists(); 10956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 11056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public abstract boolean isEmpty(); 11156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 11256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson /** 11356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Create a literal value using an int. 11456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */ 11556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public static Value literalValue(int value, EscapeMode mode, boolean partiallyEscaped) { 11656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return getIntValue(mode, partiallyEscaped, value); 11756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 11856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 11956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson /** 12056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Create a literal value using a String. 12156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */ 12256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public static Value literalValue(String value, EscapeMode mode, boolean partiallyEscaped) { 12356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson if (value.isEmpty()) { 12456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson Value v = (partiallyEscaped ? EMPTY_PART_ESCAPED : EMPTY_UNESCAPED).get(mode); 12556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson if (v != null) { 12656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return v; 12756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 12856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 12956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 13056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return new StringValue(value, mode, partiallyEscaped); 13156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 13256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 13356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson /** 13456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Create a literal value using a boolean. 13556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */ 13656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public static Value literalValue(boolean value, EscapeMode mode, boolean partiallyEscaped) { 13756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return getIntValue(mode, partiallyEscaped, value ? 1 : 0); 13856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 13956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 14056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private static Value getIntValue(EscapeMode mode, boolean partiallyEscaped, int num) { 14156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson Value v = null; 14256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson if (num == 0) { 14356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson v = (partiallyEscaped ? ZERO_PART_ESCAPED : ZERO_UNESCAPED).get(mode); 14456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } else if (num == 1) { 14556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson v = (partiallyEscaped ? ONE_PART_ESCAPED : ONE_UNESCAPED).get(mode); 14656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 14756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 14856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson if (v != null) { 14956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return v; 15056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 15156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 15256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return new NumberValue(num, mode, partiallyEscaped); 15356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 15456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 15556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson /** 15656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Create a literal value using an int with a {@code escapeMode} of {@code 15756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * EscapeMode.ESCAPE_IS_CONSTANT} and {@code partiallyEscaped} based on the {@code 15856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * partiallyEscaped} values of the inputs. 15956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * 16056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * @param value integer value of the literal 16156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * @param inputs Values that were used to compute the integer value. 16256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */ 16356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public static Value literalConstant(int value, Value... inputs) { 16456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson boolean isPartiallyEscaped = false; 16556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson for (Value input : inputs) { 16656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson if (input.isPartiallyEscaped()) { 16756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson isPartiallyEscaped = true; 16856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson break; 16956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 17056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 17156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return literalValue(value, EscapeMode.ESCAPE_IS_CONSTANT, isPartiallyEscaped); 17256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 17356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 17456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson /** 17556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Create a literal value using a string with a {@code escapeMode} of {@code 17656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * EscapeMode.ESCAPE_IS_CONSTANT} and {@code partiallyEscaped} based on the {@code 17756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * partiallyEscaped} values of the inputs. 17856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * 17956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * @param value String value of the literal 18056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * @param inputs Values that were used to compute the string value. 18156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */ 18256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public static Value literalConstant(String value, Value... inputs) { 18356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson boolean isPartiallyEscaped = false; 18456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson for (Value input : inputs) { 18556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson if (input.isPartiallyEscaped()) { 18656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson isPartiallyEscaped = true; 18756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson break; 18856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 18956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 19056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return literalValue(value, EscapeMode.ESCAPE_IS_CONSTANT, isPartiallyEscaped); 19156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 19256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 19356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson /** 19456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Create a literal value using a boolean with a {@code escapeMode} of {@code 19556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * EscapeMode.ESCAPE_IS_CONSTANT} and {@code partiallyEscaped} based on the {@code 19656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * partiallyEscaped} values of the inputs. 19756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * 19856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * @param value boolean value of the literal 19956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * @param inputs Values that were used to compute the boolean value. 20056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */ 20156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public static Value literalConstant(boolean value, Value... inputs) { 20256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson boolean isPartiallyEscaped = false; 20356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson for (Value input : inputs) { 20456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson if (input.isPartiallyEscaped()) { 20556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson isPartiallyEscaped = true; 20656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson break; 20756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 20856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 20956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return literalValue(value, EscapeMode.ESCAPE_IS_CONSTANT, isPartiallyEscaped); 21056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 21156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 21256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson /** 21356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Create a value linked to a variable name. 21456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * 21556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * @param name The pathname of the variable relative to the given {@link DataContext} 21656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * @param dataContext The DataContext defining the scope and Data objects to use when 21756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * dereferencing the name. 21856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * @return A Value object that allows access to the variable name, the variable Data object (if it 21956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * exists) and to the value of the variable. 22056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */ 22156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public static Value variableValue(String name, DataContext dataContext) { 22256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return new VariableValue(name, dataContext); 22356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 22456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 22556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson @Override 22656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public boolean equals(Object other) { 22756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson if (other == null || !(other instanceof Value)) { 22856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return false; 22956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 23056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson Value otherValue = (Value) other; 23156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // This behaves the same way as ClearSilver. 23256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return exists() == otherValue.exists() 23356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson && (asString().equals(otherValue.asString()) || (isEmpty() && otherValue.isEmpty())); 23456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 23556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 23656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson @Override 23756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public int hashCode() { 23856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return toString().hashCode(); 23956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 24056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 24156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson @Override 24256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public String toString() { 24356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return asString(); 24456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 24556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 24656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public boolean isPartiallyEscaped() { 24756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return partiallyEscaped; 24856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 24956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 25056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson /** 25156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Indicates the escaping that was applied to the expression represented by this value. 25256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * 25356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * <p> 25456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * May be checked by the JSilver code before applying autoescaping. It differs from {@code 25556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * isEscaped}, which is true iff any part of the variable expression contains an escaping 25656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * function, even if the entire expression has not been escaped. Both methods are required, 25756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * {@code isEscaped} to determine whether <?cs escape > commands should be applied, and 25856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * {@code getEscapeMode} for autoescaping. This is done to maintain compatibility with 25956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * ClearSilver's behaviour. 26056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * 26156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * @return {@code EscapeMode.ESCAPE_IS_CONSTANT} if the value represents a constant string 26256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * literal. Or the appropriate {@link EscapeMode} if the value is the output of an 26356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * escaping function. 26456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * 26556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * @see EscapeMode 26656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */ 26756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public EscapeMode getEscapeMode() { 26856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return escapeMode; 26956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 27056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 27156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson} 272