Added tagSyntax and interpolationSyntax dropdowns. Did cleanup/refactoring of old code along the way.
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/commit/007c4e13 Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/tree/007c4e13 Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/diff/007c4e13 Branch: refs/heads/master Commit: 007c4e1310c0a1eaca54061cabde6fc7e54837b2 Parents: 5313533 Author: ddekany <[email protected]> Authored: Thu Mar 22 22:36:11 2018 +0100 Committer: ddekany <[email protected]> Committed: Fri Mar 23 13:55:32 2018 +0100 ---------------------------------------------------------------------- build.gradle | 3 + dependencies.gradle | 2 +- .../onlinetester/model/ErrorCode.java | 1 - .../onlinetester/model/ExecuteRequest.java | 56 ++++++++ .../model/ExecuteResourceField.java | 57 -------- .../model/ExecuteResourceProblem.java | 53 ------- .../onlinetester/model/ExecuteResponse.java | 8 +- .../model/ExecuteResponseProblem.java | 53 +++++++ .../resources/ExecuteApiResource.java | 138 ++++++++----------- .../onlinetester/resources/WebPageResource.java | 4 +- .../services/AllowedSettingValues.java | 123 +++++++++++++++++ .../services/AllowedSettingValuesMaps.java | 115 ---------------- .../services/FreeMarkerService.java | 125 +++++++++++------ .../services/FreeMarkerServiceException.java | 1 - .../onlinetester/view/FreeMarkerOnlineView.java | 110 +++++++++++---- src/main/resources/assets/js/script.js | 8 +- src/main/resources/freemarker-online.yml | 2 +- src/main/resources/view/freemarker-online.ftl | 12 +- .../onlinetester/ApplicationStartsTest.java | 2 +- .../resources/ExecuteApiResourceTest.java | 44 +++--- .../resources/WebPageResourceTest.java | 23 +--- .../services/FreeMarkerServiceTest.java | 100 ++++++++++---- .../view/FreeMarkerOnlineViewTest.java | 8 +- 23 files changed, 592 insertions(+), 456 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/007c4e13/build.gradle ---------------------------------------------------------------------- diff --git a/build.gradle b/build.gradle index f307eb1..8d9c7d5 100644 --- a/build.gradle +++ b/build.gradle @@ -36,6 +36,9 @@ project.targetCompatibility = "1.8" repositories { mavenCentral() + maven { + url "https://repository.apache.org/content/repositories/snapshots/" + } } buildscript { http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/007c4e13/dependencies.gradle ---------------------------------------------------------------------- diff --git a/dependencies.gradle b/dependencies.gradle index c7fa0d2..33bcf98 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -30,7 +30,7 @@ ext.libraries = [ dropwizard_bundles_redirect: "io.dropwizard-bundles:dropwizard-redirect-bundle:1.0.5", // App. specific: - freemarker: "org.freemarker:freemarker:2.3.27-incubating", + freemarker: "org.freemarker:freemarker:2.3.28-incubating-SNAPSHOT", jersey_core: "org.glassfish.jersey.core:jersey-core:$jeresy_version", jackson_databind: "com.fasterxml.jackson.core:jackson-databind:$jackson_version", http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/007c4e13/src/main/java/org/apache/freemarker/onlinetester/model/ErrorCode.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/onlinetester/model/ErrorCode.java b/src/main/java/org/apache/freemarker/onlinetester/model/ErrorCode.java index c983e87..b766edf 100644 --- a/src/main/java/org/apache/freemarker/onlinetester/model/ErrorCode.java +++ b/src/main/java/org/apache/freemarker/onlinetester/model/ErrorCode.java @@ -21,5 +21,4 @@ package org.apache.freemarker.onlinetester.model; public enum ErrorCode { FREEMARKER_SERVICE_TIMEOUT - } http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/007c4e13/src/main/java/org/apache/freemarker/onlinetester/model/ExecuteRequest.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/onlinetester/model/ExecuteRequest.java b/src/main/java/org/apache/freemarker/onlinetester/model/ExecuteRequest.java index a206131..2552fa4 100644 --- a/src/main/java/org/apache/freemarker/onlinetester/model/ExecuteRequest.java +++ b/src/main/java/org/apache/freemarker/onlinetester/model/ExecuteRequest.java @@ -18,6 +18,8 @@ */ package org.apache.freemarker.onlinetester.model; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; public class ExecuteRequest { private String template; @@ -25,7 +27,45 @@ public class ExecuteRequest { private String outputFormat; private String locale; private String timeZone; + private String tagSyntax; + private String interpolationSyntax; + public static enum Field { + DATA_MODEL("dataModel"), + TEMPLATE("template"), + OUTPUT_FORMAT("outputFormat"), + LOCALE("locale"), + TIME_ZONE("timeZone"), + TAG_SYNTAX("tagSyntax"), + INTERPOLATION_SYNTAX("interpolationSyntax"); + + private final String fieldName; + + private Field(String filedName) { + this.fieldName = filedName; + } + + public String toString() { + return getFieldName(); + } + + @JsonValue + public String getFieldName() { + return fieldName; + } + + @JsonCreator + public static Field fromEnumString(String val) { + for(Field field : values()) { + if(field.getFieldName().equals(val)) { + return field; + } + } + throw new IllegalArgumentException("Invalid string value passed: " + val); + } + + } + public ExecuteRequest() { } @@ -74,5 +114,21 @@ public class ExecuteRequest { public void setTimeZone(String timeZone) { this.timeZone = timeZone; } + + public String getTagSyntax() { + return tagSyntax; + } + + public void setTagSyntax(String tagSyntax) { + this.tagSyntax = tagSyntax; + } + + public String getInterpolationSyntax() { + return interpolationSyntax; + } + + public void setInterpolationSyntax(String interpolationSyntax) { + this.interpolationSyntax = interpolationSyntax; + } } http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/007c4e13/src/main/java/org/apache/freemarker/onlinetester/model/ExecuteResourceField.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/onlinetester/model/ExecuteResourceField.java b/src/main/java/org/apache/freemarker/onlinetester/model/ExecuteResourceField.java deleted file mode 100644 index 71ad454..0000000 --- a/src/main/java/org/apache/freemarker/onlinetester/model/ExecuteResourceField.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.apache.freemarker.onlinetester.model; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonValue; - -public enum ExecuteResourceField { - DATA_MODEL("dataModel"), - TEMPLATE("template"), - OUTPUT_FORMAT("outputFormat"), - LOCALE("locale"), - TIME_ZONE("timeZone"); - - private final String fieldName; - - private ExecuteResourceField(String filedName) { - this.fieldName = filedName; - } - - public String toString() { - return getFieldName(); - } - - @JsonValue - public String getFieldName() { - return fieldName; - } - - @JsonCreator - public static ExecuteResourceField fromEnumString(String val) { - for(ExecuteResourceField field : values()) { - if(field.getFieldName().equals(val)) { - return field; - } - } - throw new IllegalArgumentException("Invalid string value passed: " + val); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/007c4e13/src/main/java/org/apache/freemarker/onlinetester/model/ExecuteResourceProblem.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/onlinetester/model/ExecuteResourceProblem.java b/src/main/java/org/apache/freemarker/onlinetester/model/ExecuteResourceProblem.java deleted file mode 100644 index 3c69d43..0000000 --- a/src/main/java/org/apache/freemarker/onlinetester/model/ExecuteResourceProblem.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.apache.freemarker.onlinetester.model; - -public class ExecuteResourceProblem { - - private ExecuteResourceField field; - private String message; - - // Needed for JSON unmarshalling - public ExecuteResourceProblem() { - // - } - - public ExecuteResourceProblem(ExecuteResourceField field, String message) { - this.field = field; - this.message = message; - } - - public ExecuteResourceField getField() { - return field; - } - - public void setField(ExecuteResourceField field) { - this.field = field; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/007c4e13/src/main/java/org/apache/freemarker/onlinetester/model/ExecuteResponse.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/onlinetester/model/ExecuteResponse.java b/src/main/java/org/apache/freemarker/onlinetester/model/ExecuteResponse.java index 41c33f1..5876d74 100644 --- a/src/main/java/org/apache/freemarker/onlinetester/model/ExecuteResponse.java +++ b/src/main/java/org/apache/freemarker/onlinetester/model/ExecuteResponse.java @@ -23,10 +23,10 @@ import java.util.List; public class ExecuteResponse { private String result; - private List<ExecuteResourceProblem> problems; + private List<ExecuteResponseProblem> problems; private boolean truncatedResult; - public ExecuteResponse(String result, List<ExecuteResourceProblem> problems, boolean truncatedResult) { + public ExecuteResponse(String result, List<ExecuteResponseProblem> problems, boolean truncatedResult) { this.result = result; this.problems = problems; this.truncatedResult = truncatedResult; @@ -36,11 +36,11 @@ public class ExecuteResponse { } - public List<ExecuteResourceProblem> getProblems() { + public List<ExecuteResponseProblem> getProblems() { return problems; } - public void setProblems(List<ExecuteResourceProblem> problems) { + public void setProblems(List<ExecuteResponseProblem> problems) { this.problems = problems; } http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/007c4e13/src/main/java/org/apache/freemarker/onlinetester/model/ExecuteResponseProblem.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/onlinetester/model/ExecuteResponseProblem.java b/src/main/java/org/apache/freemarker/onlinetester/model/ExecuteResponseProblem.java new file mode 100644 index 0000000..d7e02f6 --- /dev/null +++ b/src/main/java/org/apache/freemarker/onlinetester/model/ExecuteResponseProblem.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.freemarker.onlinetester.model; + +public class ExecuteResponseProblem { + + private ExecuteRequest.Field field; + private String message; + + // Needed for JSON unmarshalling + public ExecuteResponseProblem() { + // + } + + public ExecuteResponseProblem(ExecuteRequest.Field field, String message) { + this.field = field; + this.message = message; + } + + public ExecuteRequest.Field getField() { + return field; + } + + public void setField(ExecuteRequest.Field field) { + this.field = field; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/007c4e13/src/main/java/org/apache/freemarker/onlinetester/resources/ExecuteApiResource.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/onlinetester/resources/ExecuteApiResource.java b/src/main/java/org/apache/freemarker/onlinetester/resources/ExecuteApiResource.java index 3303e13..3607691 100644 --- a/src/main/java/org/apache/freemarker/onlinetester/resources/ExecuteApiResource.java +++ b/src/main/java/org/apache/freemarker/onlinetester/resources/ExecuteApiResource.java @@ -24,7 +24,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.TimeZone; import java.util.concurrent.RejectedExecutionException; import javax.ws.rs.Consumes; @@ -38,18 +37,22 @@ import org.apache.commons.lang3.StringUtils; import org.apache.freemarker.onlinetester.model.ErrorCode; import org.apache.freemarker.onlinetester.model.ErrorResponse; import org.apache.freemarker.onlinetester.model.ExecuteRequest; -import org.apache.freemarker.onlinetester.model.ExecuteResourceField; -import org.apache.freemarker.onlinetester.model.ExecuteResourceProblem; import org.apache.freemarker.onlinetester.model.ExecuteResponse; -import org.apache.freemarker.onlinetester.services.AllowedSettingValuesMaps; +import org.apache.freemarker.onlinetester.model.ExecuteResponseProblem; +import org.apache.freemarker.onlinetester.services.AllowedSettingValues; import org.apache.freemarker.onlinetester.services.FreeMarkerService; +import org.apache.freemarker.onlinetester.services.FreeMarkerService.ExecuteTemplateArgs; import org.apache.freemarker.onlinetester.services.FreeMarkerServiceResponse; import org.apache.freemarker.onlinetester.util.DataModelParser; import org.apache.freemarker.onlinetester.util.DataModelParsingException; import org.apache.freemarker.onlinetester.util.ExceptionUtils; -import freemarker.core.OutputFormat; +import freemarker.template.Configuration; +import freemarker.template.utility.StringUtil; +/** + * AJAX API for executing the template submitted. + */ @Path("/api/execute") public class ExecuteApiResource { private static final int MAX_TEMPLATE_INPUT_LENGTH = 10000; @@ -62,17 +65,16 @@ public class ExecuteApiResource { private static final String MAX_DATA_MODEL_INPUT_LENGTH_EXCEEDED_ERROR_MESSAGE = "The data model length has exceeded the {0} character limit set for this service."; - private static final String UNKNOWN_OUTPUT_FORMAT_ERROR_MESSAGE = "Unknown output format: {0}"; - private static final String UNKNOWN_LOCALE_ERROR_MESSAGE = "Unknown locale: {0}"; - private static final String UNKNOWN_TIME_ZONE_ERROR_MESSAGE = "Unknown time zone: {0}"; - - private static final String SERVICE_OVERBURDEN_ERROR_MESSAGE + private static final String SERVICE_TIMEOUT_ERROR_MESSAGE = "Sorry, the service is overburden and couldn't handle your request now. Try again later."; static final String DATA_MODEL_ERROR_MESSAGE_HEADING = "Failed to parse data model:"; static final String DATA_MODEL_ERROR_MESSAGE_FOOTER = "Note: This is NOT a FreeMarker error message. " + "The data model syntax is specific to this online service."; + public static final int DEFAULT_TAG_SYNTAX = Configuration.ANGLE_BRACKET_TAG_SYNTAX; + public static final int DEFAULT_INTERPLOATION_SYNTAX = Configuration.LEGACY_INTERPOLATION_SYNTAX; + private final FreeMarkerService freeMarkerService; public ExecuteApiResource(FreeMarkerService freeMarkerService) { @@ -80,8 +82,8 @@ public class ExecuteApiResource { } @POST - @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) public Response formResult( ExecuteRequest req) { ExecuteResponse resp = new ExecuteResponse(); @@ -90,118 +92,98 @@ public class ExecuteApiResource { return Response.status(400).entity("Empty Template & data").build(); } - List<ExecuteResourceProblem> problems = new ArrayList<ExecuteResourceProblem>(); + List<ExecuteResponseProblem> problems = new ArrayList<>(); - String template = getTemplate(req, problems); - Map<String, Object> dataModel = getDataModel(req, problems); - OutputFormat outputFormat = getOutputFormat(req, problems); - Locale locale = getLocale(req, problems); - TimeZone timeZone = getTimeZone(req, problems); + ExecuteTemplateArgs serviceArgs = new ExecuteTemplateArgs() + .templateSourceCode(lengthCheckAndGetTemplate(req, problems)) + .dataModel(parseDataModel(req, problems)) + .outputFormat(parseChoiceField( + ExecuteRequest.Field.OUTPUT_FORMAT, req.getOutputFormat(), + AllowedSettingValues.DEFAULT_OUTPUT_FORMAT, AllowedSettingValues.OUTPUT_FORMAT_MAP, + problems)) + .locale(parseChoiceField( + ExecuteRequest.Field.LOCALE, req.getLocale(), + AllowedSettingValues.DEFAULT_LOCALE, AllowedSettingValues.LOCALE_MAP, + problems)) + .timeZone(parseChoiceField( + ExecuteRequest.Field.TIME_ZONE, req.getTimeZone(), + AllowedSettingValues.DEFAULT_TIME_ZONE, AllowedSettingValues.TIME_ZONE_MAP, + problems)) + .tagSyntax(parseChoiceField( + ExecuteRequest.Field.TAG_SYNTAX, req.getTagSyntax(), + AllowedSettingValues.DEFAULT_TAG_SYNTAX, AllowedSettingValues.TAG_SYNTAX_MAP, + problems)) + .interpolationSyntax(parseChoiceField( + ExecuteRequest.Field.INTERPOLATION_SYNTAX, req.getInterpolationSyntax(), + AllowedSettingValues.DEFAULT_INTERPOLATION_SYNTAX, AllowedSettingValues.INTERPOLATION_SYNTAX_MAP, + problems)); if (!problems.isEmpty()) { resp.setProblems(problems); return buildFreeMarkerResponse(resp); } - FreeMarkerServiceResponse freeMarkerServiceResponse; + FreeMarkerServiceResponse serviceResponse; try { - freeMarkerServiceResponse = freeMarkerService.calculateTemplateOutput( - template, dataModel, - outputFormat, locale, timeZone); + serviceResponse = freeMarkerService.executeTemplate(serviceArgs); } catch (RejectedExecutionException e) { - String error = SERVICE_OVERBURDEN_ERROR_MESSAGE; + String error = SERVICE_TIMEOUT_ERROR_MESSAGE; return Response.serverError().entity(new ErrorResponse(ErrorCode.FREEMARKER_SERVICE_TIMEOUT, error)).build(); } - if (!freeMarkerServiceResponse.isSuccesful()){ - Throwable failureReason = freeMarkerServiceResponse.getFailureReason(); + if (!serviceResponse.isSuccesful()){ + Throwable failureReason = serviceResponse.getFailureReason(); String error = ExceptionUtils.getMessageWithCauses(failureReason); - problems.add(new ExecuteResourceProblem(ExecuteResourceField.TEMPLATE, error)); + problems.add(new ExecuteResponseProblem(ExecuteRequest.Field.TEMPLATE, error)); resp.setProblems(problems); return buildFreeMarkerResponse(resp); } - String result = freeMarkerServiceResponse.getTemplateOutput(); + String result = serviceResponse.getTemplateOutput(); resp.setResult(result); - resp.setTruncatedResult(freeMarkerServiceResponse.isTemplateOutputTruncated()); + resp.setTruncatedResult(serviceResponse.isTemplateOutputTruncated()); return buildFreeMarkerResponse(resp); } - private String getTemplate(ExecuteRequest req, List<ExecuteResourceProblem> problems) { + private String lengthCheckAndGetTemplate(ExecuteRequest req, List<ExecuteResponseProblem> problems) { String template = req.getTemplate(); - - if (template.length() > MAX_TEMPLATE_INPUT_LENGTH) { + if (template != null && template.length() > MAX_TEMPLATE_INPUT_LENGTH) { String error = formatMessage(MAX_TEMPLATE_INPUT_LENGTH_EXCEEDED_ERROR_MESSAGE, MAX_TEMPLATE_INPUT_LENGTH); - problems.add(new ExecuteResourceProblem(ExecuteResourceField.TEMPLATE, error)); + problems.add(new ExecuteResponseProblem(ExecuteRequest.Field.TEMPLATE, error)); return null; } - return template; } - private Map<String, Object> getDataModel(ExecuteRequest req, List<ExecuteResourceProblem> problems) { + private Map<String, Object> parseDataModel(ExecuteRequest req, List<ExecuteResponseProblem> problems) { String dataModel = req.getDataModel(); if (dataModel.length() > MAX_DATA_MODEL_INPUT_LENGTH) { String error = formatMessage( MAX_DATA_MODEL_INPUT_LENGTH_EXCEEDED_ERROR_MESSAGE, MAX_DATA_MODEL_INPUT_LENGTH); - problems.add(new ExecuteResourceProblem(ExecuteResourceField.DATA_MODEL, error)); + problems.add(new ExecuteResponseProblem(ExecuteRequest.Field.DATA_MODEL, error)); return null; } try { return DataModelParser.parse(dataModel, freeMarkerService.getFreeMarkerTimeZone()); } catch (DataModelParsingException e) { - problems.add(new ExecuteResourceProblem(ExecuteResourceField.DATA_MODEL, decorateResultText(e.getMessage()))); + problems.add(new ExecuteResponseProblem(ExecuteRequest.Field.DATA_MODEL, decorateResultText(e.getMessage()))); return null; } } - private OutputFormat getOutputFormat(ExecuteRequest req, List<ExecuteResourceProblem> problems) { - String outputFormatStr = req.getOutputFormat(); - - if (StringUtils.isBlank(outputFormatStr)) { - return AllowedSettingValuesMaps.DEFAULT_OUTPUT_FORMAT; - } - - OutputFormat outputFormat = AllowedSettingValuesMaps.OUTPUT_FORMAT_MAP.get(outputFormatStr); - if (outputFormat == null) { - problems.add(new ExecuteResourceProblem( - ExecuteResourceField.OUTPUT_FORMAT, - formatMessage(UNKNOWN_OUTPUT_FORMAT_ERROR_MESSAGE, outputFormatStr))); - } - return outputFormat; - } - - private Locale getLocale(ExecuteRequest req, List<ExecuteResourceProblem> problems) { - String localeStr = req.getLocale(); - - if (StringUtils.isBlank(localeStr)) { - return AllowedSettingValuesMaps.DEFAULT_LOCALE; - } - - Locale locale = AllowedSettingValuesMaps.LOCALE_MAP.get(localeStr); - if (locale == null) { - problems.add(new ExecuteResourceProblem( - ExecuteResourceField.LOCALE, - formatMessage(UNKNOWN_LOCALE_ERROR_MESSAGE, localeStr))); - } - return locale; - } - - private TimeZone getTimeZone(ExecuteRequest req, List<ExecuteResourceProblem> problems) { - String timeZoneStr = req.getTimeZone(); - - if (StringUtils.isBlank(timeZoneStr)) { - return AllowedSettingValuesMaps.DEFAULT_TIME_ZONE; + private <T> T parseChoiceField(ExecuteRequest.Field name, String rawValue, T defaultValue, + Map<String, ? extends T> rawToParsedMap, List<ExecuteResponseProblem> problems) { + if (StringUtils.isBlank(rawValue)) { + return defaultValue; } - TimeZone timeZone = AllowedSettingValuesMaps.TIME_ZONE_MAP.get(timeZoneStr); - if (timeZone == null) { - problems.add(new ExecuteResourceProblem( - ExecuteResourceField.TIME_ZONE, - formatMessage(UNKNOWN_TIME_ZONE_ERROR_MESSAGE, timeZoneStr))); + T parsedValue = rawToParsedMap.get(rawValue); + if (parsedValue == null) { + problems.add(new ExecuteResponseProblem(name, + formatMessage("Invalid value for \"{0}\": {1}", name, StringUtil.jQuote(rawValue)))); } - return timeZone; + return parsedValue; } private Response buildFreeMarkerResponse(ExecuteResponse executeResponse){ http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/007c4e13/src/main/java/org/apache/freemarker/onlinetester/resources/WebPageResource.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/onlinetester/resources/WebPageResource.java b/src/main/java/org/apache/freemarker/onlinetester/resources/WebPageResource.java index 1f7a802..89c6da1 100644 --- a/src/main/java/org/apache/freemarker/onlinetester/resources/WebPageResource.java +++ b/src/main/java/org/apache/freemarker/onlinetester/resources/WebPageResource.java @@ -49,7 +49,9 @@ public class WebPageResource { @FormParam("dataModel") String dataModel, @FormParam("outputFormat") String outputFormat, @FormParam("locale") String locale, - @FormParam("timeZone") String timeZone) { + @FormParam("timeZone") String timeZone, + @FormParam("tagSyntax") String tagSyntax, + @FormParam("interpolationSyntax") String interpolationSyntax) { FreeMarkerOnlineView view = new FreeMarkerOnlineView(); view.setTemplate(template); view.setDataModel(dataModel); http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/007c4e13/src/main/java/org/apache/freemarker/onlinetester/services/AllowedSettingValues.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/onlinetester/services/AllowedSettingValues.java b/src/main/java/org/apache/freemarker/onlinetester/services/AllowedSettingValues.java new file mode 100644 index 0000000..6911144 --- /dev/null +++ b/src/main/java/org/apache/freemarker/onlinetester/services/AllowedSettingValues.java @@ -0,0 +1,123 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.freemarker.onlinetester.services; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.TimeZone; + +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; + +import com.google.common.collect.ImmutableMap; + +import freemarker.core.HTMLOutputFormat; +import freemarker.core.OutputFormat; +import freemarker.core.PlainTextOutputFormat; +import freemarker.core.RTFOutputFormat; +import freemarker.core.UndefinedOutputFormat; +import freemarker.core.XHTMLOutputFormat; +import freemarker.core.XMLOutputFormat; +import freemarker.template.Configuration; + +/** + * Maps of the FreeMarker configuration setting values the remote caller can + * chose from (these are the value shown in a dropdown on the UI). This is + * possibly more restricted than what FreeMarker supports, for security reasons. + */ +public class AllowedSettingValues { + + public static final OutputFormat DEFAULT_OUTPUT_FORMAT = UndefinedOutputFormat.INSTANCE; + public static final String DEFAULT_OUTPUT_FORMAT_KEY = DEFAULT_OUTPUT_FORMAT.getName(); + public static final Map<String, OutputFormat> OUTPUT_FORMAT_MAP = ImmutableMap.<String, OutputFormat>builder() + .put(UndefinedOutputFormat.INSTANCE.getName(), UndefinedOutputFormat.INSTANCE) + .put(HTMLOutputFormat.INSTANCE.getName(), HTMLOutputFormat.INSTANCE) + .put(XMLOutputFormat.INSTANCE.getName(), XMLOutputFormat.INSTANCE) + .put(XHTMLOutputFormat.INSTANCE.getName(), XHTMLOutputFormat.INSTANCE) + .put(RTFOutputFormat.INSTANCE.getName(), RTFOutputFormat.INSTANCE) + .put(PlainTextOutputFormat.INSTANCE.getName(), PlainTextOutputFormat.INSTANCE) + .build(); + + public static final Locale DEFAULT_LOCALE = Locale.US; + public static final String DEFAULT_LOCALE_KEY = DEFAULT_LOCALE.toString(); + public static final Map<String, Locale> LOCALE_MAP; + static { + List<Locale> availableLocales = new ArrayList<Locale>(Arrays.asList(Locale.getAvailableLocales())); + + for (Iterator<Locale> iterator = availableLocales.iterator(); iterator.hasNext();) { + Locale locale = iterator.next(); + // Don't bloat the list with "variants" + if (!StringUtils.isBlank(locale.getVariant())) { + iterator.remove(); + } + } + + if (!availableLocales.contains(DEFAULT_LOCALE)) { + availableLocales.add(DEFAULT_LOCALE); + } + + Map<String, Locale> map = new HashMap<String, Locale>(); + for (Locale locale : availableLocales) { + map.put(locale.toString(), locale); + } + + LOCALE_MAP = Collections.unmodifiableMap(map); + } + + public static final TimeZone DEFAULT_TIME_ZONE = TimeZone.getTimeZone("America/Los_Angeles"); + public static final String DEFAULT_TIME_ZONE_KEY; + public static final Map<String, TimeZone> TIME_ZONE_MAP; + static { + String[] availableIDs = TimeZone.getAvailableIDs(); + + DEFAULT_TIME_ZONE_KEY = AllowedSettingValues.DEFAULT_TIME_ZONE.getID(); + if (!ArrayUtils.contains(availableIDs, DEFAULT_TIME_ZONE_KEY)) { + ArrayUtils.add(availableIDs, DEFAULT_TIME_ZONE_KEY); + } + + Map<String, TimeZone> map = new HashMap<String, TimeZone>(); + for (String timeZoneId : availableIDs) { + map.put(timeZoneId, TimeZone.getTimeZone(timeZoneId)); + } + + TIME_ZONE_MAP = Collections.unmodifiableMap(map); + } + + public static final String DEFAULT_TAG_SYNTAX_KEY = "angleBracket"; + public static final Map<String, Integer> TAG_SYNTAX_MAP = ImmutableMap.of( + "angleBracket", Configuration.ANGLE_BRACKET_TAG_SYNTAX, + "squareBracket", Configuration.SQUARE_BRACKET_TAG_SYNTAX, + "autoDetect", Configuration.AUTO_DETECT_TAG_SYNTAX); + public static final int DEFAULT_TAG_SYNTAX = TAG_SYNTAX_MAP.get(DEFAULT_TAG_SYNTAX_KEY); + + public static final String DEFAULT_INTERPOLATION_SYNTAX_KEY = "legacy"; + public static final Map<String, Integer> INTERPOLATION_SYNTAX_MAP = ImmutableMap.of( + "legacy", Configuration.LEGACY_INTERPOLATION_SYNTAX, + "dollar", Configuration.DOLLAR_INTERPOLATION_SYNTAX, + "squareBracket", Configuration.SQUARE_BRACKET_INTERPOLATION_SYNTAX); + public static final int DEFAULT_INTERPOLATION_SYNTAX = Configuration.LEGACY_INTERPOLATION_SYNTAX; + +} http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/007c4e13/src/main/java/org/apache/freemarker/onlinetester/services/AllowedSettingValuesMaps.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/onlinetester/services/AllowedSettingValuesMaps.java b/src/main/java/org/apache/freemarker/onlinetester/services/AllowedSettingValuesMaps.java deleted file mode 100644 index e3111aa..0000000 --- a/src/main/java/org/apache/freemarker/onlinetester/services/AllowedSettingValuesMaps.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.apache.freemarker.onlinetester.services; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.TimeZone; - -import org.apache.commons.lang3.ArrayUtils; -import org.apache.commons.lang3.StringUtils; - -import freemarker.core.HTMLOutputFormat; -import freemarker.core.OutputFormat; -import freemarker.core.PlainTextOutputFormat; -import freemarker.core.RTFOutputFormat; -import freemarker.core.UndefinedOutputFormat; -import freemarker.core.XHTMLOutputFormat; -import freemarker.core.XMLOutputFormat; - -/** - * Maps of the setting values the caller can chose from (these are the value shown in a dropdown on the UI). - */ -public class AllowedSettingValuesMaps { - - public static final OutputFormat DEFAULT_OUTPUT_FORMAT = UndefinedOutputFormat.INSTANCE; - public static final String DEFAULT_OUTPUT_FORMAT_KEY = DEFAULT_OUTPUT_FORMAT.getName(); - public static final Map<String, OutputFormat> OUTPUT_FORMAT_MAP; - static { - Map<String, OutputFormat> map = new HashMap<String, OutputFormat>(); - - addOutputFormatToMap(map, UndefinedOutputFormat.INSTANCE); - addOutputFormatToMap(map, HTMLOutputFormat.INSTANCE); - addOutputFormatToMap(map, XMLOutputFormat.INSTANCE); - addOutputFormatToMap(map, XHTMLOutputFormat.INSTANCE); - addOutputFormatToMap(map, RTFOutputFormat.INSTANCE); - addOutputFormatToMap(map, PlainTextOutputFormat.INSTANCE); - - OUTPUT_FORMAT_MAP = Collections.unmodifiableMap(map); - } - - private static void addOutputFormatToMap(Map<String, OutputFormat> map, OutputFormat outputFormat) { - map.put(outputFormat.getName(), outputFormat); - } - - public static final Locale DEFAULT_LOCALE = Locale.US; - public static final String DEFAULT_LOCALE_KEY = DEFAULT_LOCALE.toString(); - public static final Map<String, Locale> LOCALE_MAP; - static { - List<Locale> availableLocales = new ArrayList<Locale>(Arrays.asList(Locale.getAvailableLocales())); - - for (Iterator<Locale> iterator = availableLocales.iterator(); iterator.hasNext();) { - Locale locale = iterator.next(); - // Don't bloat the list with "variants" - if (!StringUtils.isBlank(locale.getVariant())) { - iterator.remove(); - } - } - - if (!availableLocales.contains(DEFAULT_LOCALE)) { - availableLocales.add(DEFAULT_LOCALE); - } - - Map<String, Locale> map = new HashMap<String, Locale>(); - for (Locale locale : availableLocales) { - map.put(locale.toString(), locale); - } - - LOCALE_MAP = Collections.unmodifiableMap(map); - } - - public static final TimeZone DEFAULT_TIME_ZONE = TimeZone.getTimeZone("America/Los_Angeles"); - - public static final String DEFAULT_TIME_ZONE_KEY; - - public static final Map<String, TimeZone> TIME_ZONE_MAP; - static { - String[] availableIDs = TimeZone.getAvailableIDs(); - - DEFAULT_TIME_ZONE_KEY = AllowedSettingValuesMaps.DEFAULT_TIME_ZONE.getID(); - if (!ArrayUtils.contains(availableIDs, DEFAULT_TIME_ZONE_KEY)) { - ArrayUtils.add(availableIDs, DEFAULT_TIME_ZONE_KEY); - } - - Map<String, TimeZone> map = new HashMap<String, TimeZone>(); - for (String timeZoneId : availableIDs) { - map.put(timeZoneId, TimeZone.getTimeZone(timeZoneId)); - } - - TIME_ZONE_MAP = Collections.unmodifiableMap(map); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/007c4e13/src/main/java/org/apache/freemarker/onlinetester/services/FreeMarkerService.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/onlinetester/services/FreeMarkerService.java b/src/main/java/org/apache/freemarker/onlinetester/services/FreeMarkerService.java index fee66b7..20f9e78 100644 --- a/src/main/java/org/apache/freemarker/onlinetester/services/FreeMarkerService.java +++ b/src/main/java/org/apache/freemarker/onlinetester/services/FreeMarkerService.java @@ -52,6 +52,7 @@ import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; import freemarker.template.TemplateExceptionHandler; +import freemarker.template.utility.StringUtil; public class FreeMarkerService { @@ -108,23 +109,13 @@ public class FreeMarkerService { // Suppress it } }); - freeMarkerConfig.setLocale(AllowedSettingValuesMaps.DEFAULT_LOCALE); - freeMarkerConfig.setTimeZone(AllowedSettingValuesMaps.DEFAULT_TIME_ZONE); - freeMarkerConfig.setOutputFormat(AllowedSettingValuesMaps.DEFAULT_OUTPUT_FORMAT); + freeMarkerConfig.setLocale(AllowedSettingValues.DEFAULT_LOCALE); + freeMarkerConfig.setTimeZone(AllowedSettingValues.DEFAULT_TIME_ZONE); + freeMarkerConfig.setOutputFormat(AllowedSettingValues.DEFAULT_OUTPUT_FORMAT); freeMarkerConfig.setOutputEncoding("UTF-8"); } /** - * @param templateSourceCode - * The FTL to execute; not {@code null}. - * @param dataModel - * The FreeMarker data-model to execute the template with; maybe {@code null}. - * @param outputFormat - * The output format to execute the template with; maybe {@code null}. - * @param locale - * The locale to execute the template with; maybe {@code null}. - * @param timeZone - * The time zone to execute the template with; maybe {@code null}. * * @return The result of the template parsing and evaluation. The method won't throw exception if that fails due to * errors in the template provided, instead it indicates this fact in the response object. That's because @@ -137,13 +128,11 @@ public class FreeMarkerService { * meaning of {@link RejectedExecutionException} either. */ @SuppressWarnings("deprecation") // for Thread.stop() - public FreeMarkerServiceResponse calculateTemplateOutput( - String templateSourceCode, Object dataModel, OutputFormat outputFormat, Locale locale, TimeZone timeZone) + public FreeMarkerServiceResponse executeTemplate(ExecuteTemplateArgs args) throws RejectedExecutionException { Objects.requireNonNull(templateExecutor, "templateExecutor was null - was postConstruct ever called?"); - final CalculateTemplateOutput task = new CalculateTemplateOutput( - templateSourceCode, dataModel, outputFormat, locale, timeZone); + final ExecuteTempalteTask task = new ExecuteTempalteTask(args); Future<FreeMarkerServiceResponse> future = templateExecutor.submit(task); synchronized (task) { @@ -203,7 +192,7 @@ public class FreeMarkerService { logger.warn("Calling Thread.stop() on unresponsive long template processing, which didn't " + "respond to Template.interrupt() on time. Service state may will be inconsistent; " + "JVM restart recommended!\n" - + "Template (quoted): \"" + StringEscapeUtils.escapeJava(templateSourceCode) + "\""); + + "Template (quoted): \"" + StringEscapeUtils.escapeJava(args.templateSourceCode) + "\""); } templateExecutorThread.stop(); } @@ -217,7 +206,7 @@ public class FreeMarkerService { templateExecutionEnded = true; } } // sync - } catch (InterruptedException e1) { + } catch (InterruptedException e2) { // Just continue... } } @@ -226,14 +215,14 @@ public class FreeMarkerService { logger.debug("Long template processing has ended."); try { return future.get(); - } catch (InterruptedException | ExecutionException e1) { - throw new FreeMarkerServiceException("Failed to get result from template executor task", e1); + } catch (InterruptedException | ExecutionException e2) { + throw new FreeMarkerServiceException("Failed to get result from template executor task", e2); } } else { throw new FreeMarkerServiceException( "Couldn't stop long running template processing within " + ABORTION_LOOP_TIME_LIMIT + " ms. It's possibly stuck forever. Such problems can exhaust the executor pool. " - + "Template (quoted): \"" + StringEscapeUtils.escapeJava(templateSourceCode) + "\""); + + "Template (quoted): " + StringUtil.jQuote(args.templateSourceCode)); } } } @@ -265,25 +254,65 @@ public class FreeMarkerService { logger.debug("The template had error(s)", e); return new FreeMarkerServiceResponse.Builder().buildForFailure(e); } + + /** + * Argument to {@link FreeMarkerService#executeTemplate(ExecuteTemplateArgs)}; fluent API to deal with many parameters, + * most of which is optional. Only {@code templateSourceCode} must be set to non-{@code null}. + */ + public static class ExecuteTemplateArgs { + private String templateSourceCode; + private Object dataModel; + private OutputFormat outputFormat; + private Locale locale; + private TimeZone timeZone; + private Integer tagSyntax; + private Integer interpolationSyntax; + + public ExecuteTemplateArgs templateSourceCode(String templateSourceCode) { + this.templateSourceCode = templateSourceCode; + return this; + } + + public ExecuteTemplateArgs dataModel(Object dataModel) { + this.dataModel = dataModel; + return this; + } + + public ExecuteTemplateArgs outputFormat(OutputFormat outputFormat) { + this.outputFormat = outputFormat; + return this; + } + + public ExecuteTemplateArgs locale(Locale locale) { + this.locale = locale; + return this; + } - private class CalculateTemplateOutput implements Callable<FreeMarkerServiceResponse> { + public ExecuteTemplateArgs timeZone(TimeZone timeZone) { + this.timeZone = timeZone; + return this; + } + + public ExecuteTemplateArgs tagSyntax(Integer tagSyntax) { + this.tagSyntax = tagSyntax; + return this; + } + + public ExecuteTemplateArgs interpolationSyntax(Integer interpolationSyntax) { + this.interpolationSyntax = interpolationSyntax; + return this; + } + } + + private class ExecuteTempalteTask implements Callable<FreeMarkerServiceResponse> { + private final ExecuteTemplateArgs args; private boolean templateExecutionStarted; private Thread templateExecutorThread; - private final String templateSourceCode; - private final Object dataModel; - private final OutputFormat outputFormat; - private final Locale locale; - private final TimeZone timeZone; private boolean taskEnded; - private CalculateTemplateOutput(String templateSourceCode, Object dataModel, - OutputFormat outputFormat, Locale locale, TimeZone timeZone) { - this.templateSourceCode = templateSourceCode; - this.dataModel = dataModel; - this.outputFormat = outputFormat; - this.locale = locale; - this.timeZone = timeZone; + private ExecuteTempalteTask(ExecuteTemplateArgs args) { + this.args = args; } @Override @@ -293,19 +322,25 @@ public class FreeMarkerService { try { TemplateConfiguration tCfg = new TemplateConfiguration(); tCfg.setParentConfiguration(freeMarkerConfig); - if (outputFormat != null) { - tCfg.setOutputFormat(outputFormat); + + if (args.outputFormat != null) { + tCfg.setOutputFormat(args.outputFormat); } - if (locale != null) { - tCfg.setLocale(locale); + if (args.locale != null) { + tCfg.setLocale(args.locale); } - if (timeZone != null) { - tCfg.setTimeZone(timeZone); + if (args.timeZone != null) { + tCfg.setTimeZone(args.timeZone); + } + if (args.tagSyntax != null) { + tCfg.setTagSyntax(args.tagSyntax); + } + if (args.interpolationSyntax != null) { + tCfg.setInterpolationSyntax(args.interpolationSyntax); } template = new Template(null, null, - new StringReader(templateSourceCode), freeMarkerConfig, tCfg, null); - + new StringReader(args.templateSourceCode), freeMarkerConfig, tCfg, null); tCfg.apply(template); } catch (ParseException e) { // Expected (part of normal operation) @@ -326,7 +361,7 @@ public class FreeMarkerService { notifyAll(); } try { - template.process(dataModel, new LengthLimitedWriter(writer, maxOutputLength)); + template.process(args.dataModel, new LengthLimitedWriter(writer, maxOutputLength)); } finally { synchronized (this) { templateExecutorThread = null; @@ -337,7 +372,7 @@ public class FreeMarkerService { } catch (LengthLimitExceededException e) { // Not really an error, we just cut the output here. resultTruncated = true; - writer.write(new MessageFormat(MAX_OUTPUT_LENGTH_EXCEEDED_TERMINATION, AllowedSettingValuesMaps.DEFAULT_LOCALE) + writer.write(new MessageFormat(MAX_OUTPUT_LENGTH_EXCEEDED_TERMINATION, AllowedSettingValues.DEFAULT_LOCALE) .format(new Object[] { maxOutputLength })); // Falls through } catch (TemplateException e) { http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/007c4e13/src/main/java/org/apache/freemarker/onlinetester/services/FreeMarkerServiceException.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/onlinetester/services/FreeMarkerServiceException.java b/src/main/java/org/apache/freemarker/onlinetester/services/FreeMarkerServiceException.java index 2ca7ee4..177b9ce 100644 --- a/src/main/java/org/apache/freemarker/onlinetester/services/FreeMarkerServiceException.java +++ b/src/main/java/org/apache/freemarker/onlinetester/services/FreeMarkerServiceException.java @@ -28,7 +28,6 @@ public class FreeMarkerServiceException extends RuntimeException { public FreeMarkerServiceException(String message) { super(message); - // TODO Auto-generated constructor stub } public FreeMarkerServiceException(String message, Throwable cause) { http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/007c4e13/src/main/java/org/apache/freemarker/onlinetester/view/FreeMarkerOnlineView.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/freemarker/onlinetester/view/FreeMarkerOnlineView.java b/src/main/java/org/apache/freemarker/onlinetester/view/FreeMarkerOnlineView.java index c90e2a5..3932dda 100644 --- a/src/main/java/org/apache/freemarker/onlinetester/view/FreeMarkerOnlineView.java +++ b/src/main/java/org/apache/freemarker/onlinetester/view/FreeMarkerOnlineView.java @@ -25,47 +25,79 @@ import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.function.BiFunction; import io.dropwizard.views.View; import org.apache.commons.lang3.StringUtils; import org.apache.freemarker.onlinetester.model.SelectionOption; -import org.apache.freemarker.onlinetester.services.AllowedSettingValuesMaps; +import org.apache.freemarker.onlinetester.services.AllowedSettingValues; import freemarker.template.Configuration; public class FreeMarkerOnlineView extends View { - private static final List<SelectionOption> LOCALE_SELECTION_OPTIONS = toLocaleSelectionOptions(AllowedSettingValuesMaps.LOCALE_MAP); - private static final List<SelectionOption> TIME_ZONE_SELECTION_OPTIONS = toSelectionOptions(AllowedSettingValuesMaps.TIME_ZONE_MAP); - private static final List<SelectionOption> OUTPUT_FORMAT_SELECTION_OPTIONS = toSelectionOptions(AllowedSettingValuesMaps.OUTPUT_FORMAT_MAP); + private static final List<SelectionOption> LOCALE_SELECTION_OPTIONS = toSelectionOptions( + AllowedSettingValues.LOCALE_MAP, + (k, v) -> truncate(v.getDisplayName(Locale.US), 18) + "; " + v.toString(), + true); + private static final List<SelectionOption> TIME_ZONE_SELECTION_OPTIONS = toSelectionOptions( + AllowedSettingValues.TIME_ZONE_MAP, + (k, v) -> truncate(k, 25), + true); + private static final List<SelectionOption> OUTPUT_FORMAT_SELECTION_OPTIONS = toSelectionOptions( + AllowedSettingValues.OUTPUT_FORMAT_MAP, + (k, v) -> k, + true); + private static final List<SelectionOption> TAG_SYNTAX_SELECTION_OPTIONS = toSelectionOptions( + AllowedSettingValues.TAG_SYNTAX_MAP, + (k, v) -> { + String label = k; + if (v == Configuration.ANGLE_BRACKET_TAG_SYNTAX) { + label += ", like <#...>, <@...>"; + } else if (v == Configuration.SQUARE_BRACKET_TAG_SYNTAX) { + label += ", like [#...], [@...]"; + } + return label; + }, + false); + private static final List<SelectionOption> INTERPOLATION_SYNTAX_SELECTION_OPTIONS = toSelectionOptions( + AllowedSettingValues.INTERPOLATION_SYNTAX_MAP, (k, v) -> { + String label = k; + if (v == Configuration.LEGACY_INTERPOLATION_SYNTAX) { + label += ", like ${...}, #{...}"; + } else if (v == Configuration.DOLLAR_INTERPOLATION_SYNTAX) { + label += ", like ${...}"; + } else if (v == Configuration.SQUARE_BRACKET_INTERPOLATION_SYNTAX) { + label += ", like [=...]"; + } + return label; + }, + false); private String template = ""; private String dataModel = ""; - private String outputFormat = AllowedSettingValuesMaps.DEFAULT_OUTPUT_FORMAT_KEY; - private String locale = AllowedSettingValuesMaps.DEFAULT_LOCALE_KEY; - private String timeZone = AllowedSettingValuesMaps.DEFAULT_TIME_ZONE_KEY; + private String outputFormat = AllowedSettingValues.DEFAULT_OUTPUT_FORMAT_KEY; + private String locale = AllowedSettingValues.DEFAULT_LOCALE_KEY; + private String timeZone = AllowedSettingValues.DEFAULT_TIME_ZONE_KEY; + private String tagSyntax = String.valueOf(AllowedSettingValues.DEFAULT_TAG_SYNTAX_KEY); + private String interpolationSyntax = String.valueOf(AllowedSettingValues.DEFAULT_INTERPOLATION_SYNTAX_KEY); private boolean execute; - - private static List<SelectionOption> toSelectionOptions(Map<String, ?> settingValueMap) { + + private static <V> List<SelectionOption> toSelectionOptions( + Map<String, ? extends V> settingValueMap, + BiFunction<String, ? super V, String> kvpToLabel, boolean sortByLabel) { ArrayList<SelectionOption> selectionOptions = new ArrayList<SelectionOption>(settingValueMap.size()); - for (String key : settingValueMap.keySet()) { - selectionOptions.add(new SelectionOption(key, truncate(key, 25))); + for (Map.Entry<String, ? extends V> ent : settingValueMap.entrySet()) { + String key = ent.getKey(); + selectionOptions.add(new SelectionOption( + key, + kvpToLabel.apply(key, ent.getValue()))); } - Collections.sort(selectionOptions); - return selectionOptions; - } - - private static List<SelectionOption> toLocaleSelectionOptions(Map<String, Locale> localeMap) { - ArrayList<SelectionOption> selectionOptions = new ArrayList<SelectionOption>(localeMap.size()); - for (Map.Entry<String, Locale> ent : localeMap.entrySet()) { - Locale locale = ent.getValue(); - selectionOptions.add( - new SelectionOption(ent.getKey(), - truncate(locale.getDisplayName(Locale.US), 18) + "; " + locale.toString())); + if (sortByLabel) { + Collections.sort(selectionOptions); } - Collections.sort(selectionOptions); return selectionOptions; } @@ -118,12 +150,20 @@ public class FreeMarkerOnlineView extends View { return TIME_ZONE_SELECTION_OPTIONS; } + public List<SelectionOption> getTagSyntaxes() { + return TAG_SYNTAX_SELECTION_OPTIONS; + } + + public List<SelectionOption> getInterpolationSyntaxes() { + return INTERPOLATION_SYNTAX_SELECTION_OPTIONS; + } + public String getOutputFormat() { return outputFormat; } public void setOutputFormat(String outputFormat) { - this.outputFormat = withDefault(outputFormat, AllowedSettingValuesMaps.DEFAULT_OUTPUT_FORMAT_KEY); + this.outputFormat = withDefault(outputFormat, AllowedSettingValues.DEFAULT_OUTPUT_FORMAT_KEY); } public String getLocale() { @@ -131,7 +171,7 @@ public class FreeMarkerOnlineView extends View { } public void setLocale(String locale) { - this.locale = withDefault(locale, AllowedSettingValuesMaps.DEFAULT_LOCALE_KEY); + this.locale = withDefault(locale, AllowedSettingValues.DEFAULT_LOCALE_KEY); } public String getTimeZone() { @@ -139,10 +179,26 @@ public class FreeMarkerOnlineView extends View { } public void setTimeZone(String timeZone) { - this.timeZone = withDefault(timeZone, AllowedSettingValuesMaps.DEFAULT_TIME_ZONE_KEY); + this.timeZone = withDefault(timeZone, AllowedSettingValues.DEFAULT_TIME_ZONE_KEY); } - public boolean isExecute() { + public String getTagSyntax() { + return tagSyntax; + } + + public void setTagSyntax(String tagSyntax) { + this.tagSyntax = withDefault(tagSyntax, AllowedSettingValues.DEFAULT_TAG_SYNTAX_KEY); + } + + public String getInterpolationSyntax() { + return interpolationSyntax; + } + + public void setInterpolationSyntax(String interpolationSyntax) { + this.interpolationSyntax = withDefault(interpolationSyntax, AllowedSettingValues.DEFAULT_INTERPOLATION_SYNTAX_KEY); + } + + public boolean isExecute() { return execute; } http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/007c4e13/src/main/resources/assets/js/script.js ---------------------------------------------------------------------- diff --git a/src/main/resources/assets/js/script.js b/src/main/resources/assets/js/script.js index 776d90a..9afba14 100644 --- a/src/main/resources/assets/js/script.js +++ b/src/main/resources/assets/js/script.js @@ -17,6 +17,8 @@ * under the License. */ +// IMPORTANT! If you modify this file, increase the number after "?v=" in the FreeMarker template! + $(document).ready(function() { $("#eval-btn").click(function() { execute(); @@ -42,7 +44,9 @@ function execute() { "dataModel": $("#dataModel").val(), "outputFormat": $("#outputFormat").val(), "locale": $("#locale").val(), - "timeZone": $("#timeZone").val() + "timeZone": $("#timeZone").val(), + "tagSyntax": $("#tagSyntax").val(), + "interpolationSyntax": $("#interpolationSyntax").val(), } $.ajax({ @@ -102,3 +106,5 @@ function showResult(result, isError) { $(".resultContainer").show(); autosize.update($("#result")); } + +//IMPORTANT! If you modify this file, increase the number after "?v=" in the FreeMarker template! http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/007c4e13/src/main/resources/freemarker-online.yml ---------------------------------------------------------------------- diff --git a/src/main/resources/freemarker-online.yml b/src/main/resources/freemarker-online.yml index a582b87..27070aa 100644 --- a/src/main/resources/freemarker-online.yml +++ b/src/main/resources/freemarker-online.yml @@ -36,7 +36,7 @@ server: appenders: [] viewRendererConfiguration: .ftl: - incompatibleImprovements: 2.3.27 + incompatibleImprovements: 2.3.28 locale: en_US timeZone: UTC outputEncoding: UTF-8 \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/007c4e13/src/main/resources/view/freemarker-online.ftl ---------------------------------------------------------------------- diff --git a/src/main/resources/view/freemarker-online.ftl b/src/main/resources/view/freemarker-online.ftl index 982fcfa..7b13c68 100644 --- a/src/main/resources/view/freemarker-online.ftl +++ b/src/main/resources/view/freemarker-online.ftl @@ -34,7 +34,7 @@ <script src="https://code.jquery.com/jquery-1.11.2.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.blockUI/2.70/jquery.blockUI.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/autosize.js/3.0.8/autosize.min.js"></script> - <script src="assets/js/script.js?v=3"></script> + <script src="assets/js/script.js?v=4"></script><!-- Always increase v if the script.js is changed! --> <script> $(function() { // Auto-focus on first form input: @@ -124,6 +124,16 @@ someXML = <example x="1">text</example></pre></div> helpHover='Date/time values are shown as seen from this time zone' /> </div> </div> + <div class="formPanel"> + <div class="horizontalBox"> + <@u.htmlSelect caption="Tag syntax" name="tagSyntax" selectionOptions=tagSyntaxes + helpLink='https://freemarker.apache.org/docs/dgui_misc_alternativesyntax.html#dgui_misc_alternativesyntax_tag' /> + </div> + <div class="horizontalBox"> + <@u.htmlSelect caption="Interpolation syntax" name="interpolationSyntax" selectionOptions=interpolationSyntaxes + helpLink='https://freemarker.apache.org/docs/dgui_misc_alternativesyntax.html#dgui_misc_alternativesyntax_interpolation' /> + </div> + </div> <div class="formBottomButtonsContainer"> <input id="eval-btn" type="button" value="Evaluate" class="pure-button pure-button-primary"/> <span class="faint">Ctrl+Enter in input fields will submit this form too</span> http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/007c4e13/src/test/java/org/apache/freemarker/onlinetester/ApplicationStartsTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/freemarker/onlinetester/ApplicationStartsTest.java b/src/test/java/org/apache/freemarker/onlinetester/ApplicationStartsTest.java index a422016..7d3aeea 100644 --- a/src/test/java/org/apache/freemarker/onlinetester/ApplicationStartsTest.java +++ b/src/test/java/org/apache/freemarker/onlinetester/ApplicationStartsTest.java @@ -33,7 +33,7 @@ import io.dropwizard.testing.junit.DropwizardAppRule; public class ApplicationStartsTest { @ClassRule - public final static DropwizardAppRule RULE = new DropwizardAppRule<FreeMarkerOnlineTesterConfiguration> + public final static DropwizardAppRule<FreeMarkerOnlineTesterConfiguration> RULE = new DropwizardAppRule<> (FreeMarkerOnlineTester.class, Resources.getResource("freemarker-online.yml").getPath()); http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/007c4e13/src/test/java/org/apache/freemarker/onlinetester/resources/ExecuteApiResourceTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/freemarker/onlinetester/resources/ExecuteApiResourceTest.java b/src/test/java/org/apache/freemarker/onlinetester/resources/ExecuteApiResourceTest.java index 7fa3fb4..ef89470 100644 --- a/src/test/java/org/apache/freemarker/onlinetester/resources/ExecuteApiResourceTest.java +++ b/src/test/java/org/apache/freemarker/onlinetester/resources/ExecuteApiResourceTest.java @@ -19,16 +19,19 @@ package org.apache.freemarker.onlinetester.resources; -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; import javax.ws.rs.client.Entity; import javax.ws.rs.core.Response; import org.apache.freemarker.onlinetester.model.ExecuteRequest; -import org.apache.freemarker.onlinetester.model.ExecuteResourceField; -import org.apache.freemarker.onlinetester.model.ExecuteResourceProblem; import org.apache.freemarker.onlinetester.model.ExecuteResponse; +import org.apache.freemarker.onlinetester.model.ExecuteResponseProblem; import org.junit.Test; public class ExecuteApiResourceTest extends ResourceTest { @@ -53,7 +56,7 @@ public class ExecuteApiResourceTest extends ResourceTest { assertEquals(200, resp.getStatus()); ExecuteResponse response = resp.readEntity(ExecuteResponse.class); assertNotNull(response.getProblems()); - assertTrue(containsProblem(response, ExecuteResourceField.DATA_MODEL)); + assertTrue(containsProblem(response, ExecuteRequest.Field.DATA_MODEL)); } @Test @@ -63,8 +66,8 @@ public class ExecuteApiResourceTest extends ResourceTest { assertEquals(200, resp.getStatus()); ExecuteResponse response = resp.readEntity(ExecuteResponse.class); assertNotNull(response.getProblems()); - assertTrue(containsProblem(response, ExecuteResourceField.DATA_MODEL)); - String problemMessage = getProblemMessage(response, ExecuteResourceField.DATA_MODEL); + assertTrue(containsProblem(response, ExecuteRequest.Field.DATA_MODEL)); + String problemMessage = getProblemMessage(response, ExecuteRequest.Field.DATA_MODEL); assertThat(problemMessage, containsString("data model")); assertThat(problemMessage, containsString("limit")); } @@ -76,8 +79,8 @@ public class ExecuteApiResourceTest extends ResourceTest { assertEquals(200, resp.getStatus()); ExecuteResponse response = resp.readEntity(ExecuteResponse.class); assertNotNull(response.getProblems()); - assertTrue(containsProblem(response, ExecuteResourceField.TEMPLATE)); - String problemMessage = getProblemMessage(response, ExecuteResourceField.TEMPLATE); + assertTrue(containsProblem(response, ExecuteRequest.Field.TEMPLATE)); + String problemMessage = getProblemMessage(response, ExecuteRequest.Field.TEMPLATE); assertThat(problemMessage, containsString("template")); assertThat(problemMessage, containsString("limit")); } @@ -88,17 +91,22 @@ public class ExecuteApiResourceTest extends ResourceTest { req.setOutputFormat("wrongOutputFormat"); req.setLocale("wrongLocale"); req.setTimeZone("wrongTimeZone"); + req.setTagSyntax("wrongTagSyntax"); + req.setInterpolationSyntax("wrongInterpolationSyntax"); Response resp = postJSON(req); assertEquals(200, resp.getStatus()); ExecuteResponse response = resp.readEntity(ExecuteResponse.class); assertNotNull(response.getProblems()); - assertThat(getProblemMessage(response, ExecuteResourceField.TEMPLATE), containsString("limit")); - assertThat(getProblemMessage(response, ExecuteResourceField.DATA_MODEL), containsString("limit")); - assertThat(getProblemMessage(response, ExecuteResourceField.OUTPUT_FORMAT), containsString("wrongOutputFormat")); - assertThat(getProblemMessage(response, ExecuteResourceField.LOCALE), containsString("wrongLocale")); - assertThat(getProblemMessage(response, ExecuteResourceField.TIME_ZONE), containsString("wrongTimeZone")); + assertThat(getProblemMessage(response, ExecuteRequest.Field.TEMPLATE), containsString("limit")); + assertThat(getProblemMessage(response, ExecuteRequest.Field.DATA_MODEL), containsString("limit")); + assertThat(getProblemMessage(response, ExecuteRequest.Field.OUTPUT_FORMAT), containsString("wrongOutputFormat")); + assertThat(getProblemMessage(response, ExecuteRequest.Field.LOCALE), containsString("wrongLocale")); + assertThat(getProblemMessage(response, ExecuteRequest.Field.TIME_ZONE), containsString("wrongTimeZone")); + assertThat(getProblemMessage(response, ExecuteRequest.Field.TAG_SYNTAX), containsString("wrongTagSyntax")); + assertThat(getProblemMessage(response, ExecuteRequest.Field.INTERPOLATION_SYNTAX), containsString( + "wrongInterpolationSyntax")); } private String create30KString() { @@ -109,8 +117,8 @@ public class ExecuteApiResourceTest extends ResourceTest { return sb.toString(); } - private boolean containsProblem(ExecuteResponse response, ExecuteResourceField field) { - for (ExecuteResourceProblem problem : response.getProblems()) { + private boolean containsProblem(ExecuteResponse response, ExecuteRequest.Field field) { + for (ExecuteResponseProblem problem : response.getProblems()) { if (problem.getField() == field) { return true; } @@ -118,8 +126,8 @@ public class ExecuteApiResourceTest extends ResourceTest { return false; } - private String getProblemMessage(ExecuteResponse response, ExecuteResourceField field) { - for (ExecuteResourceProblem problem : response.getProblems()) { + private String getProblemMessage(ExecuteResponse response, ExecuteRequest.Field field) { + for (ExecuteResponseProblem problem : response.getProblems()) { if (problem.getField() == field) { return problem.getMessage(); } http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/007c4e13/src/test/java/org/apache/freemarker/onlinetester/resources/WebPageResourceTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/freemarker/onlinetester/resources/WebPageResourceTest.java b/src/test/java/org/apache/freemarker/onlinetester/resources/WebPageResourceTest.java index 739628f..091911a 100644 --- a/src/test/java/org/apache/freemarker/onlinetester/resources/WebPageResourceTest.java +++ b/src/test/java/org/apache/freemarker/onlinetester/resources/WebPageResourceTest.java @@ -21,24 +21,17 @@ package org.apache.freemarker.onlinetester.resources; import static org.junit.Assert.assertEquals; import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyMap; -import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.when; -import java.util.Locale; -import java.util.TimeZone; - +import org.apache.freemarker.onlinetester.services.FreeMarkerService; +import org.apache.freemarker.onlinetester.services.FreeMarkerService.ExecuteTemplateArgs; +import org.apache.freemarker.onlinetester.view.FreeMarkerOnlineView; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; -import org.apache.freemarker.onlinetester.services.FreeMarkerService; -import org.apache.freemarker.onlinetester.view.FreeMarkerOnlineView; - -import freemarker.core.OutputFormat; - @RunWith(MockitoJUnitRunner.class) public class WebPageResourceTest { @@ -50,9 +43,7 @@ public class WebPageResourceTest { @Test public void testInitialForm() { - when(freeMarkerService.calculateTemplateOutput( - anyString(), anyMap(), any(OutputFormat.class), any(Locale.class), any(TimeZone.class))) - .thenThrow(new AssertionError()); + when(freeMarkerService.executeTemplate(any(ExecuteTemplateArgs.class))).thenThrow(new AssertionError()); FreeMarkerOnlineView view = webPageResource.blankForm(); assertEquals(view.getTemplate(), ""); assertEquals(view.getDataModel(), ""); @@ -60,10 +51,8 @@ public class WebPageResourceTest { @Test public void testPostedBlankForm() { - when(freeMarkerService.calculateTemplateOutput( - anyString(), anyMap(), any(OutputFormat.class), any(Locale.class), any(TimeZone.class))) - .thenThrow(new AssertionError()); - FreeMarkerOnlineView view = webPageResource.formResult(null, null, null, null, null); + when(freeMarkerService.executeTemplate(any(ExecuteTemplateArgs.class))).thenThrow(new AssertionError()); + FreeMarkerOnlineView view = webPageResource.formResult(null, null, null, null, null, null, null); assertEquals(view.getTemplate(), ""); assertEquals(view.getDataModel(), ""); } http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/007c4e13/src/test/java/org/apache/freemarker/onlinetester/services/FreeMarkerServiceTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/freemarker/onlinetester/services/FreeMarkerServiceTest.java b/src/test/java/org/apache/freemarker/onlinetester/services/FreeMarkerServiceTest.java index 37c52c9..3865265 100644 --- a/src/test/java/org/apache/freemarker/onlinetester/services/FreeMarkerServiceTest.java +++ b/src/test/java/org/apache/freemarker/onlinetester/services/FreeMarkerServiceTest.java @@ -36,6 +36,7 @@ import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import org.apache.freemarker.onlinetester.services.FreeMarkerService.ExecuteTemplateArgs; import org.junit.Before; import org.junit.Test; import org.slf4j.Logger; @@ -44,6 +45,7 @@ import org.slf4j.LoggerFactory; import freemarker.core.Environment; import freemarker.core.HTMLOutputFormat; import freemarker.core.ParseException; +import freemarker.template.Configuration; import freemarker.template.TemplateDirectiveBody; import freemarker.template.TemplateDirectiveModel; import freemarker.template.TemplateException; @@ -77,8 +79,8 @@ public class FreeMarkerServiceTest { @Test public void testCalculationOfATemplateWithNoDataModel() { - FreeMarkerServiceResponse serviceResponse = getService().calculateTemplateOutput( - "test", Collections.<String, Object>emptyMap(), null, null, null); + FreeMarkerServiceResponse serviceResponse = getService().executeTemplate(new ExecuteTemplateArgs() + .templateSourceCode("test").dataModel(Collections.emptyMap())); assertThat(serviceResponse.isSuccesful(), is(true)); assertThat(serviceResponse.getTemplateOutput(), is("test")); } @@ -88,8 +90,8 @@ public class FreeMarkerServiceTest { HashMap<String, Object> dataModel = new HashMap<>(); dataModel.put("var1", "val1"); String templateSourceCode = "${var1}"; - FreeMarkerServiceResponse serviceResponse = getService().calculateTemplateOutput( - templateSourceCode, dataModel, null, null, null); + FreeMarkerServiceResponse serviceResponse = getService().executeTemplate(new ExecuteTemplateArgs() + .templateSourceCode(templateSourceCode).dataModel(dataModel)); assertThat(serviceResponse.getTemplateOutput(), equalTo("val1")); } @@ -99,8 +101,8 @@ public class FreeMarkerServiceTest { dataModel.put("var1", "val1"); dataModel.put("var2", "val2"); String template = "${var1?capitalize} ${var2?cap_first}"; - FreeMarkerServiceResponse serviceResponse = getService().calculateTemplateOutput( - template, dataModel, null, null, null); + FreeMarkerServiceResponse serviceResponse = getService().executeTemplate(new ExecuteTemplateArgs() + .templateSourceCode(template).dataModel(dataModel)); assertThat(serviceResponse.getTemplateOutput(), equalTo("Val1 Val2")); } @@ -108,13 +110,13 @@ public class FreeMarkerServiceTest { public void testOutputFormatParamterMatters() { String template = "${'&'}"; { - FreeMarkerServiceResponse serviceResponse = getService().calculateTemplateOutput( - template, null, null, null, null); + FreeMarkerServiceResponse serviceResponse = getService().executeTemplate(new ExecuteTemplateArgs() + .templateSourceCode(template)); assertThat(serviceResponse.getTemplateOutput(), equalTo("&")); } { - FreeMarkerServiceResponse serviceResponse = getService().calculateTemplateOutput( - template, null, HTMLOutputFormat.INSTANCE, null, null); + FreeMarkerServiceResponse serviceResponse = getService().executeTemplate(new ExecuteTemplateArgs() + .templateSourceCode(template).outputFormat(HTMLOutputFormat.INSTANCE)); assertThat(serviceResponse.getTemplateOutput(), equalTo("&")); } } @@ -123,13 +125,13 @@ public class FreeMarkerServiceTest { public void testLocaleParameterMatters() { String template = "${.locale}"; { - FreeMarkerServiceResponse serviceResponse = getService().calculateTemplateOutput( - template, null, null, new Locale("en", "US"), null); + FreeMarkerServiceResponse serviceResponse = getService().executeTemplate(new ExecuteTemplateArgs() + .templateSourceCode(template).locale(Locale.US)); assertThat(serviceResponse.getTemplateOutput(), equalTo("en_US")); } { - FreeMarkerServiceResponse serviceResponse = getService().calculateTemplateOutput( - template, null, null, new Locale("ru", "RU"), null); + FreeMarkerServiceResponse serviceResponse = getService().executeTemplate(new ExecuteTemplateArgs() + .templateSourceCode(template).locale(new Locale("ru", "RU"))); assertThat(serviceResponse.getTemplateOutput(), equalTo("ru_RU")); } } @@ -140,33 +142,68 @@ public class FreeMarkerServiceTest { String gmt1Result; { - FreeMarkerServiceResponse serviceResponse = getService().calculateTemplateOutput( - template, null, null, null, TimeZone.getTimeZone("GMT+01")); + FreeMarkerServiceResponse serviceResponse = getService().executeTemplate(new ExecuteTemplateArgs() + .templateSourceCode(template).timeZone(TimeZone.getTimeZone("GMT+01"))); gmt1Result = serviceResponse.getTemplateOutput(); } String gmt2Result; { - FreeMarkerServiceResponse serviceResponse = getService().calculateTemplateOutput( - template, null, null, new Locale("ru", "RU"), null); + FreeMarkerServiceResponse serviceResponse = getService().executeTemplate(new ExecuteTemplateArgs() + .templateSourceCode(template).locale(new Locale("ru", "RU"))); gmt2Result = serviceResponse.getTemplateOutput(); } assertThat(gmt1Result, not(equalTo(gmt2Result))); } + + @Test + public void testTagSyntaxParameterMatters() { + String template = "[#if true]1[/#if]<#if true>2</#if>"; + { + FreeMarkerServiceResponse serviceResponse = getService().executeTemplate(new ExecuteTemplateArgs() + .templateSourceCode(template).tagSyntax(Configuration.ANGLE_BRACKET_TAG_SYNTAX)); + assertThat(serviceResponse.getTemplateOutput(), equalTo("[#if true]1[/#if]2")); + } + for (int tagSyntax : new int[] { Configuration.SQUARE_BRACKET_TAG_SYNTAX, Configuration.AUTO_DETECT_TAG_SYNTAX }) { + FreeMarkerServiceResponse serviceResponse = getService().executeTemplate(new ExecuteTemplateArgs() + .templateSourceCode(template).tagSyntax(tagSyntax)); + assertThat(serviceResponse.getTemplateOutput(), equalTo("1<#if true>2</#if>")); + } + } + + @Test + public void testInterpolationSyntaxParameterMatters() { + String template = "${1} #{2} [=3]"; + { + FreeMarkerServiceResponse serviceResponse = getService().executeTemplate(new ExecuteTemplateArgs() + .templateSourceCode(template).interpolationSyntax(Configuration.LEGACY_INTERPOLATION_SYNTAX)); + assertThat(serviceResponse.getTemplateOutput(), equalTo("1 2 [=3]")); + } + { + FreeMarkerServiceResponse serviceResponse = getService().executeTemplate(new ExecuteTemplateArgs() + .templateSourceCode(template).interpolationSyntax(Configuration.DOLLAR_INTERPOLATION_SYNTAX)); + assertThat(serviceResponse.getTemplateOutput(), equalTo("1 #{2} [=3]")); + } + { + FreeMarkerServiceResponse serviceResponse = getService().executeTemplate(new ExecuteTemplateArgs() + .templateSourceCode(template).interpolationSyntax(Configuration.SQUARE_BRACKET_INTERPOLATION_SYNTAX)); + assertThat(serviceResponse.getTemplateOutput(), equalTo("${1} #{2} 3")); + } + } @Test public void testTemplateWithSyntaxError() { - FreeMarkerServiceResponse serviceResponse = getService().calculateTemplateOutput( - "test ${xx", Collections.<String, Object>emptyMap(), null, null, null); + FreeMarkerServiceResponse serviceResponse = getService().executeTemplate(new ExecuteTemplateArgs() + .templateSourceCode("test ${xx").dataModel(Collections.emptyMap())); assertThat(serviceResponse.isSuccesful(), is(false)); assertThat(serviceResponse.getFailureReason(), instanceOf(ParseException.class)); } @Test public void testTemplateWithEvaluationError() { - FreeMarkerServiceResponse serviceResponse = getService().calculateTemplateOutput( - "test ${x}", Collections.<String, Object>emptyMap(), null, null, null); + FreeMarkerServiceResponse serviceResponse = getService().executeTemplate(new ExecuteTemplateArgs() + .templateSourceCode("test ${x}").dataModel(Collections.emptyMap())); assertThat(serviceResponse.isSuccesful(), is(false)); assertThat(serviceResponse.getFailureReason(), instanceOf(TemplateException.class)); } @@ -174,8 +211,8 @@ public class FreeMarkerServiceTest { @Test public void testResultAlmostTruncation() { serviceBuilder.setMaxOutputLength(5); - FreeMarkerServiceResponse serviceResponse = getService().calculateTemplateOutput( - TRUNCATION_TEST_TEMPLATE, Collections.<String, Object>emptyMap(), null, null, null); + FreeMarkerServiceResponse serviceResponse = getService().executeTemplate(new ExecuteTemplateArgs() + .templateSourceCode(TRUNCATION_TEST_TEMPLATE).dataModel(Collections.emptyMap())); assertThat(serviceResponse.isSuccesful(), is(true)); assertThat(serviceResponse.isTemplateOutputTruncated(), is(false)); assertThat(serviceResponse.getTemplateOutput(), equalTo(TRUNCATION_TEST_TEMPLATE)); @@ -185,8 +222,8 @@ public class FreeMarkerServiceTest { public void testResultTruncation() { serviceBuilder.setMaxOutputLength(4); FreeMarkerService service = getService(); - FreeMarkerServiceResponse serviceResponse = service.calculateTemplateOutput( - TRUNCATION_TEST_TEMPLATE, Collections.<String, Object>emptyMap(), null, null, null); + FreeMarkerServiceResponse serviceResponse = service.executeTemplate(new ExecuteTemplateArgs() + .templateSourceCode(TRUNCATION_TEST_TEMPLATE).dataModel(Collections.emptyMap())); assertThat(serviceResponse.isSuccesful(), is(true)); assertThat(serviceResponse.isTemplateOutputTruncated(), is(true)); assertThat(serviceResponse.getTemplateOutput(), @@ -205,8 +242,9 @@ public class FreeMarkerServiceTest { @Override public FreeMarkerServiceResponse call() throws Exception { - return getService().calculateTemplateOutput( - "<#list 1.. as _></#list>", Collections.<String, Object>emptyMap(), null, null, null); + return getService().executeTemplate(new ExecuteTemplateArgs() + .templateSourceCode("<#list 1.. as _></#list>") + .dataModel(Collections.emptyMap())); } }); @@ -231,7 +269,8 @@ public class FreeMarkerServiceTest { new Thread(new Runnable() { @Override public void run() { - service.calculateTemplateOutput("<@blocker/>", blockerDataModel, null, null, null); + service.executeTemplate(new ExecuteTemplateArgs() + .templateSourceCode("<@blocker/>").dataModel(blockerDataModel)); } }).start(); } @@ -253,7 +292,8 @@ public class FreeMarkerServiceTest { // Shouldn't accept on more tasks: try { - service.calculateTemplateOutput("<@blocker/>", blockerDataModel, null, null, null); + service.executeTemplate(new ExecuteTemplateArgs() + .templateSourceCode("<@blocker/>").dataModel(blockerDataModel)); fail("Expected RejectedExecutionException, but nothing was thrown."); } catch (RejectedExecutionException e) { // Expected http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/007c4e13/src/test/java/org/apache/freemarker/onlinetester/view/FreeMarkerOnlineViewTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/freemarker/onlinetester/view/FreeMarkerOnlineViewTest.java b/src/test/java/org/apache/freemarker/onlinetester/view/FreeMarkerOnlineViewTest.java index b9572ba..e632d77 100644 --- a/src/test/java/org/apache/freemarker/onlinetester/view/FreeMarkerOnlineViewTest.java +++ b/src/test/java/org/apache/freemarker/onlinetester/view/FreeMarkerOnlineViewTest.java @@ -26,7 +26,7 @@ import java.util.TimeZone; import org.junit.Test; -import org.apache.freemarker.onlinetester.services.AllowedSettingValuesMaps; +import org.apache.freemarker.onlinetester.services.AllowedSettingValues; import freemarker.core.HTMLOutputFormat; @@ -41,9 +41,9 @@ public class FreeMarkerOnlineViewTest { FreeMarkerOnlineView view = new FreeMarkerOnlineView(); assertEquals(view.getTemplate(), ""); assertEquals(view.getDataModel(), ""); - assertEquals(view.getOutputFormat(), AllowedSettingValuesMaps.DEFAULT_OUTPUT_FORMAT_KEY); - assertEquals(view.getLocale(), AllowedSettingValuesMaps.DEFAULT_LOCALE_KEY); - assertEquals(view.getTimeZone(), AllowedSettingValuesMaps.DEFAULT_TIME_ZONE_KEY); + assertEquals(view.getOutputFormat(), AllowedSettingValues.DEFAULT_OUTPUT_FORMAT_KEY); + assertEquals(view.getLocale(), AllowedSettingValues.DEFAULT_LOCALE_KEY); + assertEquals(view.getTimeZone(), AllowedSettingValues.DEFAULT_TIME_ZONE_KEY); } @Test
