/core/src/main/java/com/atlassian/soy/impl/functions/GetTextFunction.java
Java | 161 lines | 131 code | 24 blank | 6 comment | 12 complexity | 3ded438302054c3e49fabe156a7e4f82 MD5 | raw file
- package com.atlassian.soy.impl.functions;
- import com.atlassian.soy.impl.data.SoyValueUtils;
- import com.atlassian.soy.spi.i18n.I18nResolver;
- import com.atlassian.soy.spi.i18n.JsLocaleResolver;
- import com.google.common.base.Function;
- import com.google.common.collect.ImmutableSet;
- import com.google.common.collect.Iterables;
- import com.google.common.collect.Lists;
- import com.google.inject.Singleton;
- import com.google.template.soy.base.SoySyntaxException;
- import com.google.template.soy.data.SoyData;
- import com.google.template.soy.data.SoyValue;
- import com.google.template.soy.data.restricted.NullData;
- import com.google.template.soy.data.restricted.StringData;
- import com.google.template.soy.internal.base.CharEscaper;
- import com.google.template.soy.internal.base.CharEscapers;
- import com.google.template.soy.jssrc.restricted.JsExpr;
- import com.google.template.soy.jssrc.restricted.SoyJsSrcFunction;
- import com.google.template.soy.shared.restricted.SoyJavaFunction;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import javax.inject.Inject;
- import javax.inject.Named;
- import java.io.Serializable;
- import java.util.List;
- import java.util.Set;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
- import java.util.stream.Collectors;
- /**
- * I18N getText() soy function.
- *
- * @since 1.0
- */
- @Singleton
- public class GetTextFunction implements SoyJsSrcFunction, SoyJavaFunction {
- public static final String FUNCTION_NAME = "getText";
- private static final Logger log = LoggerFactory.getLogger(GetTextFunction.class);
- private static final Pattern STRING_ARG = Pattern.compile("^'(.*)'$");
- private static final Function<SoyValue, Serializable> SOY_DATA_TO_SERIALIZABLE_FUNCTION = new Function<SoyValue, Serializable>() {
- @Override
- public Serializable apply(SoyValue fromSoyData) {
- Object convertedSoyData = SoyValueUtils.fromSoyValue(fromSoyData);
- if (convertedSoyData instanceof Serializable) {
- return (Serializable) convertedSoyData;
- }
- if (convertedSoyData == null) {
- return NullData.INSTANCE.toString();
- }
- if (log.isDebugEnabled()) {
- log.debug("Conversion of {} from {} is not a Serializable, defaulting to toString() invocation.", convertedSoyData.getClass().getName(), fromSoyData.getClass().getName());
- }
- return convertedSoyData.toString();
- }
- };
- private static final Set<Integer> ARGS_SIZES;
- private final JsLocaleResolver jsLocaleResolver;
- private final I18nResolver i18nResolver;
- private boolean useAjsI18n;
- @Inject
- public GetTextFunction(JsLocaleResolver jsLocaleResolver, I18nResolver i18nResolver, @Named(SoyProperties.USE_AJS_I18N) boolean useAjsI18n) {
- this.jsLocaleResolver = jsLocaleResolver;
- this.i18nResolver = i18nResolver;
- this.useAjsI18n = useAjsI18n;
- }
- static {
- final ImmutableSet.Builder<Integer> args = ImmutableSet.builder();
- // we support 1 or more args, lets just pick an upper limit
- for (int i = 1; i < 20; i++) {
- args.add(i);
- }
- ARGS_SIZES = args.build();
- }
- @Override
- public String getName() {
- return FUNCTION_NAME;
- }
- @Override
- public Set<Integer> getValidArgsSizes() {
- return ARGS_SIZES;
- }
- @Override
- public JsExpr computeForJsSrc(List<JsExpr> args) {
- JsExpr keyExpr = args.get(0);
- final Matcher m = STRING_ARG.matcher(keyExpr.getText());
- if (!m.matches()) {
- throw SoySyntaxException.createWithoutMetaInfo("Argument to getText() is not a literal string: " + keyExpr.getText());
- }
- String key = m.group(1);
- List<String> i18nArgs = Lists.newArrayList();
- if (args.size() > 1) {
- i18nArgs = args.subList(1, args.size())
- .stream()
- .map(JsExpr::getText)
- .collect(Collectors.toList());
- }
- String output;
- if (useAjsI18n) {
- output = getAjsI18nJsOutput(key, i18nArgs);
- } else {
- output = getJsOutput(key, i18nArgs);
- }
- return new JsExpr(output, Integer.MAX_VALUE);
- }
- @Override
- public SoyData computeForJava(List<SoyValue> args) {
- SoyValue data = args.get(0);
- if (!(data instanceof StringData)) {
- throw SoySyntaxException.createWithoutMetaInfo("Argument to getText() is not a literal string");
- }
- List<SoyValue> params = args.subList(1, args.size());
- StringData stringData = (StringData) data;
- String text = i18nResolver.getText(stringData.getValue(), transformSoyDataListToSerializableArray(params));
- return StringData.forValue(text);
- }
- private String getJsOutput(String key, List<String> args) {
- CharEscaper jsEscaper = CharEscapers.javascriptEscaper();
- if (args.isEmpty()) {
- return "'" + jsEscaper.escape(i18nResolver.getText(jsLocaleResolver.getLocale(), key)) + "'";
- } else {
- StringBuilder call = new StringBuilder();
- final String msg = i18nResolver.getRawText(jsLocaleResolver.getLocale(), key);
- call.append("AJS.format(");
- call.append("'").append(jsEscaper.escape(msg)).append("'");
- args.forEach((arg) -> call.append(",").append(arg));
- return call.append(")").toString();
- }
- }
- private String getAjsI18nJsOutput(String key, List<String> args) {
- StringBuilder call = new StringBuilder().append(String.format("AJS.I18n.getText('%s'", key));
- args.forEach((arg) -> call.append(",").append(arg));
- return call.append(")").toString();
- }
- private Serializable[] transformSoyDataListToSerializableArray(List<SoyValue> params) {
- return Iterables.toArray(Iterables.transform(params, SOY_DATA_TO_SERIALIZABLE_FUNCTION), Serializable.class);
- }
- }