You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@freemarker.apache.org by dd...@apache.org on 2017/04/09 08:15:32 UTC
[1/5] incubator-freemarker-online-tester git commit: renamed the
package name to org/apache/freemarker/onlinetester
Repository: incubator-freemarker-online-tester
Updated Branches:
refs/heads/master 7b46afe22 -> 808bd5365
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/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
new file mode 100644
index 0000000..fcaf358
--- /dev/null
+++ b/src/test/java/org/apache/freemarker/onlinetester/services/FreeMarkerServiceTest.java
@@ -0,0 +1,308 @@
+/*
+ * 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 static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.greaterThan;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+import static org.hamcrest.Matchers.startsWith;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.TimeZone;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import freemarker.core.Environment;
+import freemarker.core.HTMLOutputFormat;
+import freemarker.core.ParseException;
+import freemarker.template.TemplateDirectiveBody;
+import freemarker.template.TemplateDirectiveModel;
+import freemarker.template.TemplateException;
+import freemarker.template.TemplateModel;
+
+@RunWith(MockitoJUnitRunner.class)
+public class FreeMarkerServiceTest {
+
+ private static final Logger LOG = LoggerFactory.getLogger(FreeMarkerServiceTest.class);
+
+ private static final int MAX_THREADS = 3;
+ private static final int MAX_QUEUE_LENGTH = 2;
+ private static final int MAX_TEMPLATE_EXECUTION_TIME = 1500;
+
+ private static final int BLOCKING_TEST_TIMEOUT = 5000;
+
+ private static final String TRUNCATION_TEST_TEMPLATE = "12345";
+
+ @InjectMocks
+ private FreeMarkerService freeMarkerService;
+
+ @Before
+ public void initializeSpringBeans() {
+ freeMarkerService.setMaxQueueLength(MAX_QUEUE_LENGTH);
+ freeMarkerService.setMaxThreads(MAX_THREADS);
+ freeMarkerService.postConstruct();
+ freeMarkerService.setMaxTemplateExecutionTime(MAX_TEMPLATE_EXECUTION_TIME);
+ }
+
+ @Test
+ public void testCalculationOfATemplateWithNoDataModel() {
+ FreeMarkerServiceResponse serviceResponse = freeMarkerService.calculateTemplateOutput(
+ "test", Collections.<String, Object>emptyMap(), null, null, null);
+ assertThat(serviceResponse.isSuccesful(), is(true));
+ assertThat(serviceResponse.getTemplateOutput(), is("test"));
+ }
+
+ @Test
+ public void testSimpleTemplate() {
+ HashMap<String, Object> dataModel = new HashMap<>();
+ dataModel.put("var1", "val1");
+ String templateSourceCode = "${var1}";
+ FreeMarkerServiceResponse serviceResponse = freeMarkerService.calculateTemplateOutput(
+ templateSourceCode, dataModel, null, null, null);
+ assertThat(serviceResponse.getTemplateOutput(), equalTo("val1"));
+ }
+
+ @Test
+ public void testTemplateWithFewArgsAndOperators() {
+ HashMap<String, Object> dataModel = new HashMap<>();
+ dataModel.put("var1", "val1");
+ dataModel.put("var2", "val2");
+ String template = "${var1?capitalize} ${var2?cap_first}";
+ FreeMarkerServiceResponse serviceResponse = freeMarkerService.calculateTemplateOutput(
+ template, dataModel, null, null, null);
+ assertThat(serviceResponse.getTemplateOutput(), equalTo("Val1 Val2"));
+ }
+
+ @Test
+ public void testOutputFormatParamterMatters() {
+ String template = "${'&'}";
+ {
+ FreeMarkerServiceResponse serviceResponse = freeMarkerService.calculateTemplateOutput(
+ template, null, null, null, null);
+ assertThat(serviceResponse.getTemplateOutput(), equalTo("&"));
+ }
+ {
+ FreeMarkerServiceResponse serviceResponse = freeMarkerService.calculateTemplateOutput(
+ template, null, HTMLOutputFormat.INSTANCE, null, null);
+ assertThat(serviceResponse.getTemplateOutput(), equalTo("&"));
+ }
+ }
+
+ @Test
+ public void testLocaleParameterMatters() {
+ String template = "${.locale}";
+ {
+ FreeMarkerServiceResponse serviceResponse = freeMarkerService.calculateTemplateOutput(
+ template, null, null, new Locale("en", "US"), null);
+ assertThat(serviceResponse.getTemplateOutput(), equalTo("en_US"));
+ }
+ {
+ FreeMarkerServiceResponse serviceResponse = freeMarkerService.calculateTemplateOutput(
+ template, null, null, new Locale("ru", "RU"), null);
+ assertThat(serviceResponse.getTemplateOutput(), equalTo("ru_RU"));
+ }
+ }
+
+ @Test
+ public void testTimeZoneParameterMatters() {
+ String template = "${" + System.currentTimeMillis() + "?numberToDatetime}";
+
+ String gmt1Result;
+ {
+ FreeMarkerServiceResponse serviceResponse = freeMarkerService.calculateTemplateOutput(
+ template, null, null, null, TimeZone.getTimeZone("GMT+01"));
+ gmt1Result = serviceResponse.getTemplateOutput();
+ }
+
+ String gmt2Result;
+ {
+ FreeMarkerServiceResponse serviceResponse = freeMarkerService.calculateTemplateOutput(
+ template, null, null, new Locale("ru", "RU"), null);
+ gmt2Result = serviceResponse.getTemplateOutput();
+ }
+
+ assertThat(gmt1Result, not(equalTo(gmt2Result)));
+ }
+
+ @Test
+ public void testTemplateWithSyntaxError() {
+ FreeMarkerServiceResponse serviceResponse = freeMarkerService.calculateTemplateOutput(
+ "test ${xx", Collections.<String, Object>emptyMap(), null, null, null);
+ assertThat(serviceResponse.isSuccesful(), is(false));
+ assertThat(serviceResponse.getFailureReason(), instanceOf(ParseException.class));
+ }
+
+ @Test
+ public void testTemplateWithEvaluationError() {
+ FreeMarkerServiceResponse serviceResponse = freeMarkerService.calculateTemplateOutput(
+ "test ${x}", Collections.<String, Object>emptyMap(), null, null, null);
+ assertThat(serviceResponse.isSuccesful(), is(false));
+ assertThat(serviceResponse.getFailureReason(), instanceOf(TemplateException.class));
+ }
+
+ @Test
+ public void testResultAlmostTruncation() {
+ freeMarkerService.setMaxOutputLength(5);
+ FreeMarkerServiceResponse serviceResponse = freeMarkerService.calculateTemplateOutput(
+ TRUNCATION_TEST_TEMPLATE, Collections.<String, Object>emptyMap(), null, null, null);
+ assertThat(serviceResponse.isSuccesful(), is(true));
+ assertThat(serviceResponse.isTemplateOutputTruncated(), is(false));
+ assertThat(serviceResponse.getTemplateOutput(), equalTo(TRUNCATION_TEST_TEMPLATE));
+ }
+
+ @Test
+ public void testResultTruncation() {
+ freeMarkerService.setMaxOutputLength(4);
+ FreeMarkerServiceResponse serviceResponse = freeMarkerService.calculateTemplateOutput(
+ TRUNCATION_TEST_TEMPLATE, Collections.<String, Object>emptyMap(), null, null, null);
+ assertThat(serviceResponse.isSuccesful(), is(true));
+ assertThat(serviceResponse.isTemplateOutputTruncated(), is(true));
+ assertThat(serviceResponse.getTemplateOutput(),
+ startsWith(TRUNCATION_TEST_TEMPLATE.substring(0, freeMarkerService.getMaxOutputLength())));
+ assertThat(serviceResponse.getTemplateOutput().charAt(freeMarkerService.getMaxOutputLength()),
+ not(equalTo(TRUNCATION_TEST_TEMPLATE.charAt(freeMarkerService.getMaxOutputLength()))));
+ }
+
+ @Test
+ public void testTemplateExecutionTimeout() throws InterruptedException, ExecutionException {
+ freeMarkerService.setMaxTemplateExecutionTime(200);
+
+ // To avoid blocking the CI server forever without giving error:
+ Future<FreeMarkerServiceResponse> future = Executors.newSingleThreadExecutor().submit(
+ new Callable<FreeMarkerServiceResponse>() {
+
+ @Override
+ public FreeMarkerServiceResponse call() throws Exception {
+ return freeMarkerService.calculateTemplateOutput(
+ "<#list 1.. as _></#list>", Collections.<String, Object>emptyMap(), null, null, null);
+ }
+
+ });
+ FreeMarkerServiceResponse serviceResponse;
+ try {
+ serviceResponse = future.get(BLOCKING_TEST_TIMEOUT, TimeUnit.MILLISECONDS);
+ } catch (TimeoutException e) {
+ throw new AssertionError("The template execution wasn't aborted (within the timeout).");
+ }
+ assertThat(serviceResponse.isSuccesful(), is(false));
+ assertThat(serviceResponse.getFailureReason(), instanceOf(TimeoutException.class));
+ }
+
+ @Test
+ public void testServiceOverburden() throws InterruptedException {
+ final BlockerDirective blocker = new BlockerDirective();
+ final Map<String, BlockerDirective> blockerDataModel = Collections.singletonMap("blocker", blocker);
+ try {
+ // Fill all available task "slots":
+ for (int i = 0; i < MAX_THREADS + MAX_QUEUE_LENGTH; i++) {
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ freeMarkerService.calculateTemplateOutput("<@blocker/>", blockerDataModel, null, null, null);
+ }
+ }).start();
+ }
+
+ // Wait until all template executions has started:
+ synchronized (blocker) {
+ final long startTime = System.currentTimeMillis();
+ while (blocker.getEntered() < MAX_THREADS) {
+ // To avoid blocking the CI server forever is something goes wrong:
+ if (System.currentTimeMillis() - startTime > BLOCKING_TEST_TIMEOUT) {
+ fail("JUnit test timed out");
+ }
+ blocker.wait(1000);
+ }
+ }
+ Thread.sleep(200);
+ // Because the others are waiting in the queue, and weren't started:
+ assertThat(blocker.getEntered(), not(greaterThan(MAX_THREADS)));
+
+ // Souldn't accept on more tasks:
+ try {
+ freeMarkerService.calculateTemplateOutput("<@blocker/>", blockerDataModel, null, null, null);
+ fail("Expected RejectedExecutionException, but nothing was thrown.");
+ } catch (RejectedExecutionException e) {
+ // Expected
+ }
+ } finally {
+ // Ensure that the started threads will end:
+ blocker.release();
+ }
+ }
+
+ private static final class BlockerDirective implements TemplateDirectiveModel {
+
+ private int entered;
+ private boolean released;
+
+ public synchronized void release() {
+ released = true;
+ notifyAll();
+ }
+
+ @Override
+ public synchronized void execute(Environment env, @SuppressWarnings("rawtypes") Map params,
+ TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException {
+ entered++;
+ notifyAll();
+ final long startTime = System.currentTimeMillis();
+ while (!released) {
+ // To avoid blocking the CI server forever is something goes wrong:
+ if (System.currentTimeMillis() - startTime > BLOCKING_TEST_TIMEOUT) {
+ LOG.error("JUnit test timed out");
+ }
+ try {
+ wait(1000);
+ } catch (InterruptedException e) {
+ LOG.error("JUnit test was interrupted");
+ }
+ }
+ LOG.debug("Blocker released");
+ }
+
+ public synchronized int getEntered() {
+ return entered;
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/test/java/org/apache/freemarker/onlinetester/util/DataModelParserTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/freemarker/onlinetester/util/DataModelParserTest.java b/src/test/java/org/apache/freemarker/onlinetester/util/DataModelParserTest.java
new file mode 100644
index 0000000..468b2b5
--- /dev/null
+++ b/src/test/java/org/apache/freemarker/onlinetester/util/DataModelParserTest.java
@@ -0,0 +1,281 @@
+/*
+ * 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.util;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.math.BigDecimal;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.GregorianCalendar;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+import freemarker.template.utility.DateUtil;
+
+public class DataModelParserTest {
+
+ @Test
+ public void testEmpty() throws DataModelParsingException {
+ assertTrue(DataModelParser.parse("", DateUtil.UTC).isEmpty());
+ assertTrue(DataModelParser.parse(" \n ", DateUtil.UTC).isEmpty());
+ }
+
+ @Test
+ public void testSingleAssignment() throws DataModelParsingException {
+ assertEquals(ImmutableMap.of("n", "v"), DataModelParser.parse("n=v", DateUtil.UTC));
+ assertEquals(ImmutableMap.of("n", "v"), DataModelParser.parse("\n\n\tn\t= v", DateUtil.UTC));
+ assertEquals(ImmutableMap.of("longerN", "longer v"), DataModelParser.parse("longerN=longer v", DateUtil.UTC));
+ assertEquals(ImmutableMap.of("a:b.c-d$@", "foo bar\nbaaz"), DataModelParser.parse("a:b.c-d$@ = foo bar\nbaaz", DateUtil.UTC));
+ }
+
+ @Test
+ public void testNotBlankButHasNoAssignment() {
+ try {
+ DataModelParser.parse("x", DateUtil.UTC);
+ fail();
+ } catch (DataModelParsingException e) {
+ assertThat(e.getMessage(), containsString("must start with an assignment"));
+ }
+ }
+
+ @Test
+ public void testNoLinebreakBeforeEquals() {
+ try {
+ DataModelParser.parse("x\n=y", DateUtil.UTC);
+ fail();
+ } catch (DataModelParsingException e) {
+ assertThat(e.getMessage(), containsString("must start with an assignment"));
+ }
+ }
+
+ @Test
+ public void testMultipleAssignments() throws DataModelParsingException {
+ assertEquals(ImmutableMap.of("n1", "v1", "n2", "v2", "n3", "v3"),
+ DataModelParser.parse("n1=v1\nn2=v2\nn3=v3", DateUtil.UTC));
+ assertEquals(ImmutableMap.of("n1", "v1", "n2", "v2", "n3", "v3"),
+ DataModelParser.parse(" n1 = v1 \r\n\r\n\tn2=v2\nn3 = v3\n\n", DateUtil.UTC));
+ assertEquals(ImmutableMap.of("n1", "=\n=v", "n2", "l1\nl2\n\nl3", "n3", "v3"),
+ DataModelParser.parse("n1==\n=v \n n2=l1\nl2\n\nl3\nn3=v3", DateUtil.UTC));
+ }
+
+ @Test
+ public void testStrings() throws DataModelParsingException {
+ assertEquals(
+ ImmutableMap.of(
+ "a", "C:\\x",
+ "b", "foo\nbar",
+ "c", "foo\t\"bar\"",
+ "d", "foo\t\"bar\"",
+ "e", "Foo's"
+ ),
+ DataModelParser.parse(
+ "a=C:\\x\n"
+ + "b=foo\nbar\n"
+ + "c=foo\t\"bar\"\n"
+ + "d=\"foo\\t\\\"bar\\\"\"\n"
+ + "e=\"Foo's\"",
+ DateUtil.UTC));
+ try {
+ DataModelParser.parse("a=\"foo", DateUtil.UTC);
+ fail();
+ } catch (DataModelParsingException e) {
+ assertThat(e.getMessage(), containsString("quoted"));
+ }
+ try {
+ DataModelParser.parse("a='foo'", DateUtil.UTC);
+ fail();
+ } catch (DataModelParsingException e) {
+ assertThat(e.getMessage(), containsString("quoted"));
+ }
+ try {
+ DataModelParser.parse("a=\"\\x\"", DateUtil.UTC);
+ fail();
+ } catch (DataModelParsingException e) {
+ assertThat(e.getMessage(), containsString("escape"));
+ }
+ }
+
+ @Test
+ public void testBasicNumbers() throws DataModelParsingException {
+ assertEquals(
+ ImmutableMap.of(
+ "a", BigDecimal.valueOf(1),
+ "b", BigDecimal.valueOf(1.5),
+ "c", BigDecimal.valueOf(-1.5),
+ "d", BigDecimal.valueOf(1.5),
+ "e", BigDecimal.valueOf(-0.125)
+ ),
+ DataModelParser.parse("a=1\nb=1.5\nc=-1.5\nd=+1.5\ne=-12.5e-2", DateUtil.UTC));
+ try {
+ DataModelParser.parse("a=1,5", DateUtil.UTC);
+ fail();
+ } catch (DataModelParsingException e) {
+ assertThat(e.getMessage(), containsString("Malformed number"));
+ assertThat(e.getMessage(), not(containsString("ISO")));
+ }
+ }
+
+ @Test
+ public void testSpecialNumbers() throws DataModelParsingException {
+ assertEquals(
+ ImmutableMap.of(
+ "a", Double.NaN,
+ "b", Double.POSITIVE_INFINITY,
+ "c", Double.NEGATIVE_INFINITY,
+ "d", Double.POSITIVE_INFINITY
+ ),
+ DataModelParser.parse("a=NaN\nb=Infinity\nc=-Infinity\nd=+Infinity", DateUtil.UTC));
+ }
+
+ @Test
+ public void testBooleans() throws DataModelParsingException {
+ assertEquals(ImmutableMap.of("a", true, "b", false), DataModelParser.parse("a=true\nb=false", DateUtil.UTC));
+ try {
+ DataModelParser.parse("a=True", DateUtil.UTC);
+ fail();
+ } catch (DataModelParsingException e) {
+ assertThat(e.getMessage(), containsString("true"));
+ }
+ }
+
+ @Test
+ public void testTemporals() throws DataModelParsingException {
+ final Map<String, Object> dm = DataModelParser.parse("a=2014-02-12T01:02:03Z\nb=2014-02-12\nc=01:02:03Z", DateUtil.UTC);
+
+ final GregorianCalendar cal = new GregorianCalendar(DateUtil.UTC);
+ cal.clear();
+
+ cal.set(2014, 1, 12, 1, 2, 3);
+ Timestamp a = new Timestamp(cal.getTimeInMillis());
+ assertThat(dm.get("a"), instanceOf(Timestamp.class));
+ assertEquals(dm.get("a"), a);
+
+ cal.set(2014, 1, 12, 0, 0, 0);
+ java.sql.Date b = new java.sql.Date(cal.getTimeInMillis());
+ assertThat(dm.get("b"), instanceOf(java.sql.Date.class));
+ assertEquals(dm.get("b"), b);
+
+ cal.set(1970, 0, 1, 1, 2, 3);
+ Time c = new Time(cal.getTimeInMillis());
+ assertThat(dm.get("c"), instanceOf(Time.class));
+ assertEquals(dm.get("c"), c);
+
+ try {
+ DataModelParser.parse("a=2012T123", DateUtil.UTC);
+ fail();
+ } catch (DataModelParsingException e) {
+ assertThat(e.getMessage(), containsString("ISO 8601 date-time"));
+ }
+ try {
+ DataModelParser.parse("a=2012-0102", DateUtil.UTC);
+ fail();
+ } catch (DataModelParsingException e) {
+ assertThat(e.getMessage(), containsString("ISO 8601 date"));
+ }
+ try {
+ DataModelParser.parse("a=25:00", DateUtil.UTC);
+ fail();
+ } catch (DataModelParsingException e) {
+ assertThat(e.getMessage(), containsString("ISO 8601 time"));
+ }
+ }
+
+ @Test
+ public void testMaps() throws DataModelParsingException {
+ final Object map = DataModelParser.parse(
+ "n = {\n"
+ + "\t\"a\": 1,\n"
+ + "\t\"b\": 2\n"
+ + "}",
+ DateUtil.UTC)
+ .get("n");
+ assertEquals(ImmutableMap.of("a", 1, "b", 2), map);
+ assertThat(map, instanceOf(LinkedHashMap.class));
+ try {
+ DataModelParser.parse("n={1:2}", DateUtil.UTC);
+ fail();
+ } catch (DataModelParsingException e) {
+ assertThat(e.getMessage(), containsString("JSON"));
+ }
+ }
+
+ @Test
+ public void testLists() throws DataModelParsingException {
+ final Object list = DataModelParser.parse("n=[1, 2]", DateUtil.UTC).get("n");
+ assertEquals(ImmutableList.of(1, 2), list);
+ assertThat(list, instanceOf(List.class));
+ try {
+ DataModelParser.parse("n=[", DateUtil.UTC);
+ fail();
+ } catch (DataModelParsingException e) {
+ assertThat(e.getMessage(), containsString("JSON"));
+ }
+ }
+
+ @Test
+ public void testXML() throws DataModelParsingException {
+ final Object doc = DataModelParser.parse("n=<e xmlns='foo:/bar' a='123'>text</e>", DateUtil.UTC).get("n");
+ assertThat(doc, instanceOf(Document.class));
+ final Node firstChild = ((Document) doc).getFirstChild();
+ assertEquals("e", firstChild.getNodeName());
+ assertEquals("foo:/bar", firstChild.getNamespaceURI());
+
+ try {
+ DataModelParser.parse("n=<ns:e />", DateUtil.UTC);
+ fail();
+ } catch (DataModelParsingException e) {
+ assertThat(e.getMessage(), containsString("XML"));
+ }
+ }
+
+ @Test
+ public void testNull() throws DataModelParsingException {
+ assertNull(DataModelParser.parse("n=null", DateUtil.UTC).get("n"));
+ try {
+ DataModelParser.parse("a=NULL", DateUtil.UTC);
+ fail();
+ } catch (DataModelParsingException e) {
+ assertThat(e.getMessage(), containsString("null"));
+ }
+ }
+
+ @Test
+ public void testEmptyValue() throws DataModelParsingException {
+ try {
+ DataModelParser.parse("n=", DateUtil.UTC);
+ fail();
+ } catch (DataModelParsingException e) {
+ assertThat(e.getMessage(), containsString("Empty"));
+ }
+
+ assertEquals("", DataModelParser.parse("n=\"\"", DateUtil.UTC).get("n"));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/test/java/org/apache/freemarker/onlinetester/util/LengthLimitedWriterTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/freemarker/onlinetester/util/LengthLimitedWriterTest.java b/src/test/java/org/apache/freemarker/onlinetester/util/LengthLimitedWriterTest.java
new file mode 100644
index 0000000..b072a96
--- /dev/null
+++ b/src/test/java/org/apache/freemarker/onlinetester/util/LengthLimitedWriterTest.java
@@ -0,0 +1,77 @@
+/*
+ * 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.util;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.StringWriter;
+
+import org.junit.Test;
+
+public class LengthLimitedWriterTest {
+
+ private StringWriter wrappedW = new StringWriter();
+ private LengthLimitedWriter w = new LengthLimitedWriter(wrappedW, 5);
+
+ @Test
+ public void testLimitNotExceeded() throws IOException {
+ w.write("123");
+ w.write("45");
+ }
+
+ @Test
+ public void testLimitExceededWithString() throws IOException {
+ w.write("123");
+ try {
+ w.write("456");
+ fail();
+ } catch (LengthLimitExceededException e) {
+ assertEquals("12345", wrappedW.toString());
+ }
+ }
+
+ @Test
+ public void testLimitExceededWithCharArray() throws IOException {
+ w.write(new char[] { '1', '2', '3' });
+ try {
+ w.write(new char[] { '4', '5', '6' });
+ fail();
+ } catch (LengthLimitExceededException e) {
+ assertEquals("12345", wrappedW.toString());
+ }
+ }
+
+ @Test
+ public void testLimitExceededWithChar() throws IOException {
+ w.write('1');
+ w.write('2');
+ w.write('3');
+ w.write('4');
+ w.write('5');
+ try {
+ w.write('6');
+ fail();
+ } catch (LengthLimitExceededException e) {
+ assertEquals("12345", wrappedW.toString());
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/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
new file mode 100644
index 0000000..b9572ba
--- /dev/null
+++ b/src/test/java/org/apache/freemarker/onlinetester/view/FreeMarkerOnlineViewTest.java
@@ -0,0 +1,69 @@
+/*
+ * 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.view;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Locale;
+import java.util.TimeZone;
+
+import org.junit.Test;
+
+import org.apache.freemarker.onlinetester.services.AllowedSettingValuesMaps;
+
+import freemarker.core.HTMLOutputFormat;
+
+
+public class FreeMarkerOnlineViewTest {
+
+ private static final String TEMPLATE = "Template";
+ private static final String DATA_MODEL = "DataModel";
+
+ @Test
+ public void testVieEmptyConstrucotr() {
+ 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);
+ }
+
+ @Test
+ public void testViewWhenAllOK() {
+ FreeMarkerOnlineView view = new FreeMarkerOnlineView();
+
+ view.setTemplate(TEMPLATE);
+ view.setDataModel(DATA_MODEL);
+ String outputFormatStr = HTMLOutputFormat.INSTANCE.getName();
+ view.setOutputFormat(outputFormatStr);
+ String localeStr = Locale.GERMAN.toString();
+ view.setLocale(localeStr);
+ String timeZoneStr = TimeZone.getTimeZone("GMT+01").getID();
+ view.setTimeZone(timeZoneStr);
+
+ assertEquals(view.getTemplate(), TEMPLATE);
+ assertEquals(view.getDataModel(), DATA_MODEL);
+ assertEquals(view.getOutputFormat(), outputFormatStr);
+ assertEquals(view.getLocale(), localeStr);
+ assertEquals(view.getTimeZone(), timeZoneStr);
+ }
+
+}
[4/5] incubator-freemarker-online-tester git commit: renamed the
package name to org/apache/freemarker/onlinetester
Posted by dd...@apache.org.
renamed the package name to org/apache/freemarker/onlinetester
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/2f0c0424
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/tree/2f0c0424
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/diff/2f0c0424
Branch: refs/heads/master
Commit: 2f0c0424bbfee360018b3d5e8d7688b588d4b176
Parents: 7b46afe
Author: Pradeep Murugesan <pr...@outlook.com>
Authored: Sun Apr 9 09:15:49 2017 +0200
Committer: Pradeep Murugesan <pr...@outlook.com>
Committed: Sun Apr 9 09:15:49 2017 +0200
----------------------------------------------------------------------
README.md | 36 +-
build.gradle | 4 +-
intellij.gradle | 2 +-
.../dropwizard/ApplicationStartup.java | 42 ---
.../healthchecks/MyProjectHealthCheck.java | 37 --
.../com/kenshoo/freemarker/model/ErrorCode.java | 25 --
.../kenshoo/freemarker/model/ErrorResponse.java | 30 --
.../freemarker/model/ExecuteRequest.java | 78 ----
.../freemarker/model/ExecuteResourceField.java | 57 ---
.../model/ExecuteResourceProblem.java | 53 ---
.../freemarker/model/ExecuteResponse.java | 63 ----
.../freemarker/model/SelectionOption.java | 88 -----
.../FreeMarkerOnlineExecuteResource.java | 220 -----------
.../resources/FreeMarkerOnlineResource.java | 63 ----
.../services/AllowedSettingValuesMaps.java | 115 ------
.../freemarker/services/FreeMarkerService.java | 364 -------------------
.../services/FreeMarkerServiceException.java | 38 --
.../services/FreeMarkerServiceResponse.java | 68 ----
.../freemarker/util/DataModelParser.java | 268 --------------
.../util/DataModelParsingException.java | 39 --
.../kenshoo/freemarker/util/ExceptionUtils.java | 53 ---
.../util/LengthLimitExceededException.java | 35 --
.../freemarker/util/LengthLimitedWriter.java | 87 -----
.../freemarker/view/FreeMarkerOnlineView.java | 157 --------
.../dropwizard/ApplicationStartup.java | 42 +++
.../healthchecks/MyProjectHealthCheck.java | 37 ++
.../onlinetester/model/ErrorCode.java | 25 ++
.../onlinetester/model/ErrorResponse.java | 30 ++
.../onlinetester/model/ExecuteRequest.java | 78 ++++
.../model/ExecuteResourceField.java | 57 +++
.../model/ExecuteResourceProblem.java | 53 +++
.../onlinetester/model/ExecuteResponse.java | 63 ++++
.../onlinetester/model/SelectionOption.java | 88 +++++
.../FreeMarkerOnlineExecuteResource.java | 220 +++++++++++
.../resources/FreeMarkerOnlineResource.java | 63 ++++
.../services/AllowedSettingValuesMaps.java | 115 ++++++
.../services/FreeMarkerService.java | 364 +++++++++++++++++++
.../services/FreeMarkerServiceException.java | 38 ++
.../services/FreeMarkerServiceResponse.java | 68 ++++
.../onlinetester/util/DataModelParser.java | 268 ++++++++++++++
.../util/DataModelParsingException.java | 39 ++
.../onlinetester/util/ExceptionUtils.java | 53 +++
.../util/LengthLimitExceededException.java | 35 ++
.../onlinetester/util/LengthLimitedWriter.java | 87 +++++
.../onlinetester/view/FreeMarkerOnlineView.java | 157 ++++++++
src/main/resources/spring/bootstrap-context.xml | 2 +-
.../platform/DropWizardServiceTest.java | 36 --
.../platform/YamlPropertiesPersister.java | 91 -----
.../FreeMarkerOnlineExecuteResourceTest.java | 159 --------
.../resources/FreeMarkerOnlineResourceTest.java | 70 ----
.../FreeMarkerServiceResponseBuilderTest.java | 61 ----
.../services/FreeMarkerServiceTest.java | 308 ----------------
.../freemarker/util/DataModelParserTest.java | 281 --------------
.../util/LengthLimitedWriterTest.java | 77 ----
.../view/FreeMarkerOnlineViewTest.java | 69 ----
.../platform/DropWizardServiceTest.java | 39 ++
.../platform/YamlPropertiesPersister.java | 91 +++++
.../FreeMarkerOnlineExecuteResourceTest.java | 159 ++++++++
.../resources/FreeMarkerOnlineResourceTest.java | 70 ++++
.../FreeMarkerServiceResponseBuilderTest.java | 61 ++++
.../services/FreeMarkerServiceTest.java | 308 ++++++++++++++++
.../onlinetester/util/DataModelParserTest.java | 281 ++++++++++++++
.../util/LengthLimitedWriterTest.java | 77 ++++
.../view/FreeMarkerOnlineViewTest.java | 69 ++++
64 files changed, 3157 insertions(+), 3154 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/README.md
----------------------------------------------------------------------
diff --git a/README.md b/README.md
index 38e5992..546e48e 100644
--- a/README.md
+++ b/README.md
@@ -1,22 +1,22 @@
```
-/*
- * 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.
- */
+
+ 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.
+
```
freemarker-online
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/build.gradle
----------------------------------------------------------------------
diff --git a/build.gradle b/build.gradle
index 66ee5fd..3e0405f 100644
--- a/build.gradle
+++ b/build.gradle
@@ -17,7 +17,7 @@
* under the License.
*/
-group = 'com.kenshoo.freemarker'
+group = 'org.apache.freemarker.onlinetester'
project.projectName = "freemarker-online"
def BUILD_NUMBER = project.hasProperty('BUILD_NUMBER') ? "$BUILD_NUMBER" : 'undef'
project.version = "0.1.$BUILD_NUMBER"
@@ -100,7 +100,7 @@ fatJar {
exclude "META-INF/*.DSA"
exclude "META-INF/*.RSA"
manifest {
- attributes 'Main-Class': 'com.kenshoo.freemarker.dropwizard.ApplicationStartup'
+ attributes 'Main-Class': 'org.apache.freemarker.onlinetester.dropwizard.ApplicationStartup'
attributes 'Implementation-Version': "$version"
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/intellij.gradle
----------------------------------------------------------------------
diff --git a/intellij.gradle b/intellij.gradle
index 8cf9da1..0853356 100644
--- a/intellij.gradle
+++ b/intellij.gradle
@@ -39,7 +39,7 @@ idea.workspace.iws.withXml { provider ->
list.appendNode('item', [index: '0', class: 'java.lang.String', itemvalue: 'MyProjectStartup'])
def Application = runManager.appendNode('configuration', [default: 'false', name: "${projectName}", type: 'Application', factoryName: 'Application'])
Application.appendNode('extension', [name: 'coverage', enabled: 'false', merge: 'false', runner: 'idea'])
- Application.appendNode('option', [name: 'MAIN_CLASS_NAME', value: "com.kenshoo.freemarker.dropwizard.ApplicationStartup"])
+ Application.appendNode('option', [name: 'MAIN_CLASS_NAME', value: "org.apache.freemarker.onlinetester.dropwizard.ApplicationStartup"])
Application.appendNode('option', [name: 'VM_PARAMETERS', value: ""])
Application.appendNode('option', [name: 'PROGRAM_PARAMETERS', value: "server src/main/resources/${projectName}.yml"])
Application.appendNode('option', [name: 'WORKING_DIRECTORY', value: "$projectDir"])
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/main/java/com/kenshoo/freemarker/dropwizard/ApplicationStartup.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/kenshoo/freemarker/dropwizard/ApplicationStartup.java b/src/main/java/com/kenshoo/freemarker/dropwizard/ApplicationStartup.java
deleted file mode 100644
index 9378e33..0000000
--- a/src/main/java/com/kenshoo/freemarker/dropwizard/ApplicationStartup.java
+++ /dev/null
@@ -1,42 +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 com.kenshoo.freemarker.dropwizard;
-
-import com.berico.fallwizard.SpringConfiguration;
-import com.berico.fallwizard.SpringService;
-import com.yammer.dropwizard.assets.AssetsBundle;
-import com.yammer.dropwizard.config.Bootstrap;
-import com.yammer.dropwizard.views.ViewBundle;
-
-public class ApplicationStartup extends SpringService<SpringConfiguration> {
-
- public static void main(String[] args) throws Exception {
- new ApplicationStartup().run(args);
- }
-
- @Override
- public void initialize(Bootstrap<SpringConfiguration> bootstrap) {
- bootstrap.setName("freemarker-online");
- bootstrap.addBundle(new ViewBundle());
- bootstrap.addBundle(new AssetsBundle("/assets/css", "/css"));
- bootstrap.addBundle(new AssetsBundle("/assets/js", "/js"));
- }
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/main/java/com/kenshoo/freemarker/healthchecks/MyProjectHealthCheck.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/kenshoo/freemarker/healthchecks/MyProjectHealthCheck.java b/src/main/java/com/kenshoo/freemarker/healthchecks/MyProjectHealthCheck.java
deleted file mode 100644
index 6f353dd..0000000
--- a/src/main/java/com/kenshoo/freemarker/healthchecks/MyProjectHealthCheck.java
+++ /dev/null
@@ -1,37 +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 com.kenshoo.freemarker.healthchecks;
-
-import com.yammer.metrics.core.HealthCheck;
-import org.springframework.stereotype.Component;
-
-@Component
-public class MyProjectHealthCheck extends HealthCheck {
-
- // note that this is due to the default spring CTR
- public MyProjectHealthCheck() {
- super("MyProjectHealthCheck");
- }
-
- @Override
- protected Result check() throws Exception {
- return Result.healthy(); // we're always healthy!
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/main/java/com/kenshoo/freemarker/model/ErrorCode.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/kenshoo/freemarker/model/ErrorCode.java b/src/main/java/com/kenshoo/freemarker/model/ErrorCode.java
deleted file mode 100644
index d26566c..0000000
--- a/src/main/java/com/kenshoo/freemarker/model/ErrorCode.java
+++ /dev/null
@@ -1,25 +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 com.kenshoo.freemarker.model;
-
-public enum ErrorCode {
- FREEMARKER_SERVICE_TIMEOUT
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/main/java/com/kenshoo/freemarker/model/ErrorResponse.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/kenshoo/freemarker/model/ErrorResponse.java b/src/main/java/com/kenshoo/freemarker/model/ErrorResponse.java
deleted file mode 100644
index 5af5314..0000000
--- a/src/main/java/com/kenshoo/freemarker/model/ErrorResponse.java
+++ /dev/null
@@ -1,30 +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 com.kenshoo.freemarker.model;
-
-public class ErrorResponse {
- private ErrorCode errorCode;
- private String errorDescription;
-
- public ErrorResponse(ErrorCode errorCode, String errorDescription) {
- this.errorCode = errorCode;
- this.errorDescription = errorDescription;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/main/java/com/kenshoo/freemarker/model/ExecuteRequest.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/kenshoo/freemarker/model/ExecuteRequest.java b/src/main/java/com/kenshoo/freemarker/model/ExecuteRequest.java
deleted file mode 100644
index 5797116..0000000
--- a/src/main/java/com/kenshoo/freemarker/model/ExecuteRequest.java
+++ /dev/null
@@ -1,78 +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 com.kenshoo.freemarker.model;
-
-
-public class ExecuteRequest {
- private String template;
- private String dataModel;
- private String outputFormat;
- private String locale;
- private String timeZone;
-
- public ExecuteRequest() {
- }
-
- public ExecuteRequest(String template, String dataModel) {
- this.template = template;
- this.dataModel = dataModel;
- }
-
- public String getDataModel() {
- return dataModel;
- }
-
- public void setDataModel(String dataModel) {
- this.dataModel = dataModel;
- }
-
- public String getTemplate() {
-
- return template;
- }
-
- public void setTemplate(String template) {
- this.template = template;
- }
-
- public String getOutputFormat() {
- return outputFormat;
- }
-
- public void setOutputFormat(String outputFormat) {
- this.outputFormat = outputFormat;
- }
-
- public String getLocale() {
- return locale;
- }
-
- public void setLocale(String locale) {
- this.locale = locale;
- }
-
- public String getTimeZone() {
- return timeZone;
- }
-
- public void setTimeZone(String timeZone) {
- this.timeZone = timeZone;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/main/java/com/kenshoo/freemarker/model/ExecuteResourceField.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/kenshoo/freemarker/model/ExecuteResourceField.java b/src/main/java/com/kenshoo/freemarker/model/ExecuteResourceField.java
deleted file mode 100644
index 815b1e8..0000000
--- a/src/main/java/com/kenshoo/freemarker/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 com.kenshoo.freemarker.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/2f0c0424/src/main/java/com/kenshoo/freemarker/model/ExecuteResourceProblem.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/kenshoo/freemarker/model/ExecuteResourceProblem.java b/src/main/java/com/kenshoo/freemarker/model/ExecuteResourceProblem.java
deleted file mode 100644
index 3acf216..0000000
--- a/src/main/java/com/kenshoo/freemarker/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 com.kenshoo.freemarker.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/2f0c0424/src/main/java/com/kenshoo/freemarker/model/ExecuteResponse.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/kenshoo/freemarker/model/ExecuteResponse.java b/src/main/java/com/kenshoo/freemarker/model/ExecuteResponse.java
deleted file mode 100644
index 8261858..0000000
--- a/src/main/java/com/kenshoo/freemarker/model/ExecuteResponse.java
+++ /dev/null
@@ -1,63 +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 com.kenshoo.freemarker.model;
-
-import java.util.List;
-
-public class ExecuteResponse {
- private String result;
- private List<ExecuteResourceProblem> problems;
- private boolean truncatedResult;
-
- public ExecuteResponse(String result, List<ExecuteResourceProblem> problems, boolean truncatedResult) {
- this.result = result;
- this.problems = problems;
- this.truncatedResult = truncatedResult;
- }
-
- public ExecuteResponse() {
-
- }
-
- public List<ExecuteResourceProblem> getProblems() {
- return problems;
- }
-
- public void setProblems(List<ExecuteResourceProblem> problems) {
- this.problems = problems;
- }
-
- public boolean isTruncatedResult() {
- return truncatedResult;
- }
-
- public void setTruncatedResult(boolean truncatedResult) {
- this.truncatedResult = truncatedResult;
- }
-
- public String getResult() {
- return result;
- }
-
- public void setResult(String result) {
- this.result = result;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/main/java/com/kenshoo/freemarker/model/SelectionOption.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/kenshoo/freemarker/model/SelectionOption.java b/src/main/java/com/kenshoo/freemarker/model/SelectionOption.java
deleted file mode 100644
index d68d419..0000000
--- a/src/main/java/com/kenshoo/freemarker/model/SelectionOption.java
+++ /dev/null
@@ -1,88 +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 com.kenshoo.freemarker.model;
-
-public class SelectionOption implements Comparable<SelectionOption> {
-
- private final String value;
- private final String label;
-
- public String getValue() {
- return value;
- }
-
- public String getLabel() {
- return label;
- }
-
- public SelectionOption(String value, String label) {
- this.value = value;
- this.label = label;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((label == null) ? 0 : label.hashCode());
- result = prime * result + ((value == null) ? 0 : value.hashCode());
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- SelectionOption other = (SelectionOption) obj;
- if (label == null) {
- if (other.label != null) {
- return false;
- }
- } else if (!label.equals(other.label)) {
- return false;
- }
- if (value == null) {
- if (other.value != null) {
- return false;
- }
- } else if (!value.equals(other.value)) {
- return false;
- }
- return true;
- }
-
- @Override
- public int compareTo(SelectionOption o) {
- int r = label.compareTo(o.label);
- if (r != 0) {
- return r;
- }
-
- return value.compareTo(o.value);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/main/java/com/kenshoo/freemarker/resources/FreeMarkerOnlineExecuteResource.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/kenshoo/freemarker/resources/FreeMarkerOnlineExecuteResource.java b/src/main/java/com/kenshoo/freemarker/resources/FreeMarkerOnlineExecuteResource.java
deleted file mode 100644
index d55f8a2..0000000
--- a/src/main/java/com/kenshoo/freemarker/resources/FreeMarkerOnlineExecuteResource.java
+++ /dev/null
@@ -1,220 +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 com.kenshoo.freemarker.resources;
-
-import java.text.MessageFormat;
-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;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-import com.kenshoo.freemarker.model.ErrorCode;
-import com.kenshoo.freemarker.model.ErrorResponse;
-import com.kenshoo.freemarker.model.ExecuteRequest;
-import com.kenshoo.freemarker.model.ExecuteResourceField;
-import com.kenshoo.freemarker.model.ExecuteResourceProblem;
-import com.kenshoo.freemarker.model.ExecuteResponse;
-import com.kenshoo.freemarker.services.AllowedSettingValuesMaps;
-import com.kenshoo.freemarker.services.FreeMarkerService;
-import com.kenshoo.freemarker.services.FreeMarkerServiceResponse;
-import com.kenshoo.freemarker.util.DataModelParser;
-import com.kenshoo.freemarker.util.DataModelParsingException;
-import com.kenshoo.freemarker.util.ExceptionUtils;
-
-import freemarker.core.OutputFormat;
-
-@Path("/api/execute")
-@Component
-public class FreeMarkerOnlineExecuteResource {
- private static final int MAX_TEMPLATE_INPUT_LENGTH = 10000;
-
- private static final int MAX_DATA_MODEL_INPUT_LENGTH = 10000;
-
- private static final String MAX_TEMPLATE_INPUT_LENGTH_EXCEEDED_ERROR_MESSAGE
- = "The template length has exceeded the {0} character limit set for this service.";
-
- 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
- = "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.";
-
- @Autowired
- private FreeMarkerService freeMarkerService;
-
- @POST
- @Produces(MediaType.APPLICATION_JSON)
- @Consumes(MediaType.APPLICATION_JSON)
- public Response formResult(
- ExecuteRequest req) {
- ExecuteResponse resp = new ExecuteResponse();
-
- if (StringUtils.isBlank(req.getTemplate()) && StringUtils.isBlank(req.getDataModel())) {
- return Response.status(400).entity("Empty Template & data").build();
- }
-
- List<ExecuteResourceProblem> problems = new ArrayList<ExecuteResourceProblem>();
-
- 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);
-
- if (!problems.isEmpty()) {
- resp.setProblems(problems);
- return buildFreeMarkerResponse(resp);
- }
-
- FreeMarkerServiceResponse freeMarkerServiceResponse;
- try {
- freeMarkerServiceResponse = freeMarkerService.calculateTemplateOutput(
- template, dataModel,
- outputFormat, locale, timeZone);
- } catch (RejectedExecutionException e) {
- String error = SERVICE_OVERBURDEN_ERROR_MESSAGE;
- return Response.serverError().entity(new ErrorResponse(ErrorCode.FREEMARKER_SERVICE_TIMEOUT, error)).build();
- }
- if (!freeMarkerServiceResponse.isSuccesful()){
- Throwable failureReason = freeMarkerServiceResponse.getFailureReason();
- String error = ExceptionUtils.getMessageWithCauses(failureReason);
- problems.add(new ExecuteResourceProblem(ExecuteResourceField.TEMPLATE, error));
- resp.setProblems(problems);
- return buildFreeMarkerResponse(resp);
- }
-
- String result = freeMarkerServiceResponse.getTemplateOutput();
- resp.setResult(result);
- resp.setTruncatedResult(freeMarkerServiceResponse.isTemplateOutputTruncated());
- return buildFreeMarkerResponse(resp);
- }
-
- private String getTemplate(ExecuteRequest req, List<ExecuteResourceProblem> problems) {
- String template = req.getTemplate();
-
- if (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));
- return null;
- }
-
- return template;
- }
-
- private Map<String, Object> getDataModel(ExecuteRequest req, List<ExecuteResourceProblem> 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));
- return null;
- }
-
- try {
- return DataModelParser.parse(dataModel, freeMarkerService.getFreeMarkerTimeZone());
- } catch (DataModelParsingException e) {
- problems.add(new ExecuteResourceProblem(ExecuteResourceField.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;
- }
-
- 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)));
- }
- return timeZone;
- }
-
- private Response buildFreeMarkerResponse(ExecuteResponse executeResponse){
- return Response.ok().entity(executeResponse).build();
- }
-
- private String decorateResultText(String resultText) {
- return DATA_MODEL_ERROR_MESSAGE_HEADING + "\n\n" + resultText + "\n\n" + DATA_MODEL_ERROR_MESSAGE_FOOTER;
- }
-
- private String formatMessage(String key, Object... params) {
- return new MessageFormat(key, Locale.US).format(params);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/main/java/com/kenshoo/freemarker/resources/FreeMarkerOnlineResource.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/kenshoo/freemarker/resources/FreeMarkerOnlineResource.java b/src/main/java/com/kenshoo/freemarker/resources/FreeMarkerOnlineResource.java
deleted file mode 100644
index e612c8c..0000000
--- a/src/main/java/com/kenshoo/freemarker/resources/FreeMarkerOnlineResource.java
+++ /dev/null
@@ -1,63 +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 com.kenshoo.freemarker.resources;
-
-import javax.ws.rs.Consumes;
-import javax.ws.rs.FormParam;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-
-import org.springframework.stereotype.Component;
-
-import com.kenshoo.freemarker.view.FreeMarkerOnlineView;
-
-@Path("/")
-@Component
-public class FreeMarkerOnlineResource {
-
- @GET
- @Produces(MediaType.TEXT_HTML)
- public FreeMarkerOnlineView blankForm() {
- return new FreeMarkerOnlineView();
- }
-
- @POST
- @Produces(MediaType.TEXT_HTML)
- @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
- public FreeMarkerOnlineView formResult(
- @FormParam("template") String template,
- @FormParam("dataModel") String dataModel,
- @FormParam("outputFormat") String outputFormat,
- @FormParam("locale") String locale,
- @FormParam("timeZone") String timeZone) {
- FreeMarkerOnlineView view = new FreeMarkerOnlineView();
- view.setTemplate(template);
- view.setDataModel(dataModel);
- view.setOutputFormat(outputFormat);
- view.setLocale(locale);
- view.setTimeZone(timeZone);
- view.setExecute(true);
- return view;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/main/java/com/kenshoo/freemarker/services/AllowedSettingValuesMaps.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/kenshoo/freemarker/services/AllowedSettingValuesMaps.java b/src/main/java/com/kenshoo/freemarker/services/AllowedSettingValuesMaps.java
deleted file mode 100644
index 8b98df0..0000000
--- a/src/main/java/com/kenshoo/freemarker/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 com.kenshoo.freemarker.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/2f0c0424/src/main/java/com/kenshoo/freemarker/services/FreeMarkerService.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/kenshoo/freemarker/services/FreeMarkerService.java b/src/main/java/com/kenshoo/freemarker/services/FreeMarkerService.java
deleted file mode 100644
index 84a96ea..0000000
--- a/src/main/java/com/kenshoo/freemarker/services/FreeMarkerService.java
+++ /dev/null
@@ -1,364 +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 com.kenshoo.freemarker.services;
-
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.text.MessageFormat;
-import java.util.Locale;
-import java.util.Objects;
-import java.util.TimeZone;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
-import java.util.concurrent.RejectedExecutionException;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-import javax.annotation.PostConstruct;
-
-import org.apache.commons.lang3.StringEscapeUtils;
-import org.eclipse.jetty.util.BlockingArrayQueue;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Service;
-
-import com.kenshoo.freemarker.util.LengthLimitExceededException;
-import com.kenshoo.freemarker.util.LengthLimitedWriter;
-
-import freemarker.core.FreeMarkerInternalsAccessor;
-import freemarker.core.OutputFormat;
-import freemarker.core.ParseException;
-import freemarker.core.TemplateClassResolver;
-import freemarker.core.TemplateConfiguration;
-import freemarker.template.Configuration;
-import freemarker.template.Template;
-import freemarker.template.TemplateException;
-import freemarker.template.TemplateExceptionHandler;
-
-@Service
-public class FreeMarkerService {
-
- private static final int DEFAULT_MAX_OUTPUT_LENGTH = 100000;
- private static final int DEFAULT_MAX_THREADS = Math.max(2,
- (int) Math.round(Runtime.getRuntime().availableProcessors() * 3.0 / 4));
- /** Not implemented yet, will need 2.3.22, even then a _CoreAPI call. */
- private static final long DEFAULT_MAX_TEMPLATE_EXECUTION_TIME = 2000;
- private static final int MIN_DEFAULT_MAX_QUEUE_LENGTH = 2;
- private static final int MAX_DEFAULT_MAX_QUEUE_LENGTH_MILLISECONDS = 30000;
- private static final long THREAD_KEEP_ALIVE_TIME = 4 * 1000;
- private static final long ABORTION_LOOP_TIME_LIMIT = 5000;
- private static final long ABORTION_LOOP_INTERRUPTION_DISTANCE = 50;
-
- private static final String MAX_OUTPUT_LENGTH_EXCEEDED_TERMINATION = "\n----------\n"
- + "Aborted template processing, as the output length has exceeded the {0} character limit set for "
- + "this service.";
-
- private static final Logger logger = LoggerFactory.getLogger(FreeMarkerService.class);
-
- private final Configuration freeMarkerConfig;
-
- private ExecutorService templateExecutor;
-
- private int maxOutputLength = DEFAULT_MAX_OUTPUT_LENGTH;
-
- private int maxThreads = DEFAULT_MAX_THREADS;
- private Integer maxQueueLength;
- private long maxTemplateExecutionTime = DEFAULT_MAX_TEMPLATE_EXECUTION_TIME;
-
- public FreeMarkerService() {
- freeMarkerConfig = new Configuration(Configuration.getVersion());
- freeMarkerConfig.setNewBuiltinClassResolver(TemplateClassResolver.ALLOWS_NOTHING_RESOLVER);
- freeMarkerConfig.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
- freeMarkerConfig.setLogTemplateExceptions(false);
- freeMarkerConfig.setLocale(AllowedSettingValuesMaps.DEFAULT_LOCALE);
- freeMarkerConfig.setTimeZone(AllowedSettingValuesMaps.DEFAULT_TIME_ZONE);
- freeMarkerConfig.setOutputFormat(AllowedSettingValuesMaps.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
- * this is a service for trying out the template language, so such errors are part of the normal operation.
- *
- * @throws RejectedExecutionException
- * If the service is overburden and thus doing the calculation was rejected.
- * @throws FreeMarkerServiceException
- * If the calculation fails from a reason that's not a mistake in the template and doesn't fit the
- * meaning of {@link RejectedExecutionException} either.
- */
- public FreeMarkerServiceResponse calculateTemplateOutput(
- String templateSourceCode, Object dataModel, OutputFormat outputFormat, Locale locale, TimeZone timeZone)
- throws RejectedExecutionException {
- Objects.requireNonNull(templateExecutor, "templateExecutor was null - was postConstruct ever called?");
-
- final CalculateTemplateOutput task = new CalculateTemplateOutput(
- templateSourceCode, dataModel, outputFormat, locale, timeZone);
- Future<FreeMarkerServiceResponse> future = templateExecutor.submit(task);
-
- synchronized (task) {
- while (!task.isTemplateExecutionStarted() && !task.isTaskEnded() && !future.isDone()) {
- try {
- task.wait(50); // Timeout is needed to periodically check future.isDone()
- } catch (InterruptedException e) {
- throw new FreeMarkerServiceException("Template execution task was interrupted.", e);
- }
- }
- }
-
- try {
- return future.get(maxTemplateExecutionTime, TimeUnit.MILLISECONDS);
- } catch (ExecutionException e) {
- throw new FreeMarkerServiceException("Template execution task unexpectedly failed", e.getCause());
- } catch (InterruptedException e) {
- throw new FreeMarkerServiceException("Template execution task was interrupted.", e);
- } catch (TimeoutException e) {
- // Exactly one interruption should be enough, and it should abort template processing pretty much
- // immediately. But to be on the safe side we will interrupt in a loop, with a timeout.
- final long abortionLoopStartTime = System.currentTimeMillis();
- long timeLeft = ABORTION_LOOP_TIME_LIMIT;
- boolean templateExecutionEnded = false;
- do {
- synchronized (task) {
- Thread templateExecutorThread = task.getTemplateExecutorThread();
- if (templateExecutorThread == null) {
- templateExecutionEnded = true;
- } else {
- FreeMarkerInternalsAccessor.interruptTemplateProcessing(templateExecutorThread);
- logger.debug("Trying to interrupt overly long template processing (" + timeLeft + " ms left).");
- }
- }
- if (!templateExecutionEnded) {
- try {
- timeLeft = ABORTION_LOOP_TIME_LIMIT - (System.currentTimeMillis() - abortionLoopStartTime);
- if (timeLeft > 0) {
- Thread.sleep(ABORTION_LOOP_INTERRUPTION_DISTANCE);
- }
- } catch (InterruptedException eInt) {
- logger.error("Template execution abortion loop was interrupted", eInt);
- timeLeft = 0;
- }
- }
- } while (!templateExecutionEnded && timeLeft > 0);
-
- if (templateExecutionEnded) {
- 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", e);
- }
- } 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));
- }
- }
- }
-
- public int getMaxOutputLength() {
- return maxOutputLength;
- }
-
- public void setMaxOutputLength(int maxOutputLength) {
- this.maxOutputLength = maxOutputLength;
- }
-
- public int getMaxThreads() {
- return maxThreads;
- }
-
- public void setMaxThreads(int maxThreads) {
- this.maxThreads = maxThreads;
- }
-
- public int getMaxQueueLength() {
- return maxQueueLength;
- }
-
- public void setMaxQueueLength(int maxQueueLength) {
- this.maxQueueLength = maxQueueLength;
- }
-
- public long getMaxTemplateExecutionTime() {
- return maxTemplateExecutionTime;
- }
-
- public void setMaxTemplateExecutionTime(long maxTemplateExecutionTime) {
- this.maxTemplateExecutionTime = maxTemplateExecutionTime;
- }
-
- /**
- * Returns the time zone used by the FreeMarker templates.
- */
- public TimeZone getFreeMarkerTimeZone() {
- return freeMarkerConfig.getTimeZone();
- }
-
- private FreeMarkerServiceResponse createFailureResponse(Throwable e) {
- logger.debug("The template had error(s)", e);
- return new FreeMarkerServiceResponse.Builder().buildForFailure(e);
- }
-
- @PostConstruct
- public void postConstruct() {
- int actualMaxQueueLength = maxQueueLength != null
- ? maxQueueLength
- : Math.max(
- MIN_DEFAULT_MAX_QUEUE_LENGTH,
- (int) (MAX_DEFAULT_MAX_QUEUE_LENGTH_MILLISECONDS / maxTemplateExecutionTime));
- ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
- maxThreads, maxThreads,
- THREAD_KEEP_ALIVE_TIME, TimeUnit.MILLISECONDS,
- new BlockingArrayQueue<Runnable>(actualMaxQueueLength));
- threadPoolExecutor.allowCoreThreadTimeOut(true);
- templateExecutor = threadPoolExecutor;
- }
-
- private class CalculateTemplateOutput implements Callable<FreeMarkerServiceResponse> {
-
- 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;
- }
-
- @Override
- public FreeMarkerServiceResponse call() throws Exception {
- try {
- Template template;
- try {
- TemplateConfiguration tCfg = new TemplateConfiguration();
- tCfg.setParentConfiguration(freeMarkerConfig);
- if (outputFormat != null) {
- tCfg.setOutputFormat(outputFormat);
- }
- if (locale != null) {
- tCfg.setLocale(locale);
- }
- if (timeZone != null) {
- tCfg.setTimeZone(timeZone);
- }
-
- template = new Template(null, null,
- new StringReader(templateSourceCode), freeMarkerConfig, tCfg, null);
-
- tCfg.apply(template);
- } catch (ParseException e) {
- // Expected (part of normal operation)
- return createFailureResponse(e);
- } catch (Exception e) {
- // Not expected
- throw new FreeMarkerServiceException("Unexpected exception during template parsing", e);
- }
-
- FreeMarkerInternalsAccessor.makeTemplateInterruptable(template);
-
- boolean resultTruncated;
- StringWriter writer = new StringWriter();
- try {
- synchronized (this) {
- templateExecutorThread = Thread.currentThread();
- templateExecutionStarted = true;
- notifyAll();
- }
- try {
- template.process(dataModel, new LengthLimitedWriter(writer, maxOutputLength));
- } finally {
- synchronized (this) {
- templateExecutorThread = null;
- FreeMarkerInternalsAccessor.clearAnyPendingTemplateProcessingInterruption();
- }
- }
- resultTruncated = false;
- } 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)
- .format(new Object[] { maxOutputLength }));
- // Falls through
- } catch (TemplateException e) {
- // Expected (part of normal operation)
- return createFailureResponse(e);
- } catch (Exception e) {
- if (FreeMarkerInternalsAccessor.isTemplateProcessingInterruptedException(e)) {
- return new FreeMarkerServiceResponse.Builder().buildForFailure(new TimeoutException(
- "Template processing was aborted for exceeding the " + getMaxTemplateExecutionTime()
- + " ms time limit set for this online service. This is usually because you have "
- + "a very long running #list (or other kind of loop) in your template."));
- }
- // Not expected
- throw new FreeMarkerServiceException("Unexpected exception during template evaluation", e);
- }
-
- return new FreeMarkerServiceResponse.Builder().buildForSuccess(writer.toString(), resultTruncated);
- } finally {
- synchronized (this) {
- taskEnded = true;
- notifyAll();
- }
- }
- }
-
- private synchronized boolean isTemplateExecutionStarted() {
- return templateExecutionStarted;
- }
-
- private synchronized boolean isTaskEnded() {
- return taskEnded;
- }
-
- /**
- * @return non-{@code null} after the task execution has actually started, but before it has finished.
- */
- private synchronized Thread getTemplateExecutorThread() {
- return templateExecutorThread;
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/main/java/com/kenshoo/freemarker/services/FreeMarkerServiceException.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/kenshoo/freemarker/services/FreeMarkerServiceException.java b/src/main/java/com/kenshoo/freemarker/services/FreeMarkerServiceException.java
deleted file mode 100644
index ae7970d..0000000
--- a/src/main/java/com/kenshoo/freemarker/services/FreeMarkerServiceException.java
+++ /dev/null
@@ -1,38 +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 com.kenshoo.freemarker.services;
-
-/**
- * When {@link FreeMarkerService} fails on an unexpected way (non-user error).
- */
-public class FreeMarkerServiceException extends RuntimeException {
-
- private static final long serialVersionUID = 1L;
-
- public FreeMarkerServiceException(String message) {
- super(message);
- // TODO Auto-generated constructor stub
- }
-
- public FreeMarkerServiceException(String message, Throwable cause) {
- super(message, cause);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/main/java/com/kenshoo/freemarker/services/FreeMarkerServiceResponse.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/kenshoo/freemarker/services/FreeMarkerServiceResponse.java b/src/main/java/com/kenshoo/freemarker/services/FreeMarkerServiceResponse.java
deleted file mode 100644
index 8aa37ec..0000000
--- a/src/main/java/com/kenshoo/freemarker/services/FreeMarkerServiceResponse.java
+++ /dev/null
@@ -1,68 +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 com.kenshoo.freemarker.services;
-
-public class FreeMarkerServiceResponse {
-
- private final String templateOutput;
- private final boolean templateOutputTruncated;
- private final Throwable failureReason;
-
- FreeMarkerServiceResponse(String templateOutput, boolean templateOutputTruncated) {
- this.templateOutput = templateOutput;
- this.templateOutputTruncated = templateOutputTruncated;
- this.failureReason = null;
- }
-
- FreeMarkerServiceResponse(Throwable failureReason) {
- this.templateOutput = null;
- this.templateOutputTruncated = false;
- this.failureReason = failureReason;
- }
-
- public String getTemplateOutput() {
- return templateOutput;
- }
-
- public boolean isTemplateOutputTruncated() {
- return templateOutputTruncated;
- }
-
- public boolean isSuccesful() {
- return failureReason == null;
- }
-
- public Throwable getFailureReason() {
- return failureReason;
- }
-
- public static class Builder {
-
- public FreeMarkerServiceResponse buildForSuccess(String result, boolean resultTruncated){
- return new FreeMarkerServiceResponse(result, resultTruncated);
- }
-
- public FreeMarkerServiceResponse buildForFailure(Throwable failureReason){
- return new FreeMarkerServiceResponse(failureReason);
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/main/java/com/kenshoo/freemarker/util/DataModelParser.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/kenshoo/freemarker/util/DataModelParser.java b/src/main/java/com/kenshoo/freemarker/util/DataModelParser.java
deleted file mode 100644
index ada847d..0000000
--- a/src/main/java/com/kenshoo/freemarker/util/DataModelParser.java
+++ /dev/null
@@ -1,268 +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 com.kenshoo.freemarker.util;
-
-import java.io.IOException;
-import java.io.StringReader;
-import java.math.BigDecimal;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.TimeZone;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.xml.parsers.DocumentBuilder;
-
-import org.springframework.util.StringUtils;
-import org.w3c.dom.Document;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-import freemarker.ext.dom.NodeModel;
-import freemarker.template.utility.DateUtil;
-import freemarker.template.utility.DateUtil.CalendarFieldsToDateConverter;
-import freemarker.template.utility.DateUtil.DateParseException;
-import freemarker.template.utility.DateUtil.TrivialCalendarFieldsToDateConverter;
-
-/**
- * Parses the text that the user enters into the data model input field.
- */
-public final class DataModelParser {
-
- private static final String KEYWORD_NEGATIVE_INFINITY = "-Infinity";
-
- private static final String KEYWORD_POSITIVE_INFINITY = "+Infinity";
-
- private static final String KEYWORD_INFINITY = "Infinity";
-
- private static final String KEYWORD_TRUE = "true";
-
- private static final String KEYWORD_FALSE = "false";
-
- private static final String KEYWORD_NULL = "null";
-
- private static final String KEYWORD_NAN = "NaN";
-
- /** Matches a line starting like "someVariable=". */
- private static final Pattern ASSIGNMENT_START = Pattern.compile(
- "^\\s*"
- + "(\\p{L}[\\p{L}\\p{N}\\.:\\-_$@]*)" // name
- + "[ \t]*=\\s*",
- Pattern.MULTILINE);
-
- /** Matches a value that starts like a number, or probably meant to be number at least. */
- private static final Pattern NUMBER_LIKE = Pattern.compile("[+-]?[\\.,]?[0-9].*", Pattern.DOTALL);
-
- private static final ObjectMapper JSON_MAPPER = new ObjectMapper();
-
- private DataModelParser() {
- // Not meant to be instantiated
- }
-
- public static Map<String, Object> parse(String src, TimeZone timeZone) throws DataModelParsingException {
- if (!StringUtils.hasText(src)) {
- return Collections.emptyMap();
- }
-
- Map<String, Object> dataModel = new LinkedHashMap<>();
-
- String lastName = null;
- int lastAssignmentStartEnd = 0;
- final Matcher assignmentStart = ASSIGNMENT_START.matcher(src);
- findAssignments: while (true) {
- boolean hasNextAssignment = assignmentStart.find(lastAssignmentStartEnd);
-
- if (lastName != null) {
- String value = src.substring(
- lastAssignmentStartEnd, hasNextAssignment ? assignmentStart.start() : src.length())
- .trim();
- final Object parsedValue;
- try {
- parsedValue = parseValue(value, timeZone);
- } catch (DataModelParsingException e) {
- throw new DataModelParsingException(
- "Failed to parse the value of \"" + lastName + "\":\n" + e.getMessage(), e.getCause());
- }
- dataModel.put(lastName, parsedValue);
- }
-
- if (lastName == null && (!hasNextAssignment || assignmentStart.start() != 0)) {
- throw new DataModelParsingException(
- "The data model specification must start with an assignment (name=value).");
- }
-
- if (!hasNextAssignment) {
- break findAssignments;
- }
-
- lastName = assignmentStart.group(1).trim();
- lastAssignmentStartEnd = assignmentStart.end();
- }
-
- return dataModel;
- }
-
- private static Object parseValue(String value, TimeZone timeZone) throws DataModelParsingException {
- // Note: Because we fall back to interpret the input as a literal string value when it doesn't look like
- // anything else (like a number, boolean, etc.), it's important to avoid misunderstandings, and throw exception
- // in suspicious situations. The user can always quote the string value if we are "too smart". But he will
- // be confused about the rules of FreeMarker if what he believes to be a non-string is misinterpreted by this
- // parser as a string. Getting sometimes an error and then quoting the string is better than that.
-
- if (value.endsWith(";")) { // Tolerate this habit of Java and JavaScript programmers
- value = value.substring(value.length() - 1).trim();
- }
-
- if (NUMBER_LIKE.matcher(value).matches()) {
- try {
- return new BigDecimal(value);
- } catch (NumberFormatException e) {
- // Maybe it's a ISO 8601 Date/time/datetime
- CalendarFieldsToDateConverter calToDateConverter = new TrivialCalendarFieldsToDateConverter();
-
- DateParseException attemptedTemportalPExc = null;
- String attemptedTemporalType = null;
- final int dashIdx = value.indexOf('-');
- final int colonIdx = value.indexOf(':');
- if (value.indexOf('T') > 1 || (dashIdx > 1 && colonIdx > dashIdx)) {
- try {
- return new Timestamp(
- DateUtil.parseISO8601DateTime(value, timeZone, calToDateConverter).getTime());
- } catch (DateParseException pExc) {
- attemptedTemporalType = "date-time";
- attemptedTemportalPExc = pExc;
- }
- } else if (dashIdx > 1) {
- try {
- return new java.sql.Date(
- DateUtil.parseISO8601Date(value, timeZone, calToDateConverter).getTime());
- } catch (DateParseException pExc) {
- attemptedTemporalType = "date";
- attemptedTemportalPExc = pExc;
- }
- } else if (colonIdx > 1) {
- try {
- return new Time(
- DateUtil.parseISO8601Time(value, timeZone, calToDateConverter).getTime());
- } catch (DateParseException pExc) {
- attemptedTemporalType = "time";
- attemptedTemportalPExc = pExc;
- }
- }
- if (attemptedTemportalPExc == null) {
- throw new DataModelParsingException("Malformed number: " + value, e);
- } else {
- throw new DataModelParsingException(
- "Malformed ISO 8601 " + attemptedTemporalType + " (or malformed number): " +
- attemptedTemportalPExc.getMessage(), e.getCause());
- }
- }
- } else if (value.startsWith("\"")) {
- try {
- return JSON_MAPPER.readValue(value, String.class);
- } catch (IOException e) {
- throw new DataModelParsingException(
- "Malformed quoted string (using JSON syntax): " + getMessageWithoutLocation(e),
- e);
- }
- } else if (value.startsWith("\'")) {
- throw new DataModelParsingException(
- "Malformed quoted string (using JSON syntax): Use \" character for quotation, not \' character.");
- } else if (value.startsWith("[")) {
- try {
- return JSON_MAPPER.readValue(value, List.class);
- } catch (IOException e) {
- throw new DataModelParsingException(
- "Malformed list (using JSON syntax): " + getMessageWithoutLocation(e),
- e);
- }
- } else if (value.startsWith("{")) {
- try {
- return JSON_MAPPER.readValue(value, LinkedHashMap.class);
- } catch (IOException e) {
- throw new DataModelParsingException(
- "Malformed list (using JSON syntax): " + getMessageWithoutLocation(e),
- e);
- }
- } else if (value.startsWith("<")) {
- try {
- DocumentBuilder builder = NodeModel.getDocumentBuilderFactory().newDocumentBuilder();
- ErrorHandler errorHandler = NodeModel.getErrorHandler();
- if (errorHandler != null) builder.setErrorHandler(errorHandler);
- final Document doc = builder.parse(new InputSource(new StringReader(value)));
- NodeModel.simplify(doc);
- return doc;
- } catch (SAXException e) {
- final String saxMsg = e.getMessage();
- throw new DataModelParsingException("Malformed XML: " + (saxMsg != null ? saxMsg : e), e);
- } catch (Exception e) {
- throw new DataModelParsingException("XML parsing has failed with internal error: " + e, e);
- }
- } else if (value.equalsIgnoreCase(KEYWORD_TRUE)) {
- checkKeywordCase(value, KEYWORD_TRUE);
- return Boolean.TRUE;
- } else if (value.equalsIgnoreCase(KEYWORD_FALSE)) {
- checkKeywordCase(value, KEYWORD_FALSE);
- return Boolean.FALSE;
- } else if (value.equalsIgnoreCase(KEYWORD_NULL)) {
- checkKeywordCase(value, KEYWORD_NULL);
- return null;
- } else if (value.equalsIgnoreCase(KEYWORD_NAN)) {
- checkKeywordCase(value, KEYWORD_NAN);
- return Double.NaN;
- } else if (value.equalsIgnoreCase(KEYWORD_INFINITY)) {
- checkKeywordCase(value, KEYWORD_INFINITY);
- return Double.POSITIVE_INFINITY;
- } else if (value.equalsIgnoreCase(KEYWORD_POSITIVE_INFINITY)) {
- checkKeywordCase(value, KEYWORD_POSITIVE_INFINITY);
- return Double.POSITIVE_INFINITY;
- } else if (value.equalsIgnoreCase(KEYWORD_NEGATIVE_INFINITY)) {
- checkKeywordCase(value, KEYWORD_NEGATIVE_INFINITY);
- return Double.NEGATIVE_INFINITY;
- } else if (value.length() == 0) {
- throw new DataModelParsingException(
- "Empty value. (If you indeed wanted a 0 length string, quote it, like \"\".)");
- } else {
- return value;
- }
- }
-
- private static String getMessageWithoutLocation(IOException e) {
- return e instanceof JsonProcessingException
- ? ((JsonProcessingException) e).getOriginalMessage()
- : e.getMessage();
- }
-
- private static void checkKeywordCase(String inputKeyword, String correctKeyword) throws DataModelParsingException {
- if (!correctKeyword.equals(inputKeyword)) {
- throw new DataModelParsingException("Keywords are case sensitive; the correct form is: "
- + correctKeyword);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/main/java/com/kenshoo/freemarker/util/DataModelParsingException.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/kenshoo/freemarker/util/DataModelParsingException.java b/src/main/java/com/kenshoo/freemarker/util/DataModelParsingException.java
deleted file mode 100644
index 926e10b..0000000
--- a/src/main/java/com/kenshoo/freemarker/util/DataModelParsingException.java
+++ /dev/null
@@ -1,39 +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 com.kenshoo.freemarker.util;
-
-import java.util.TimeZone;
-
-/**
- * Thrown by {@link DataModelParser#parse(String, TimeZone)}.
- */
-public class DataModelParsingException extends Exception {
-
- private static final long serialVersionUID = 1L;
-
- public DataModelParsingException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public DataModelParsingException(String message) {
- super(message);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/main/java/com/kenshoo/freemarker/util/ExceptionUtils.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/kenshoo/freemarker/util/ExceptionUtils.java b/src/main/java/com/kenshoo/freemarker/util/ExceptionUtils.java
deleted file mode 100644
index 5c7548b..0000000
--- a/src/main/java/com/kenshoo/freemarker/util/ExceptionUtils.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 com.kenshoo.freemarker.util;
-
-import freemarker.core.ParseException;
-import freemarker.template.TemplateException;
-
-public final class ExceptionUtils {
-
- private ExceptionUtils() {
- // Not meant to be instantiated
- }
-
- /**
- * The error message (and sometimes also the class), and then the same with the cause exception, and so on. Doesn't
- * contain the stack trace or other location information.
- */
- public static String getMessageWithCauses(final Throwable exc) {
- StringBuilder sb = new StringBuilder();
-
- Throwable curExc = exc;
- while (curExc != null) {
- if (curExc != exc) {
- sb.append("\n\nCaused by:\n");
- }
- String msg = curExc.getMessage();
- if (msg == null || !(curExc instanceof TemplateException || curExc instanceof ParseException)) {
- sb.append(curExc.getClass().getName()).append(": ");
- }
- sb.append(msg);
- curExc = curExc.getCause();
- }
- return sb.toString();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/main/java/com/kenshoo/freemarker/util/LengthLimitExceededException.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/kenshoo/freemarker/util/LengthLimitExceededException.java b/src/main/java/com/kenshoo/freemarker/util/LengthLimitExceededException.java
deleted file mode 100644
index df25144..0000000
--- a/src/main/java/com/kenshoo/freemarker/util/LengthLimitExceededException.java
+++ /dev/null
@@ -1,35 +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 com.kenshoo.freemarker.util;
-
-import java.io.IOException;
-
-/**
- * Thrown by {@link LengthLimitedWriter}.
- */
-public class LengthLimitExceededException extends IOException {
-
- private static final long serialVersionUID = 1L;
-
- public LengthLimitExceededException() {
- super("The outout String length limit of the Writer was exceeded.");
- }
-
-}
[5/5] incubator-freemarker-online-tester git commit: Renamed the
package to org.apache.freemarker.onlinetester
Posted by dd...@apache.org.
Renamed the package to org.apache.freemarker.onlinetester
Merge commit 'refs/pull/6/head' of https://github.com/apache/incubator-freemarker-online-tester
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/808bd536
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/tree/808bd536
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/diff/808bd536
Branch: refs/heads/master
Commit: 808bd536597f47f2a3c85e5e77f1129eda218df6
Parents: 7b46afe 2f0c042
Author: ddekany <dd...@apache.org>
Authored: Sun Apr 9 10:14:19 2017 +0200
Committer: ddekany <dd...@apache.org>
Committed: Sun Apr 9 10:15:21 2017 +0200
----------------------------------------------------------------------
README.md | 36 +-
build.gradle | 4 +-
intellij.gradle | 2 +-
.../dropwizard/ApplicationStartup.java | 42 ---
.../healthchecks/MyProjectHealthCheck.java | 37 --
.../com/kenshoo/freemarker/model/ErrorCode.java | 25 --
.../kenshoo/freemarker/model/ErrorResponse.java | 30 --
.../freemarker/model/ExecuteRequest.java | 78 ----
.../freemarker/model/ExecuteResourceField.java | 57 ---
.../model/ExecuteResourceProblem.java | 53 ---
.../freemarker/model/ExecuteResponse.java | 63 ----
.../freemarker/model/SelectionOption.java | 88 -----
.../FreeMarkerOnlineExecuteResource.java | 220 -----------
.../resources/FreeMarkerOnlineResource.java | 63 ----
.../services/AllowedSettingValuesMaps.java | 115 ------
.../freemarker/services/FreeMarkerService.java | 364 -------------------
.../services/FreeMarkerServiceException.java | 38 --
.../services/FreeMarkerServiceResponse.java | 68 ----
.../freemarker/util/DataModelParser.java | 268 --------------
.../util/DataModelParsingException.java | 39 --
.../kenshoo/freemarker/util/ExceptionUtils.java | 53 ---
.../util/LengthLimitExceededException.java | 35 --
.../freemarker/util/LengthLimitedWriter.java | 87 -----
.../freemarker/view/FreeMarkerOnlineView.java | 157 --------
.../dropwizard/ApplicationStartup.java | 42 +++
.../healthchecks/MyProjectHealthCheck.java | 37 ++
.../onlinetester/model/ErrorCode.java | 25 ++
.../onlinetester/model/ErrorResponse.java | 30 ++
.../onlinetester/model/ExecuteRequest.java | 78 ++++
.../model/ExecuteResourceField.java | 57 +++
.../model/ExecuteResourceProblem.java | 53 +++
.../onlinetester/model/ExecuteResponse.java | 63 ++++
.../onlinetester/model/SelectionOption.java | 88 +++++
.../FreeMarkerOnlineExecuteResource.java | 220 +++++++++++
.../resources/FreeMarkerOnlineResource.java | 63 ++++
.../services/AllowedSettingValuesMaps.java | 115 ++++++
.../services/FreeMarkerService.java | 364 +++++++++++++++++++
.../services/FreeMarkerServiceException.java | 38 ++
.../services/FreeMarkerServiceResponse.java | 68 ++++
.../onlinetester/util/DataModelParser.java | 268 ++++++++++++++
.../util/DataModelParsingException.java | 39 ++
.../onlinetester/util/ExceptionUtils.java | 53 +++
.../util/LengthLimitExceededException.java | 35 ++
.../onlinetester/util/LengthLimitedWriter.java | 87 +++++
.../onlinetester/view/FreeMarkerOnlineView.java | 157 ++++++++
src/main/resources/spring/bootstrap-context.xml | 2 +-
.../platform/DropWizardServiceTest.java | 36 --
.../platform/YamlPropertiesPersister.java | 91 -----
.../FreeMarkerOnlineExecuteResourceTest.java | 159 --------
.../resources/FreeMarkerOnlineResourceTest.java | 70 ----
.../FreeMarkerServiceResponseBuilderTest.java | 61 ----
.../services/FreeMarkerServiceTest.java | 308 ----------------
.../freemarker/util/DataModelParserTest.java | 281 --------------
.../util/LengthLimitedWriterTest.java | 77 ----
.../view/FreeMarkerOnlineViewTest.java | 69 ----
.../platform/DropWizardServiceTest.java | 39 ++
.../platform/YamlPropertiesPersister.java | 91 +++++
.../FreeMarkerOnlineExecuteResourceTest.java | 159 ++++++++
.../resources/FreeMarkerOnlineResourceTest.java | 70 ++++
.../FreeMarkerServiceResponseBuilderTest.java | 61 ++++
.../services/FreeMarkerServiceTest.java | 308 ++++++++++++++++
.../onlinetester/util/DataModelParserTest.java | 281 ++++++++++++++
.../util/LengthLimitedWriterTest.java | 77 ++++
.../view/FreeMarkerOnlineViewTest.java | 69 ++++
64 files changed, 3157 insertions(+), 3154 deletions(-)
----------------------------------------------------------------------
[3/5] incubator-freemarker-online-tester git commit: renamed the
package name to org/apache/freemarker/onlinetester
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/main/java/com/kenshoo/freemarker/util/LengthLimitedWriter.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/kenshoo/freemarker/util/LengthLimitedWriter.java b/src/main/java/com/kenshoo/freemarker/util/LengthLimitedWriter.java
deleted file mode 100644
index abf3edc..0000000
--- a/src/main/java/com/kenshoo/freemarker/util/LengthLimitedWriter.java
+++ /dev/null
@@ -1,87 +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 com.kenshoo.freemarker.util;
-
-import java.io.FilterWriter;
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.Writer;
-
-/**
- * A {@link StringWriter} that limits its buffer size, and throws {@link LengthLimitExceededException} when that's
- * exceeded.
- */
-public class LengthLimitedWriter extends FilterWriter {
-
- private int lengthLeft;
-
- public LengthLimitedWriter(Writer writer, int lengthLimit) {
- super(writer);
- this.lengthLeft = lengthLimit;
- }
-
- @Override
- public void write(int c) throws IOException {
- if (lengthLeft < 1) {
- throw new LengthLimitExceededException();
- }
-
- super.write(c);
-
- lengthLeft--;
- }
-
- @Override
- public void write(char[] cbuf, int off, int len) throws IOException {
- final boolean lengthExceeded;
- if (lengthLeft < len) {
- len = lengthLeft;
- lengthExceeded = true;
- } else {
- lengthExceeded = false;
- }
-
- super.write(cbuf, off, len);
- lengthLeft -= len;
-
- if (lengthExceeded) {
- throw new LengthLimitExceededException();
- }
- }
-
- @Override
- public void write(String str, int off, int len) throws IOException {
- final boolean lengthExceeded;
- if (lengthLeft < len) {
- len = lengthLeft;
- lengthExceeded = true;
- } else {
- lengthExceeded = false;
- }
-
- super.write(str, off, len);
- lengthLeft -= len;
-
- if (lengthExceeded) {
- throw new LengthLimitExceededException();
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/main/java/com/kenshoo/freemarker/view/FreeMarkerOnlineView.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/kenshoo/freemarker/view/FreeMarkerOnlineView.java b/src/main/java/com/kenshoo/freemarker/view/FreeMarkerOnlineView.java
deleted file mode 100644
index fb256f1..0000000
--- a/src/main/java/com/kenshoo/freemarker/view/FreeMarkerOnlineView.java
+++ /dev/null
@@ -1,157 +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 com.kenshoo.freemarker.view;
-
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
-import org.apache.commons.lang3.StringUtils;
-
-import com.kenshoo.freemarker.model.SelectionOption;
-import com.kenshoo.freemarker.services.AllowedSettingValuesMaps;
-import com.yammer.dropwizard.views.View;
-
-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 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 boolean execute;
-
- private static List<SelectionOption> toSelectionOptions(Map<String, ?> settingValueMap) {
- ArrayList<SelectionOption> selectionOptions = new ArrayList<SelectionOption>(settingValueMap.size());
- for (String key : settingValueMap.keySet()) {
- selectionOptions.add(new SelectionOption(key, truncate(key, 25)));
- }
- 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()));
- }
- Collections.sort(selectionOptions);
- return selectionOptions;
- }
-
- private static String truncate(String s, int maxLength) {
- if (s == null) {
- return null;
- }
- return s.length() <= maxLength ? s : s.substring(0, Math.max(maxLength - 3, 0)) + "[...]";
- }
-
- /**
- *
- * @param template
- * @param dataModel
- * @param execute set to true if the execution should be triggered on page load.
- */
- public FreeMarkerOnlineView() {
- super("/view/freemarker-online.ftl", Charset.forName("utf-8"));
- }
-
- public String getTemplate() {
- return template;
- }
-
- public void setTemplate(String template) {
- this.template = withDefault(template, "");
- }
-
- public String getDataModel() {
- return dataModel;
- }
-
- public void setDataModel(String dataModel) {
- this.dataModel = withDefault(dataModel, "");
- }
-
- public String getFreeMarkerVersion() {
- return Configuration.getVersion().toString();
- }
-
- public List<SelectionOption> getOutputFormats() {
- return OUTPUT_FORMAT_SELECTION_OPTIONS;
- }
-
- public List<SelectionOption> getLocales() {
- return LOCALE_SELECTION_OPTIONS;
- }
-
- public List<SelectionOption> getTimeZones() {
- return TIME_ZONE_SELECTION_OPTIONS;
- }
-
- public String getOutputFormat() {
- return outputFormat;
- }
-
- public void setOutputFormat(String outputFormat) {
- this.outputFormat = withDefault(outputFormat, AllowedSettingValuesMaps.DEFAULT_OUTPUT_FORMAT_KEY);
- }
-
- public String getLocale() {
- return locale;
- }
-
- public void setLocale(String locale) {
- this.locale = withDefault(locale, AllowedSettingValuesMaps.DEFAULT_LOCALE_KEY);
- }
-
- public String getTimeZone() {
- return timeZone;
- }
-
- public void setTimeZone(String timeZone) {
- this.timeZone = withDefault(timeZone, AllowedSettingValuesMaps.DEFAULT_TIME_ZONE_KEY);
- }
-
- public boolean isExecute() {
- return execute;
- }
-
- public void setExecute(boolean executeImmediately) {
- this.execute = executeImmediately;
- }
-
- private static String withDefault(String value, String defaultValue) {
- return !StringUtils.isBlank(value) ? value : defaultValue;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/main/java/org/apache/freemarker/onlinetester/dropwizard/ApplicationStartup.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/onlinetester/dropwizard/ApplicationStartup.java b/src/main/java/org/apache/freemarker/onlinetester/dropwizard/ApplicationStartup.java
new file mode 100644
index 0000000..4caf07c
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/onlinetester/dropwizard/ApplicationStartup.java
@@ -0,0 +1,42 @@
+/*
+ * 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.dropwizard;
+
+import com.berico.fallwizard.SpringConfiguration;
+import com.berico.fallwizard.SpringService;
+import com.yammer.dropwizard.assets.AssetsBundle;
+import com.yammer.dropwizard.config.Bootstrap;
+import com.yammer.dropwizard.views.ViewBundle;
+
+public class ApplicationStartup extends SpringService<SpringConfiguration> {
+
+ public static void main(String[] args) throws Exception {
+ new ApplicationStartup().run(args);
+ }
+
+ @Override
+ public void initialize(Bootstrap<SpringConfiguration> bootstrap) {
+ bootstrap.setName("freemarker-online");
+ bootstrap.addBundle(new ViewBundle());
+ bootstrap.addBundle(new AssetsBundle("/assets/css", "/css"));
+ bootstrap.addBundle(new AssetsBundle("/assets/js", "/js"));
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/main/java/org/apache/freemarker/onlinetester/healthchecks/MyProjectHealthCheck.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/onlinetester/healthchecks/MyProjectHealthCheck.java b/src/main/java/org/apache/freemarker/onlinetester/healthchecks/MyProjectHealthCheck.java
new file mode 100644
index 0000000..192fa46
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/onlinetester/healthchecks/MyProjectHealthCheck.java
@@ -0,0 +1,37 @@
+/*
+ * 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.healthchecks;
+
+import com.yammer.metrics.core.HealthCheck;
+import org.springframework.stereotype.Component;
+
+@Component
+public class MyProjectHealthCheck extends HealthCheck {
+
+ // note that this is due to the default spring CTR
+ public MyProjectHealthCheck() {
+ super("MyProjectHealthCheck");
+ }
+
+ @Override
+ protected Result check() throws Exception {
+ return Result.healthy(); // we're always healthy!
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/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
new file mode 100644
index 0000000..c983e87
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/onlinetester/model/ErrorCode.java
@@ -0,0 +1,25 @@
+/*
+ * 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 enum ErrorCode {
+ FREEMARKER_SERVICE_TIMEOUT
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/main/java/org/apache/freemarker/onlinetester/model/ErrorResponse.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/onlinetester/model/ErrorResponse.java b/src/main/java/org/apache/freemarker/onlinetester/model/ErrorResponse.java
new file mode 100644
index 0000000..68ddf69
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/onlinetester/model/ErrorResponse.java
@@ -0,0 +1,30 @@
+/*
+ * 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 ErrorResponse {
+ private ErrorCode errorCode;
+ private String errorDescription;
+
+ public ErrorResponse(ErrorCode errorCode, String errorDescription) {
+ this.errorCode = errorCode;
+ this.errorDescription = errorDescription;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/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
new file mode 100644
index 0000000..a206131
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/onlinetester/model/ExecuteRequest.java
@@ -0,0 +1,78 @@
+/*
+ * 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 ExecuteRequest {
+ private String template;
+ private String dataModel;
+ private String outputFormat;
+ private String locale;
+ private String timeZone;
+
+ public ExecuteRequest() {
+ }
+
+ public ExecuteRequest(String template, String dataModel) {
+ this.template = template;
+ this.dataModel = dataModel;
+ }
+
+ public String getDataModel() {
+ return dataModel;
+ }
+
+ public void setDataModel(String dataModel) {
+ this.dataModel = dataModel;
+ }
+
+ public String getTemplate() {
+
+ return template;
+ }
+
+ public void setTemplate(String template) {
+ this.template = template;
+ }
+
+ public String getOutputFormat() {
+ return outputFormat;
+ }
+
+ public void setOutputFormat(String outputFormat) {
+ this.outputFormat = outputFormat;
+ }
+
+ public String getLocale() {
+ return locale;
+ }
+
+ public void setLocale(String locale) {
+ this.locale = locale;
+ }
+
+ public String getTimeZone() {
+ return timeZone;
+ }
+
+ public void setTimeZone(String timeZone) {
+ this.timeZone = timeZone;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/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
new file mode 100644
index 0000000..71ad454
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/onlinetester/model/ExecuteResourceField.java
@@ -0,0 +1,57 @@
+/*
+ * 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/2f0c0424/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
new file mode 100644
index 0000000..3c69d43
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/onlinetester/model/ExecuteResourceProblem.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 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/2f0c0424/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
new file mode 100644
index 0000000..41c33f1
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/onlinetester/model/ExecuteResponse.java
@@ -0,0 +1,63 @@
+/*
+ * 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 java.util.List;
+
+public class ExecuteResponse {
+ private String result;
+ private List<ExecuteResourceProblem> problems;
+ private boolean truncatedResult;
+
+ public ExecuteResponse(String result, List<ExecuteResourceProblem> problems, boolean truncatedResult) {
+ this.result = result;
+ this.problems = problems;
+ this.truncatedResult = truncatedResult;
+ }
+
+ public ExecuteResponse() {
+
+ }
+
+ public List<ExecuteResourceProblem> getProblems() {
+ return problems;
+ }
+
+ public void setProblems(List<ExecuteResourceProblem> problems) {
+ this.problems = problems;
+ }
+
+ public boolean isTruncatedResult() {
+ return truncatedResult;
+ }
+
+ public void setTruncatedResult(boolean truncatedResult) {
+ this.truncatedResult = truncatedResult;
+ }
+
+ public String getResult() {
+ return result;
+ }
+
+ public void setResult(String result) {
+ this.result = result;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/main/java/org/apache/freemarker/onlinetester/model/SelectionOption.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/onlinetester/model/SelectionOption.java b/src/main/java/org/apache/freemarker/onlinetester/model/SelectionOption.java
new file mode 100644
index 0000000..d7dfe49
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/onlinetester/model/SelectionOption.java
@@ -0,0 +1,88 @@
+/*
+ * 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 SelectionOption implements Comparable<SelectionOption> {
+
+ private final String value;
+ private final String label;
+
+ public String getValue() {
+ return value;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public SelectionOption(String value, String label) {
+ this.value = value;
+ this.label = label;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((label == null) ? 0 : label.hashCode());
+ result = prime * result + ((value == null) ? 0 : value.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ SelectionOption other = (SelectionOption) obj;
+ if (label == null) {
+ if (other.label != null) {
+ return false;
+ }
+ } else if (!label.equals(other.label)) {
+ return false;
+ }
+ if (value == null) {
+ if (other.value != null) {
+ return false;
+ }
+ } else if (!value.equals(other.value)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public int compareTo(SelectionOption o) {
+ int r = label.compareTo(o.label);
+ if (r != 0) {
+ return r;
+ }
+
+ return value.compareTo(o.value);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/main/java/org/apache/freemarker/onlinetester/resources/FreeMarkerOnlineExecuteResource.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/onlinetester/resources/FreeMarkerOnlineExecuteResource.java b/src/main/java/org/apache/freemarker/onlinetester/resources/FreeMarkerOnlineExecuteResource.java
new file mode 100644
index 0000000..c850720
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/onlinetester/resources/FreeMarkerOnlineExecuteResource.java
@@ -0,0 +1,220 @@
+/*
+ * 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.resources;
+
+import java.text.MessageFormat;
+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;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.freemarker.onlinetester.model.ErrorCode;
+import org.apache.freemarker.onlinetester.model.ExecuteResourceProblem;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+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.ExecuteResponse;
+import org.apache.freemarker.onlinetester.services.AllowedSettingValuesMaps;
+import org.apache.freemarker.onlinetester.services.FreeMarkerService;
+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;
+
+@Path("/api/execute")
+@Component
+public class FreeMarkerOnlineExecuteResource {
+ private static final int MAX_TEMPLATE_INPUT_LENGTH = 10000;
+
+ private static final int MAX_DATA_MODEL_INPUT_LENGTH = 10000;
+
+ private static final String MAX_TEMPLATE_INPUT_LENGTH_EXCEEDED_ERROR_MESSAGE
+ = "The template length has exceeded the {0} character limit set for this service.";
+
+ 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
+ = "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.";
+
+ @Autowired
+ private FreeMarkerService freeMarkerService;
+
+ @POST
+ @Produces(MediaType.APPLICATION_JSON)
+ @Consumes(MediaType.APPLICATION_JSON)
+ public Response formResult(
+ ExecuteRequest req) {
+ ExecuteResponse resp = new ExecuteResponse();
+
+ if (StringUtils.isBlank(req.getTemplate()) && StringUtils.isBlank(req.getDataModel())) {
+ return Response.status(400).entity("Empty Template & data").build();
+ }
+
+ List<ExecuteResourceProblem> problems = new ArrayList<ExecuteResourceProblem>();
+
+ 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);
+
+ if (!problems.isEmpty()) {
+ resp.setProblems(problems);
+ return buildFreeMarkerResponse(resp);
+ }
+
+ FreeMarkerServiceResponse freeMarkerServiceResponse;
+ try {
+ freeMarkerServiceResponse = freeMarkerService.calculateTemplateOutput(
+ template, dataModel,
+ outputFormat, locale, timeZone);
+ } catch (RejectedExecutionException e) {
+ String error = SERVICE_OVERBURDEN_ERROR_MESSAGE;
+ return Response.serverError().entity(new ErrorResponse(ErrorCode.FREEMARKER_SERVICE_TIMEOUT, error)).build();
+ }
+ if (!freeMarkerServiceResponse.isSuccesful()){
+ Throwable failureReason = freeMarkerServiceResponse.getFailureReason();
+ String error = ExceptionUtils.getMessageWithCauses(failureReason);
+ problems.add(new ExecuteResourceProblem(ExecuteResourceField.TEMPLATE, error));
+ resp.setProblems(problems);
+ return buildFreeMarkerResponse(resp);
+ }
+
+ String result = freeMarkerServiceResponse.getTemplateOutput();
+ resp.setResult(result);
+ resp.setTruncatedResult(freeMarkerServiceResponse.isTemplateOutputTruncated());
+ return buildFreeMarkerResponse(resp);
+ }
+
+ private String getTemplate(ExecuteRequest req, List<ExecuteResourceProblem> problems) {
+ String template = req.getTemplate();
+
+ if (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));
+ return null;
+ }
+
+ return template;
+ }
+
+ private Map<String, Object> getDataModel(ExecuteRequest req, List<ExecuteResourceProblem> 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));
+ return null;
+ }
+
+ try {
+ return DataModelParser.parse(dataModel, freeMarkerService.getFreeMarkerTimeZone());
+ } catch (DataModelParsingException e) {
+ problems.add(new ExecuteResourceProblem(ExecuteResourceField.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;
+ }
+
+ 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)));
+ }
+ return timeZone;
+ }
+
+ private Response buildFreeMarkerResponse(ExecuteResponse executeResponse){
+ return Response.ok().entity(executeResponse).build();
+ }
+
+ private String decorateResultText(String resultText) {
+ return DATA_MODEL_ERROR_MESSAGE_HEADING + "\n\n" + resultText + "\n\n" + DATA_MODEL_ERROR_MESSAGE_FOOTER;
+ }
+
+ private String formatMessage(String key, Object... params) {
+ return new MessageFormat(key, Locale.US).format(params);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/main/java/org/apache/freemarker/onlinetester/resources/FreeMarkerOnlineResource.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/onlinetester/resources/FreeMarkerOnlineResource.java b/src/main/java/org/apache/freemarker/onlinetester/resources/FreeMarkerOnlineResource.java
new file mode 100644
index 0000000..ebf82a1
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/onlinetester/resources/FreeMarkerOnlineResource.java
@@ -0,0 +1,63 @@
+/*
+ * 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.resources;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import org.springframework.stereotype.Component;
+
+import org.apache.freemarker.onlinetester.view.FreeMarkerOnlineView;
+
+@Path("/")
+@Component
+public class FreeMarkerOnlineResource {
+
+ @GET
+ @Produces(MediaType.TEXT_HTML)
+ public FreeMarkerOnlineView blankForm() {
+ return new FreeMarkerOnlineView();
+ }
+
+ @POST
+ @Produces(MediaType.TEXT_HTML)
+ @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+ public FreeMarkerOnlineView formResult(
+ @FormParam("template") String template,
+ @FormParam("dataModel") String dataModel,
+ @FormParam("outputFormat") String outputFormat,
+ @FormParam("locale") String locale,
+ @FormParam("timeZone") String timeZone) {
+ FreeMarkerOnlineView view = new FreeMarkerOnlineView();
+ view.setTemplate(template);
+ view.setDataModel(dataModel);
+ view.setOutputFormat(outputFormat);
+ view.setLocale(locale);
+ view.setTimeZone(timeZone);
+ view.setExecute(true);
+ return view;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/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
new file mode 100644
index 0000000..e3111aa
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/onlinetester/services/AllowedSettingValuesMaps.java
@@ -0,0 +1,115 @@
+/*
+ * 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/2f0c0424/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
new file mode 100644
index 0000000..4487abe
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/onlinetester/services/FreeMarkerService.java
@@ -0,0 +1,364 @@
+/*
+ * 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.io.StringReader;
+import java.io.StringWriter;
+import java.text.MessageFormat;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.TimeZone;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import javax.annotation.PostConstruct;
+
+import org.apache.commons.lang3.StringEscapeUtils;
+import org.apache.freemarker.onlinetester.util.LengthLimitedWriter;
+import org.eclipse.jetty.util.BlockingArrayQueue;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import org.apache.freemarker.onlinetester.util.LengthLimitExceededException;
+
+import freemarker.core.FreeMarkerInternalsAccessor;
+import freemarker.core.OutputFormat;
+import freemarker.core.ParseException;
+import freemarker.core.TemplateClassResolver;
+import freemarker.core.TemplateConfiguration;
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+import freemarker.template.TemplateException;
+import freemarker.template.TemplateExceptionHandler;
+
+@Service
+public class FreeMarkerService {
+
+ private static final int DEFAULT_MAX_OUTPUT_LENGTH = 100000;
+ private static final int DEFAULT_MAX_THREADS = Math.max(2,
+ (int) Math.round(Runtime.getRuntime().availableProcessors() * 3.0 / 4));
+ /** Not implemented yet, will need 2.3.22, even then a _CoreAPI call. */
+ private static final long DEFAULT_MAX_TEMPLATE_EXECUTION_TIME = 2000;
+ private static final int MIN_DEFAULT_MAX_QUEUE_LENGTH = 2;
+ private static final int MAX_DEFAULT_MAX_QUEUE_LENGTH_MILLISECONDS = 30000;
+ private static final long THREAD_KEEP_ALIVE_TIME = 4 * 1000;
+ private static final long ABORTION_LOOP_TIME_LIMIT = 5000;
+ private static final long ABORTION_LOOP_INTERRUPTION_DISTANCE = 50;
+
+ private static final String MAX_OUTPUT_LENGTH_EXCEEDED_TERMINATION = "\n----------\n"
+ + "Aborted template processing, as the output length has exceeded the {0} character limit set for "
+ + "this service.";
+
+ private static final Logger logger = LoggerFactory.getLogger(FreeMarkerService.class);
+
+ private final Configuration freeMarkerConfig;
+
+ private ExecutorService templateExecutor;
+
+ private int maxOutputLength = DEFAULT_MAX_OUTPUT_LENGTH;
+
+ private int maxThreads = DEFAULT_MAX_THREADS;
+ private Integer maxQueueLength;
+ private long maxTemplateExecutionTime = DEFAULT_MAX_TEMPLATE_EXECUTION_TIME;
+
+ public FreeMarkerService() {
+ freeMarkerConfig = new Configuration(Configuration.getVersion());
+ freeMarkerConfig.setNewBuiltinClassResolver(TemplateClassResolver.ALLOWS_NOTHING_RESOLVER);
+ freeMarkerConfig.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
+ freeMarkerConfig.setLogTemplateExceptions(false);
+ freeMarkerConfig.setLocale(AllowedSettingValuesMaps.DEFAULT_LOCALE);
+ freeMarkerConfig.setTimeZone(AllowedSettingValuesMaps.DEFAULT_TIME_ZONE);
+ freeMarkerConfig.setOutputFormat(AllowedSettingValuesMaps.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
+ * this is a service for trying out the template language, so such errors are part of the normal operation.
+ *
+ * @throws RejectedExecutionException
+ * If the service is overburden and thus doing the calculation was rejected.
+ * @throws FreeMarkerServiceException
+ * If the calculation fails from a reason that's not a mistake in the template and doesn't fit the
+ * meaning of {@link RejectedExecutionException} either.
+ */
+ public FreeMarkerServiceResponse calculateTemplateOutput(
+ String templateSourceCode, Object dataModel, OutputFormat outputFormat, Locale locale, TimeZone timeZone)
+ throws RejectedExecutionException {
+ Objects.requireNonNull(templateExecutor, "templateExecutor was null - was postConstruct ever called?");
+
+ final CalculateTemplateOutput task = new CalculateTemplateOutput(
+ templateSourceCode, dataModel, outputFormat, locale, timeZone);
+ Future<FreeMarkerServiceResponse> future = templateExecutor.submit(task);
+
+ synchronized (task) {
+ while (!task.isTemplateExecutionStarted() && !task.isTaskEnded() && !future.isDone()) {
+ try {
+ task.wait(50); // Timeout is needed to periodically check future.isDone()
+ } catch (InterruptedException e) {
+ throw new FreeMarkerServiceException("Template execution task was interrupted.", e);
+ }
+ }
+ }
+
+ try {
+ return future.get(maxTemplateExecutionTime, TimeUnit.MILLISECONDS);
+ } catch (ExecutionException e) {
+ throw new FreeMarkerServiceException("Template execution task unexpectedly failed", e.getCause());
+ } catch (InterruptedException e) {
+ throw new FreeMarkerServiceException("Template execution task was interrupted.", e);
+ } catch (TimeoutException e) {
+ // Exactly one interruption should be enough, and it should abort template processing pretty much
+ // immediately. But to be on the safe side we will interrupt in a loop, with a timeout.
+ final long abortionLoopStartTime = System.currentTimeMillis();
+ long timeLeft = ABORTION_LOOP_TIME_LIMIT;
+ boolean templateExecutionEnded = false;
+ do {
+ synchronized (task) {
+ Thread templateExecutorThread = task.getTemplateExecutorThread();
+ if (templateExecutorThread == null) {
+ templateExecutionEnded = true;
+ } else {
+ FreeMarkerInternalsAccessor.interruptTemplateProcessing(templateExecutorThread);
+ logger.debug("Trying to interrupt overly long template processing (" + timeLeft + " ms left).");
+ }
+ }
+ if (!templateExecutionEnded) {
+ try {
+ timeLeft = ABORTION_LOOP_TIME_LIMIT - (System.currentTimeMillis() - abortionLoopStartTime);
+ if (timeLeft > 0) {
+ Thread.sleep(ABORTION_LOOP_INTERRUPTION_DISTANCE);
+ }
+ } catch (InterruptedException eInt) {
+ logger.error("Template execution abortion loop was interrupted", eInt);
+ timeLeft = 0;
+ }
+ }
+ } while (!templateExecutionEnded && timeLeft > 0);
+
+ if (templateExecutionEnded) {
+ 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", e);
+ }
+ } 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));
+ }
+ }
+ }
+
+ public int getMaxOutputLength() {
+ return maxOutputLength;
+ }
+
+ public void setMaxOutputLength(int maxOutputLength) {
+ this.maxOutputLength = maxOutputLength;
+ }
+
+ public int getMaxThreads() {
+ return maxThreads;
+ }
+
+ public void setMaxThreads(int maxThreads) {
+ this.maxThreads = maxThreads;
+ }
+
+ public int getMaxQueueLength() {
+ return maxQueueLength;
+ }
+
+ public void setMaxQueueLength(int maxQueueLength) {
+ this.maxQueueLength = maxQueueLength;
+ }
+
+ public long getMaxTemplateExecutionTime() {
+ return maxTemplateExecutionTime;
+ }
+
+ public void setMaxTemplateExecutionTime(long maxTemplateExecutionTime) {
+ this.maxTemplateExecutionTime = maxTemplateExecutionTime;
+ }
+
+ /**
+ * Returns the time zone used by the FreeMarker templates.
+ */
+ public TimeZone getFreeMarkerTimeZone() {
+ return freeMarkerConfig.getTimeZone();
+ }
+
+ private FreeMarkerServiceResponse createFailureResponse(Throwable e) {
+ logger.debug("The template had error(s)", e);
+ return new FreeMarkerServiceResponse.Builder().buildForFailure(e);
+ }
+
+ @PostConstruct
+ public void postConstruct() {
+ int actualMaxQueueLength = maxQueueLength != null
+ ? maxQueueLength
+ : Math.max(
+ MIN_DEFAULT_MAX_QUEUE_LENGTH,
+ (int) (MAX_DEFAULT_MAX_QUEUE_LENGTH_MILLISECONDS / maxTemplateExecutionTime));
+ ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
+ maxThreads, maxThreads,
+ THREAD_KEEP_ALIVE_TIME, TimeUnit.MILLISECONDS,
+ new BlockingArrayQueue<Runnable>(actualMaxQueueLength));
+ threadPoolExecutor.allowCoreThreadTimeOut(true);
+ templateExecutor = threadPoolExecutor;
+ }
+
+ private class CalculateTemplateOutput implements Callable<FreeMarkerServiceResponse> {
+
+ 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;
+ }
+
+ @Override
+ public FreeMarkerServiceResponse call() throws Exception {
+ try {
+ Template template;
+ try {
+ TemplateConfiguration tCfg = new TemplateConfiguration();
+ tCfg.setParentConfiguration(freeMarkerConfig);
+ if (outputFormat != null) {
+ tCfg.setOutputFormat(outputFormat);
+ }
+ if (locale != null) {
+ tCfg.setLocale(locale);
+ }
+ if (timeZone != null) {
+ tCfg.setTimeZone(timeZone);
+ }
+
+ template = new Template(null, null,
+ new StringReader(templateSourceCode), freeMarkerConfig, tCfg, null);
+
+ tCfg.apply(template);
+ } catch (ParseException e) {
+ // Expected (part of normal operation)
+ return createFailureResponse(e);
+ } catch (Exception e) {
+ // Not expected
+ throw new FreeMarkerServiceException("Unexpected exception during template parsing", e);
+ }
+
+ FreeMarkerInternalsAccessor.makeTemplateInterruptable(template);
+
+ boolean resultTruncated;
+ StringWriter writer = new StringWriter();
+ try {
+ synchronized (this) {
+ templateExecutorThread = Thread.currentThread();
+ templateExecutionStarted = true;
+ notifyAll();
+ }
+ try {
+ template.process(dataModel, new LengthLimitedWriter(writer, maxOutputLength));
+ } finally {
+ synchronized (this) {
+ templateExecutorThread = null;
+ FreeMarkerInternalsAccessor.clearAnyPendingTemplateProcessingInterruption();
+ }
+ }
+ resultTruncated = false;
+ } 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)
+ .format(new Object[] { maxOutputLength }));
+ // Falls through
+ } catch (TemplateException e) {
+ // Expected (part of normal operation)
+ return createFailureResponse(e);
+ } catch (Exception e) {
+ if (FreeMarkerInternalsAccessor.isTemplateProcessingInterruptedException(e)) {
+ return new FreeMarkerServiceResponse.Builder().buildForFailure(new TimeoutException(
+ "Template processing was aborted for exceeding the " + getMaxTemplateExecutionTime()
+ + " ms time limit set for this online service. This is usually because you have "
+ + "a very long running #list (or other kind of loop) in your template."));
+ }
+ // Not expected
+ throw new FreeMarkerServiceException("Unexpected exception during template evaluation", e);
+ }
+
+ return new FreeMarkerServiceResponse.Builder().buildForSuccess(writer.toString(), resultTruncated);
+ } finally {
+ synchronized (this) {
+ taskEnded = true;
+ notifyAll();
+ }
+ }
+ }
+
+ private synchronized boolean isTemplateExecutionStarted() {
+ return templateExecutionStarted;
+ }
+
+ private synchronized boolean isTaskEnded() {
+ return taskEnded;
+ }
+
+ /**
+ * @return non-{@code null} after the task execution has actually started, but before it has finished.
+ */
+ private synchronized Thread getTemplateExecutorThread() {
+ return templateExecutorThread;
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/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
new file mode 100644
index 0000000..2ca7ee4
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/onlinetester/services/FreeMarkerServiceException.java
@@ -0,0 +1,38 @@
+/*
+ * 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;
+
+/**
+ * When {@link FreeMarkerService} fails on an unexpected way (non-user error).
+ */
+public class FreeMarkerServiceException extends RuntimeException {
+
+ private static final long serialVersionUID = 1L;
+
+ public FreeMarkerServiceException(String message) {
+ super(message);
+ // TODO Auto-generated constructor stub
+ }
+
+ public FreeMarkerServiceException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/main/java/org/apache/freemarker/onlinetester/services/FreeMarkerServiceResponse.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/onlinetester/services/FreeMarkerServiceResponse.java b/src/main/java/org/apache/freemarker/onlinetester/services/FreeMarkerServiceResponse.java
new file mode 100644
index 0000000..3950717
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/onlinetester/services/FreeMarkerServiceResponse.java
@@ -0,0 +1,68 @@
+/*
+ * 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;
+
+public class FreeMarkerServiceResponse {
+
+ private final String templateOutput;
+ private final boolean templateOutputTruncated;
+ private final Throwable failureReason;
+
+ FreeMarkerServiceResponse(String templateOutput, boolean templateOutputTruncated) {
+ this.templateOutput = templateOutput;
+ this.templateOutputTruncated = templateOutputTruncated;
+ this.failureReason = null;
+ }
+
+ FreeMarkerServiceResponse(Throwable failureReason) {
+ this.templateOutput = null;
+ this.templateOutputTruncated = false;
+ this.failureReason = failureReason;
+ }
+
+ public String getTemplateOutput() {
+ return templateOutput;
+ }
+
+ public boolean isTemplateOutputTruncated() {
+ return templateOutputTruncated;
+ }
+
+ public boolean isSuccesful() {
+ return failureReason == null;
+ }
+
+ public Throwable getFailureReason() {
+ return failureReason;
+ }
+
+ public static class Builder {
+
+ public FreeMarkerServiceResponse buildForSuccess(String result, boolean resultTruncated){
+ return new FreeMarkerServiceResponse(result, resultTruncated);
+ }
+
+ public FreeMarkerServiceResponse buildForFailure(Throwable failureReason){
+ return new FreeMarkerServiceResponse(failureReason);
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/main/java/org/apache/freemarker/onlinetester/util/DataModelParser.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/onlinetester/util/DataModelParser.java b/src/main/java/org/apache/freemarker/onlinetester/util/DataModelParser.java
new file mode 100644
index 0000000..b356be6
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/onlinetester/util/DataModelParser.java
@@ -0,0 +1,268 @@
+/*
+ * 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.util;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.math.BigDecimal;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.xml.parsers.DocumentBuilder;
+
+import org.springframework.util.StringUtils;
+import org.w3c.dom.Document;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import freemarker.ext.dom.NodeModel;
+import freemarker.template.utility.DateUtil;
+import freemarker.template.utility.DateUtil.CalendarFieldsToDateConverter;
+import freemarker.template.utility.DateUtil.DateParseException;
+import freemarker.template.utility.DateUtil.TrivialCalendarFieldsToDateConverter;
+
+/**
+ * Parses the text that the user enters into the data model input field.
+ */
+public final class DataModelParser {
+
+ private static final String KEYWORD_NEGATIVE_INFINITY = "-Infinity";
+
+ private static final String KEYWORD_POSITIVE_INFINITY = "+Infinity";
+
+ private static final String KEYWORD_INFINITY = "Infinity";
+
+ private static final String KEYWORD_TRUE = "true";
+
+ private static final String KEYWORD_FALSE = "false";
+
+ private static final String KEYWORD_NULL = "null";
+
+ private static final String KEYWORD_NAN = "NaN";
+
+ /** Matches a line starting like "someVariable=". */
+ private static final Pattern ASSIGNMENT_START = Pattern.compile(
+ "^\\s*"
+ + "(\\p{L}[\\p{L}\\p{N}\\.:\\-_$@]*)" // name
+ + "[ \t]*=\\s*",
+ Pattern.MULTILINE);
+
+ /** Matches a value that starts like a number, or probably meant to be number at least. */
+ private static final Pattern NUMBER_LIKE = Pattern.compile("[+-]?[\\.,]?[0-9].*", Pattern.DOTALL);
+
+ private static final ObjectMapper JSON_MAPPER = new ObjectMapper();
+
+ private DataModelParser() {
+ // Not meant to be instantiated
+ }
+
+ public static Map<String, Object> parse(String src, TimeZone timeZone) throws DataModelParsingException {
+ if (!StringUtils.hasText(src)) {
+ return Collections.emptyMap();
+ }
+
+ Map<String, Object> dataModel = new LinkedHashMap<>();
+
+ String lastName = null;
+ int lastAssignmentStartEnd = 0;
+ final Matcher assignmentStart = ASSIGNMENT_START.matcher(src);
+ findAssignments: while (true) {
+ boolean hasNextAssignment = assignmentStart.find(lastAssignmentStartEnd);
+
+ if (lastName != null) {
+ String value = src.substring(
+ lastAssignmentStartEnd, hasNextAssignment ? assignmentStart.start() : src.length())
+ .trim();
+ final Object parsedValue;
+ try {
+ parsedValue = parseValue(value, timeZone);
+ } catch (DataModelParsingException e) {
+ throw new DataModelParsingException(
+ "Failed to parse the value of \"" + lastName + "\":\n" + e.getMessage(), e.getCause());
+ }
+ dataModel.put(lastName, parsedValue);
+ }
+
+ if (lastName == null && (!hasNextAssignment || assignmentStart.start() != 0)) {
+ throw new DataModelParsingException(
+ "The data model specification must start with an assignment (name=value).");
+ }
+
+ if (!hasNextAssignment) {
+ break findAssignments;
+ }
+
+ lastName = assignmentStart.group(1).trim();
+ lastAssignmentStartEnd = assignmentStart.end();
+ }
+
+ return dataModel;
+ }
+
+ private static Object parseValue(String value, TimeZone timeZone) throws DataModelParsingException {
+ // Note: Because we fall back to interpret the input as a literal string value when it doesn't look like
+ // anything else (like a number, boolean, etc.), it's important to avoid misunderstandings, and throw exception
+ // in suspicious situations. The user can always quote the string value if we are "too smart". But he will
+ // be confused about the rules of FreeMarker if what he believes to be a non-string is misinterpreted by this
+ // parser as a string. Getting sometimes an error and then quoting the string is better than that.
+
+ if (value.endsWith(";")) { // Tolerate this habit of Java and JavaScript programmers
+ value = value.substring(value.length() - 1).trim();
+ }
+
+ if (NUMBER_LIKE.matcher(value).matches()) {
+ try {
+ return new BigDecimal(value);
+ } catch (NumberFormatException e) {
+ // Maybe it's a ISO 8601 Date/time/datetime
+ CalendarFieldsToDateConverter calToDateConverter = new TrivialCalendarFieldsToDateConverter();
+
+ DateParseException attemptedTemportalPExc = null;
+ String attemptedTemporalType = null;
+ final int dashIdx = value.indexOf('-');
+ final int colonIdx = value.indexOf(':');
+ if (value.indexOf('T') > 1 || (dashIdx > 1 && colonIdx > dashIdx)) {
+ try {
+ return new Timestamp(
+ DateUtil.parseISO8601DateTime(value, timeZone, calToDateConverter).getTime());
+ } catch (DateParseException pExc) {
+ attemptedTemporalType = "date-time";
+ attemptedTemportalPExc = pExc;
+ }
+ } else if (dashIdx > 1) {
+ try {
+ return new java.sql.Date(
+ DateUtil.parseISO8601Date(value, timeZone, calToDateConverter).getTime());
+ } catch (DateParseException pExc) {
+ attemptedTemporalType = "date";
+ attemptedTemportalPExc = pExc;
+ }
+ } else if (colonIdx > 1) {
+ try {
+ return new Time(
+ DateUtil.parseISO8601Time(value, timeZone, calToDateConverter).getTime());
+ } catch (DateParseException pExc) {
+ attemptedTemporalType = "time";
+ attemptedTemportalPExc = pExc;
+ }
+ }
+ if (attemptedTemportalPExc == null) {
+ throw new DataModelParsingException("Malformed number: " + value, e);
+ } else {
+ throw new DataModelParsingException(
+ "Malformed ISO 8601 " + attemptedTemporalType + " (or malformed number): " +
+ attemptedTemportalPExc.getMessage(), e.getCause());
+ }
+ }
+ } else if (value.startsWith("\"")) {
+ try {
+ return JSON_MAPPER.readValue(value, String.class);
+ } catch (IOException e) {
+ throw new DataModelParsingException(
+ "Malformed quoted string (using JSON syntax): " + getMessageWithoutLocation(e),
+ e);
+ }
+ } else if (value.startsWith("\'")) {
+ throw new DataModelParsingException(
+ "Malformed quoted string (using JSON syntax): Use \" character for quotation, not \' character.");
+ } else if (value.startsWith("[")) {
+ try {
+ return JSON_MAPPER.readValue(value, List.class);
+ } catch (IOException e) {
+ throw new DataModelParsingException(
+ "Malformed list (using JSON syntax): " + getMessageWithoutLocation(e),
+ e);
+ }
+ } else if (value.startsWith("{")) {
+ try {
+ return JSON_MAPPER.readValue(value, LinkedHashMap.class);
+ } catch (IOException e) {
+ throw new DataModelParsingException(
+ "Malformed list (using JSON syntax): " + getMessageWithoutLocation(e),
+ e);
+ }
+ } else if (value.startsWith("<")) {
+ try {
+ DocumentBuilder builder = NodeModel.getDocumentBuilderFactory().newDocumentBuilder();
+ ErrorHandler errorHandler = NodeModel.getErrorHandler();
+ if (errorHandler != null) builder.setErrorHandler(errorHandler);
+ final Document doc = builder.parse(new InputSource(new StringReader(value)));
+ NodeModel.simplify(doc);
+ return doc;
+ } catch (SAXException e) {
+ final String saxMsg = e.getMessage();
+ throw new DataModelParsingException("Malformed XML: " + (saxMsg != null ? saxMsg : e), e);
+ } catch (Exception e) {
+ throw new DataModelParsingException("XML parsing has failed with internal error: " + e, e);
+ }
+ } else if (value.equalsIgnoreCase(KEYWORD_TRUE)) {
+ checkKeywordCase(value, KEYWORD_TRUE);
+ return Boolean.TRUE;
+ } else if (value.equalsIgnoreCase(KEYWORD_FALSE)) {
+ checkKeywordCase(value, KEYWORD_FALSE);
+ return Boolean.FALSE;
+ } else if (value.equalsIgnoreCase(KEYWORD_NULL)) {
+ checkKeywordCase(value, KEYWORD_NULL);
+ return null;
+ } else if (value.equalsIgnoreCase(KEYWORD_NAN)) {
+ checkKeywordCase(value, KEYWORD_NAN);
+ return Double.NaN;
+ } else if (value.equalsIgnoreCase(KEYWORD_INFINITY)) {
+ checkKeywordCase(value, KEYWORD_INFINITY);
+ return Double.POSITIVE_INFINITY;
+ } else if (value.equalsIgnoreCase(KEYWORD_POSITIVE_INFINITY)) {
+ checkKeywordCase(value, KEYWORD_POSITIVE_INFINITY);
+ return Double.POSITIVE_INFINITY;
+ } else if (value.equalsIgnoreCase(KEYWORD_NEGATIVE_INFINITY)) {
+ checkKeywordCase(value, KEYWORD_NEGATIVE_INFINITY);
+ return Double.NEGATIVE_INFINITY;
+ } else if (value.length() == 0) {
+ throw new DataModelParsingException(
+ "Empty value. (If you indeed wanted a 0 length string, quote it, like \"\".)");
+ } else {
+ return value;
+ }
+ }
+
+ private static String getMessageWithoutLocation(IOException e) {
+ return e instanceof JsonProcessingException
+ ? ((JsonProcessingException) e).getOriginalMessage()
+ : e.getMessage();
+ }
+
+ private static void checkKeywordCase(String inputKeyword, String correctKeyword) throws DataModelParsingException {
+ if (!correctKeyword.equals(inputKeyword)) {
+ throw new DataModelParsingException("Keywords are case sensitive; the correct form is: "
+ + correctKeyword);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/main/java/org/apache/freemarker/onlinetester/util/DataModelParsingException.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/onlinetester/util/DataModelParsingException.java b/src/main/java/org/apache/freemarker/onlinetester/util/DataModelParsingException.java
new file mode 100644
index 0000000..8c62127
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/onlinetester/util/DataModelParsingException.java
@@ -0,0 +1,39 @@
+/*
+ * 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.util;
+
+import java.util.TimeZone;
+
+/**
+ * Thrown by {@link DataModelParser#parse(String, TimeZone)}.
+ */
+public class DataModelParsingException extends Exception {
+
+ private static final long serialVersionUID = 1L;
+
+ public DataModelParsingException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public DataModelParsingException(String message) {
+ super(message);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/main/java/org/apache/freemarker/onlinetester/util/ExceptionUtils.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/onlinetester/util/ExceptionUtils.java b/src/main/java/org/apache/freemarker/onlinetester/util/ExceptionUtils.java
new file mode 100644
index 0000000..dfbe293
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/onlinetester/util/ExceptionUtils.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.util;
+
+import freemarker.core.ParseException;
+import freemarker.template.TemplateException;
+
+public final class ExceptionUtils {
+
+ private ExceptionUtils() {
+ // Not meant to be instantiated
+ }
+
+ /**
+ * The error message (and sometimes also the class), and then the same with the cause exception, and so on. Doesn't
+ * contain the stack trace or other location information.
+ */
+ public static String getMessageWithCauses(final Throwable exc) {
+ StringBuilder sb = new StringBuilder();
+
+ Throwable curExc = exc;
+ while (curExc != null) {
+ if (curExc != exc) {
+ sb.append("\n\nCaused by:\n");
+ }
+ String msg = curExc.getMessage();
+ if (msg == null || !(curExc instanceof TemplateException || curExc instanceof ParseException)) {
+ sb.append(curExc.getClass().getName()).append(": ");
+ }
+ sb.append(msg);
+ curExc = curExc.getCause();
+ }
+ return sb.toString();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/main/java/org/apache/freemarker/onlinetester/util/LengthLimitExceededException.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/onlinetester/util/LengthLimitExceededException.java b/src/main/java/org/apache/freemarker/onlinetester/util/LengthLimitExceededException.java
new file mode 100644
index 0000000..f7bb00c
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/onlinetester/util/LengthLimitExceededException.java
@@ -0,0 +1,35 @@
+/*
+ * 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.util;
+
+import java.io.IOException;
+
+/**
+ * Thrown by {@link LengthLimitedWriter}.
+ */
+public class LengthLimitExceededException extends IOException {
+
+ private static final long serialVersionUID = 1L;
+
+ public LengthLimitExceededException() {
+ super("The outout String length limit of the Writer was exceeded.");
+ }
+
+}
[2/5] incubator-freemarker-online-tester git commit: renamed the
package name to org/apache/freemarker/onlinetester
Posted by dd...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/main/java/org/apache/freemarker/onlinetester/util/LengthLimitedWriter.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/freemarker/onlinetester/util/LengthLimitedWriter.java b/src/main/java/org/apache/freemarker/onlinetester/util/LengthLimitedWriter.java
new file mode 100644
index 0000000..bb2650d
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/onlinetester/util/LengthLimitedWriter.java
@@ -0,0 +1,87 @@
+/*
+ * 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.util;
+
+import java.io.FilterWriter;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+
+/**
+ * A {@link StringWriter} that limits its buffer size, and throws {@link LengthLimitExceededException} when that's
+ * exceeded.
+ */
+public class LengthLimitedWriter extends FilterWriter {
+
+ private int lengthLeft;
+
+ public LengthLimitedWriter(Writer writer, int lengthLimit) {
+ super(writer);
+ this.lengthLeft = lengthLimit;
+ }
+
+ @Override
+ public void write(int c) throws IOException {
+ if (lengthLeft < 1) {
+ throw new LengthLimitExceededException();
+ }
+
+ super.write(c);
+
+ lengthLeft--;
+ }
+
+ @Override
+ public void write(char[] cbuf, int off, int len) throws IOException {
+ final boolean lengthExceeded;
+ if (lengthLeft < len) {
+ len = lengthLeft;
+ lengthExceeded = true;
+ } else {
+ lengthExceeded = false;
+ }
+
+ super.write(cbuf, off, len);
+ lengthLeft -= len;
+
+ if (lengthExceeded) {
+ throw new LengthLimitExceededException();
+ }
+ }
+
+ @Override
+ public void write(String str, int off, int len) throws IOException {
+ final boolean lengthExceeded;
+ if (lengthLeft < len) {
+ len = lengthLeft;
+ lengthExceeded = true;
+ } else {
+ lengthExceeded = false;
+ }
+
+ super.write(str, off, len);
+ lengthLeft -= len;
+
+ if (lengthExceeded) {
+ throw new LengthLimitExceededException();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/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
new file mode 100644
index 0000000..3aecbb5
--- /dev/null
+++ b/src/main/java/org/apache/freemarker/onlinetester/view/FreeMarkerOnlineView.java
@@ -0,0 +1,157 @@
+/*
+ * 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.view;
+
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+
+import org.apache.freemarker.onlinetester.model.SelectionOption;
+import org.apache.freemarker.onlinetester.services.AllowedSettingValuesMaps;
+import com.yammer.dropwizard.views.View;
+
+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 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 boolean execute;
+
+ private static List<SelectionOption> toSelectionOptions(Map<String, ?> settingValueMap) {
+ ArrayList<SelectionOption> selectionOptions = new ArrayList<SelectionOption>(settingValueMap.size());
+ for (String key : settingValueMap.keySet()) {
+ selectionOptions.add(new SelectionOption(key, truncate(key, 25)));
+ }
+ 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()));
+ }
+ Collections.sort(selectionOptions);
+ return selectionOptions;
+ }
+
+ private static String truncate(String s, int maxLength) {
+ if (s == null) {
+ return null;
+ }
+ return s.length() <= maxLength ? s : s.substring(0, Math.max(maxLength - 3, 0)) + "[...]";
+ }
+
+ /**
+ *
+ * @param template
+ * @param dataModel
+ * @param execute set to true if the execution should be triggered on page load.
+ */
+ public FreeMarkerOnlineView() {
+ super("/view/freemarker-online.ftl", Charset.forName("utf-8"));
+ }
+
+ public String getTemplate() {
+ return template;
+ }
+
+ public void setTemplate(String template) {
+ this.template = withDefault(template, "");
+ }
+
+ public String getDataModel() {
+ return dataModel;
+ }
+
+ public void setDataModel(String dataModel) {
+ this.dataModel = withDefault(dataModel, "");
+ }
+
+ public String getFreeMarkerVersion() {
+ return Configuration.getVersion().toString();
+ }
+
+ public List<SelectionOption> getOutputFormats() {
+ return OUTPUT_FORMAT_SELECTION_OPTIONS;
+ }
+
+ public List<SelectionOption> getLocales() {
+ return LOCALE_SELECTION_OPTIONS;
+ }
+
+ public List<SelectionOption> getTimeZones() {
+ return TIME_ZONE_SELECTION_OPTIONS;
+ }
+
+ public String getOutputFormat() {
+ return outputFormat;
+ }
+
+ public void setOutputFormat(String outputFormat) {
+ this.outputFormat = withDefault(outputFormat, AllowedSettingValuesMaps.DEFAULT_OUTPUT_FORMAT_KEY);
+ }
+
+ public String getLocale() {
+ return locale;
+ }
+
+ public void setLocale(String locale) {
+ this.locale = withDefault(locale, AllowedSettingValuesMaps.DEFAULT_LOCALE_KEY);
+ }
+
+ public String getTimeZone() {
+ return timeZone;
+ }
+
+ public void setTimeZone(String timeZone) {
+ this.timeZone = withDefault(timeZone, AllowedSettingValuesMaps.DEFAULT_TIME_ZONE_KEY);
+ }
+
+ public boolean isExecute() {
+ return execute;
+ }
+
+ public void setExecute(boolean executeImmediately) {
+ this.execute = executeImmediately;
+ }
+
+ private static String withDefault(String value, String defaultValue) {
+ return !StringUtils.isBlank(value) ? value : defaultValue;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/main/resources/spring/bootstrap-context.xml
----------------------------------------------------------------------
diff --git a/src/main/resources/spring/bootstrap-context.xml b/src/main/resources/spring/bootstrap-context.xml
index db4bf9b..8d8e518 100644
--- a/src/main/resources/spring/bootstrap-context.xml
+++ b/src/main/resources/spring/bootstrap-context.xml
@@ -24,7 +24,7 @@
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd ">
- <context:component-scan base-package="com.kenshoo"/>
+ <context:component-scan base-package="org.apache.freemarker.onlinetester"/>
<context:annotation-config/>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/test/java/com/kenshoo/freemarker/platform/DropWizardServiceTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/com/kenshoo/freemarker/platform/DropWizardServiceTest.java b/src/test/java/com/kenshoo/freemarker/platform/DropWizardServiceTest.java
deleted file mode 100644
index 312ed0b..0000000
--- a/src/test/java/com/kenshoo/freemarker/platform/DropWizardServiceTest.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2014 Kenshoo.com
- *
- * Licensed 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 com.kenshoo.freemarker.platform;
-
-import com.google.common.io.Resources;
-import com.kenshoo.freemarker.dropwizard.ApplicationStartup;
-import com.yammer.dropwizard.testing.junit.DropwizardServiceRule;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.rules.TestRule;
-
-public class DropWizardServiceTest {
- @ClassRule
- public static TestRule testRule = new DropwizardServiceRule<>(ApplicationStartup.class,
- Resources.getResource("freemarker-online.yml").getPath());
-
-
- @Test
- public void testServerIsUp() throws Exception {
- ((DropwizardServiceRule) testRule).getService();
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/test/java/com/kenshoo/freemarker/platform/YamlPropertiesPersister.java
----------------------------------------------------------------------
diff --git a/src/test/java/com/kenshoo/freemarker/platform/YamlPropertiesPersister.java b/src/test/java/com/kenshoo/freemarker/platform/YamlPropertiesPersister.java
deleted file mode 100644
index 1299581..0000000
--- a/src/test/java/com/kenshoo/freemarker/platform/YamlPropertiesPersister.java
+++ /dev/null
@@ -1,91 +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 com.kenshoo.freemarker.platform;
-
-import com.fasterxml.jackson.dataformat.yaml.snakeyaml.Yaml;
-import org.springframework.util.PropertiesPersister;
-import org.springframework.util.StringUtils;
-
-import java.io.*;
-import java.util.Map;
-import java.util.Properties;
-
-public class YamlPropertiesPersister implements PropertiesPersister {
- @Override
- public void load(Properties props, InputStream is) throws IOException {
- load(props, new InputStreamReader(is));
- }
-
- /**
- * We want to traverse map representing Yaml object and each time we find String=String pair we want to
- * save it as Property. As we are going deeper into map we generate compound key as path-like String
- *
- * @see org.springframework.util.PropertiesPersister#load(java.util.Properties, java.io.Reader)
- */
- @Override
- public void load(Properties props, Reader reader) throws IOException {
- Yaml yaml = new Yaml();
- @SuppressWarnings("unchecked")
- Map<String, Object> map = (Map<String, Object>) yaml.load(reader);
- // now we can populate supplied props
- assignProperties(props, map, null);
- }
-
- @SuppressWarnings("unchecked")
- public void assignProperties(Properties props, Map<String, Object> map, String path) {
- for (Map.Entry<String, Object> entry : map.entrySet()) {
- String key = entry.getKey();
- if (!StringUtils.isEmpty(path))
- key = path + "." + key;
- Object val = entry.getValue();
- if (val instanceof String) {
- // see if we need to create a compound key
- props.put(key, val);
- } else if (val instanceof Map) {
- assignProperties(props, (Map<String, Object>) val, key);
- }
- }
- }
-
- @Override
- public void store(Properties props, OutputStream os, String header) throws IOException {
- throw new IllegalStateException("Current implementation is a read-only");
- }
-
- @Override
- public void store(Properties props, Writer writer, String header) throws IOException {
- throw new IllegalStateException("Current implementation is a read-only");
- }
-
- @Override
- public void loadFromXml(Properties props, InputStream is) throws IOException {
- throw new IllegalStateException("Use DefaultPropertiesPersister if you want to read/write XML");
- }
-
- @Override
- public void storeToXml(Properties props, OutputStream os, String header) throws IOException {
- throw new IllegalStateException("Use DefaultPropertiesPersister if you want to load/store to XML");
- }
-
- @Override
- public void storeToXml(Properties props, OutputStream os, String header, String encoding) throws IOException {
- throw new IllegalStateException("Use DefaultPropertiesPersister if you want to read/write XML");
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/test/java/com/kenshoo/freemarker/resources/FreeMarkerOnlineExecuteResourceTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/com/kenshoo/freemarker/resources/FreeMarkerOnlineExecuteResourceTest.java b/src/test/java/com/kenshoo/freemarker/resources/FreeMarkerOnlineExecuteResourceTest.java
deleted file mode 100644
index e7ca204..0000000
--- a/src/test/java/com/kenshoo/freemarker/resources/FreeMarkerOnlineExecuteResourceTest.java
+++ /dev/null
@@ -1,159 +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 com.kenshoo.freemarker.resources;
-
-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 org.junit.Test;
-import org.springframework.web.context.ContextLoaderListener;
-import org.springframework.web.context.request.RequestContextListener;
-
-import com.kenshoo.freemarker.model.ExecuteRequest;
-import com.kenshoo.freemarker.model.ExecuteResourceField;
-import com.kenshoo.freemarker.model.ExecuteResourceProblem;
-import com.kenshoo.freemarker.model.ExecuteResponse;
-import com.sun.jersey.api.client.ClientResponse;
-import com.sun.jersey.spi.spring.container.servlet.SpringServlet;
-import com.sun.jersey.test.framework.AppDescriptor;
-import com.sun.jersey.test.framework.JerseyTest;
-import com.sun.jersey.test.framework.WebAppDescriptor;
-
-public class FreeMarkerOnlineExecuteResourceTest extends JerseyTest {
- private static final String DATA_MODEL = "user=John";
- private static final String TEMPLATE_WITH_VARIABLE = "Welcome ${user}";
- private static final String TEMPLATE_PLAIN = "Welcome John";
- private static final String MALFORMED_DATA_MODEL = "userJohn";
- private static final String EXECUTE_API = "api/execute";
- @Override
- protected AppDescriptor configure() {
- return new WebAppDescriptor.Builder("com.kenshoo.freemarker.resources")
- .contextPath("/")
- .contextListenerClass(ContextLoaderListener.class)
- .contextParam("contextConfigLocation", "classpath:spring/bootstrap-context.xml")
- .servletClass(SpringServlet.class)
- .requestListenerClass(RequestContextListener.class)
- .build();
- }
-
- @Test
- public void testSuccessRequest() throws Exception {
- ExecuteRequest req = new ExecuteRequest(TEMPLATE_WITH_VARIABLE, DATA_MODEL);
- ClientResponse resp = client().resource(getBaseURI().toString() + EXECUTE_API)
- .header("Content-Type", "application/json").entity(req).post(ClientResponse.class);
- assertEquals(200, resp.getStatus());
- ExecuteResponse response = resp.getEntity(ExecuteResponse.class);
- assertNull(response.getProblems());
- }
-
- @Test
- public void testMalformedDataModel() throws Exception {
- ExecuteRequest req = new ExecuteRequest(TEMPLATE_PLAIN, MALFORMED_DATA_MODEL);
- ClientResponse resp = client().resource(getBaseURI().toString() + EXECUTE_API)
- .header("Content-Type", "application/json").entity(req).post(ClientResponse.class);
- assertEquals(200, resp.getStatus());
- ExecuteResponse response = resp.getEntity(ExecuteResponse.class);
- assertNotNull(response.getProblems());
- assertTrue(containsProblem(response, ExecuteResourceField.DATA_MODEL));
- }
-
- @Test
- public void testLongDataModel() throws Exception {
- ExecuteRequest req = new ExecuteRequest(TEMPLATE_PLAIN, create30KString());
- ClientResponse resp = client().resource(getBaseURI().toString() + EXECUTE_API)
- .header("Content-Type", "application/json").entity(req).post(ClientResponse.class);
- assertEquals(200, resp.getStatus());
- ExecuteResponse response = resp.getEntity(ExecuteResponse.class);
- assertNotNull(response.getProblems());
- assertTrue(containsProblem(response, ExecuteResourceField.DATA_MODEL));
- String problemMessage = getProblemMessage(response, ExecuteResourceField.DATA_MODEL);
- assertThat(problemMessage, containsString("data model"));
- assertThat(problemMessage, containsString("limit"));
- }
-
- @Test
- public void testLongTemplate() throws Exception {
- ExecuteRequest req = new ExecuteRequest(create30KString(), DATA_MODEL);
- ClientResponse resp = client().resource(getBaseURI().toString() + EXECUTE_API)
- .header("Content-Type", "application/json").entity(req).post(ClientResponse.class);
- assertEquals(200, resp.getStatus());
- ExecuteResponse response = resp.getEntity(ExecuteResponse.class);
- assertNotNull(response.getProblems());
- assertTrue(containsProblem(response, ExecuteResourceField.TEMPLATE));
- String problemMessage = getProblemMessage(response, ExecuteResourceField.TEMPLATE);
- assertThat(problemMessage, containsString("template"));
- assertThat(problemMessage, containsString("limit"));
- }
-
- @Test
- public void testMultipleErrorsDataModel() throws Exception {
- ExecuteRequest req = new ExecuteRequest(create30KString(), create30KString());
- req.setOutputFormat("wrongOutputFormat");
- req.setLocale("wrongLocale");
- req.setTimeZone("wrongTimeZone");
-
- ClientResponse resp = client().resource(getBaseURI() + EXECUTE_API)
- .header("Content-Type", "application/json").entity(req).post(ClientResponse.class);
-
- assertEquals(200, resp.getStatus());
- ExecuteResponse response = resp.getEntity(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"));
- }
-
- private String create30KString() {
- final String veryLongString;
- {
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < 30000 / 10; i++) {
- sb.append("0123456789");
- }
- veryLongString = sb.toString();
- }
- return veryLongString;
- }
-
- private boolean containsProblem(ExecuteResponse response, ExecuteResourceField field) {
- for (ExecuteResourceProblem problem : response.getProblems()) {
- if (problem.getField() == field) {
- return true;
- }
- }
- return false;
- }
-
- private String getProblemMessage(ExecuteResponse response, ExecuteResourceField field) {
- for (ExecuteResourceProblem problem : response.getProblems()) {
- if (problem.getField() == field) {
- return problem.getMessage();
- }
- }
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/test/java/com/kenshoo/freemarker/resources/FreeMarkerOnlineResourceTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/com/kenshoo/freemarker/resources/FreeMarkerOnlineResourceTest.java b/src/test/java/com/kenshoo/freemarker/resources/FreeMarkerOnlineResourceTest.java
deleted file mode 100644
index 6b3df76..0000000
--- a/src/test/java/com/kenshoo/freemarker/resources/FreeMarkerOnlineResourceTest.java
+++ /dev/null
@@ -1,70 +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 com.kenshoo.freemarker.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.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
-
-import com.kenshoo.freemarker.services.FreeMarkerService;
-import com.kenshoo.freemarker.view.FreeMarkerOnlineView;
-
-import freemarker.core.OutputFormat;
-
-@RunWith(MockitoJUnitRunner.class)
-public class FreeMarkerOnlineResourceTest {
-
- @InjectMocks
- FreeMarkerOnlineResource freeMarkerOnlineResultResource;
-
- @Mock
- FreeMarkerService freeMarkerService;
-
- @Test
- public void testInitialForm() {
- when(freeMarkerService.calculateTemplateOutput(
- anyString(), anyMap(), any(OutputFormat.class), any(Locale.class), any(TimeZone.class)))
- .thenThrow(new AssertionError());
- FreeMarkerOnlineView view = freeMarkerOnlineResultResource.blankForm();
- assertEquals(view.getTemplate(), "");
- assertEquals(view.getDataModel(), "");
- }
-
- @Test
- public void testPostedBlankForm() {
- when(freeMarkerService.calculateTemplateOutput(
- anyString(), anyMap(), any(OutputFormat.class), any(Locale.class), any(TimeZone.class)))
- .thenThrow(new AssertionError());
- FreeMarkerOnlineView view = freeMarkerOnlineResultResource.formResult(null, null, null, null, null);
- assertEquals(view.getTemplate(), "");
- assertEquals(view.getDataModel(), "");
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/test/java/com/kenshoo/freemarker/services/FreeMarkerServiceResponseBuilderTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/com/kenshoo/freemarker/services/FreeMarkerServiceResponseBuilderTest.java b/src/test/java/com/kenshoo/freemarker/services/FreeMarkerServiceResponseBuilderTest.java
deleted file mode 100644
index caf5ca4..0000000
--- a/src/test/java/com/kenshoo/freemarker/services/FreeMarkerServiceResponseBuilderTest.java
+++ /dev/null
@@ -1,61 +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 com.kenshoo.freemarker.services;
-
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
-
-import org.junit.Test;
-
-public class FreeMarkerServiceResponseBuilderTest {
-
- private static final String RESULT = "Result";
-
- private final FreeMarkerServiceResponse.Builder builder = new FreeMarkerServiceResponse.Builder();
-
- @Test
- public void testSuccessResult() {
- FreeMarkerServiceResponse result = builder.buildForSuccess(RESULT, false);
- assertThat(result.getTemplateOutput(), equalTo(RESULT));
- assertThat(result.isTemplateOutputTruncated(), is(false));
- assertThat(result.isSuccesful(), is(true));
- assertThat(result.getFailureReason(), nullValue());
- }
-
- @Test
- public void testSuccessTruncatedResult() {
- FreeMarkerServiceResponse result = builder.buildForSuccess(RESULT, true);
- assertThat(result.getTemplateOutput(), equalTo(RESULT));
- assertThat(result.isTemplateOutputTruncated(), is(true));
- assertThat(result.isSuccesful(), is(true));
- assertThat(result.getFailureReason(), nullValue());
- }
-
- @Test
- public void testErrorResult() {
- Throwable failureReason = new Exception();
- FreeMarkerServiceResponse result = builder.buildForFailure(failureReason);
- assertThat(result.getTemplateOutput(), nullValue());
- assertThat(result.isTemplateOutputTruncated(), is(false));
- assertThat(result.isSuccesful(), is(false));
- assertThat(result.getFailureReason(), sameInstance(failureReason));
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/test/java/com/kenshoo/freemarker/services/FreeMarkerServiceTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/com/kenshoo/freemarker/services/FreeMarkerServiceTest.java b/src/test/java/com/kenshoo/freemarker/services/FreeMarkerServiceTest.java
deleted file mode 100644
index 6608d52..0000000
--- a/src/test/java/com/kenshoo/freemarker/services/FreeMarkerServiceTest.java
+++ /dev/null
@@ -1,308 +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 com.kenshoo.freemarker.services;
-
-import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.greaterThan;
-import static org.hamcrest.Matchers.instanceOf;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.not;
-import static org.hamcrest.Matchers.startsWith;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.fail;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-import java.util.TimeZone;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.RejectedExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InjectMocks;
-import org.mockito.runners.MockitoJUnitRunner;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import freemarker.core.Environment;
-import freemarker.core.HTMLOutputFormat;
-import freemarker.core.ParseException;
-import freemarker.template.TemplateDirectiveBody;
-import freemarker.template.TemplateDirectiveModel;
-import freemarker.template.TemplateException;
-import freemarker.template.TemplateModel;
-
-@RunWith(MockitoJUnitRunner.class)
-public class FreeMarkerServiceTest {
-
- private static final Logger LOG = LoggerFactory.getLogger(FreeMarkerServiceTest.class);
-
- private static final int MAX_THREADS = 3;
- private static final int MAX_QUEUE_LENGTH = 2;
- private static final int MAX_TEMPLATE_EXECUTION_TIME = 1500;
-
- private static final int BLOCKING_TEST_TIMEOUT = 5000;
-
- private static final String TRUNCATION_TEST_TEMPLATE = "12345";
-
- @InjectMocks
- private FreeMarkerService freeMarkerService;
-
- @Before
- public void initializeSpringBeans() {
- freeMarkerService.setMaxQueueLength(MAX_QUEUE_LENGTH);
- freeMarkerService.setMaxThreads(MAX_THREADS);
- freeMarkerService.postConstruct();
- freeMarkerService.setMaxTemplateExecutionTime(MAX_TEMPLATE_EXECUTION_TIME);
- }
-
- @Test
- public void testCalculationOfATemplateWithNoDataModel() {
- FreeMarkerServiceResponse serviceResponse = freeMarkerService.calculateTemplateOutput(
- "test", Collections.<String, Object>emptyMap(), null, null, null);
- assertThat(serviceResponse.isSuccesful(), is(true));
- assertThat(serviceResponse.getTemplateOutput(), is("test"));
- }
-
- @Test
- public void testSimpleTemplate() {
- HashMap<String, Object> dataModel = new HashMap<>();
- dataModel.put("var1", "val1");
- String templateSourceCode = "${var1}";
- FreeMarkerServiceResponse serviceResponse = freeMarkerService.calculateTemplateOutput(
- templateSourceCode, dataModel, null, null, null);
- assertThat(serviceResponse.getTemplateOutput(), equalTo("val1"));
- }
-
- @Test
- public void testTemplateWithFewArgsAndOperators() {
- HashMap<String, Object> dataModel = new HashMap<>();
- dataModel.put("var1", "val1");
- dataModel.put("var2", "val2");
- String template = "${var1?capitalize} ${var2?cap_first}";
- FreeMarkerServiceResponse serviceResponse = freeMarkerService.calculateTemplateOutput(
- template, dataModel, null, null, null);
- assertThat(serviceResponse.getTemplateOutput(), equalTo("Val1 Val2"));
- }
-
- @Test
- public void testOutputFormatParamterMatters() {
- String template = "${'&'}";
- {
- FreeMarkerServiceResponse serviceResponse = freeMarkerService.calculateTemplateOutput(
- template, null, null, null, null);
- assertThat(serviceResponse.getTemplateOutput(), equalTo("&"));
- }
- {
- FreeMarkerServiceResponse serviceResponse = freeMarkerService.calculateTemplateOutput(
- template, null, HTMLOutputFormat.INSTANCE, null, null);
- assertThat(serviceResponse.getTemplateOutput(), equalTo("&"));
- }
- }
-
- @Test
- public void testLocaleParameterMatters() {
- String template = "${.locale}";
- {
- FreeMarkerServiceResponse serviceResponse = freeMarkerService.calculateTemplateOutput(
- template, null, null, new Locale("en", "US"), null);
- assertThat(serviceResponse.getTemplateOutput(), equalTo("en_US"));
- }
- {
- FreeMarkerServiceResponse serviceResponse = freeMarkerService.calculateTemplateOutput(
- template, null, null, new Locale("ru", "RU"), null);
- assertThat(serviceResponse.getTemplateOutput(), equalTo("ru_RU"));
- }
- }
-
- @Test
- public void testTimeZoneParameterMatters() {
- String template = "${" + System.currentTimeMillis() + "?numberToDatetime}";
-
- String gmt1Result;
- {
- FreeMarkerServiceResponse serviceResponse = freeMarkerService.calculateTemplateOutput(
- template, null, null, null, TimeZone.getTimeZone("GMT+01"));
- gmt1Result = serviceResponse.getTemplateOutput();
- }
-
- String gmt2Result;
- {
- FreeMarkerServiceResponse serviceResponse = freeMarkerService.calculateTemplateOutput(
- template, null, null, new Locale("ru", "RU"), null);
- gmt2Result = serviceResponse.getTemplateOutput();
- }
-
- assertThat(gmt1Result, not(equalTo(gmt2Result)));
- }
-
- @Test
- public void testTemplateWithSyntaxError() {
- FreeMarkerServiceResponse serviceResponse = freeMarkerService.calculateTemplateOutput(
- "test ${xx", Collections.<String, Object>emptyMap(), null, null, null);
- assertThat(serviceResponse.isSuccesful(), is(false));
- assertThat(serviceResponse.getFailureReason(), instanceOf(ParseException.class));
- }
-
- @Test
- public void testTemplateWithEvaluationError() {
- FreeMarkerServiceResponse serviceResponse = freeMarkerService.calculateTemplateOutput(
- "test ${x}", Collections.<String, Object>emptyMap(), null, null, null);
- assertThat(serviceResponse.isSuccesful(), is(false));
- assertThat(serviceResponse.getFailureReason(), instanceOf(TemplateException.class));
- }
-
- @Test
- public void testResultAlmostTruncation() {
- freeMarkerService.setMaxOutputLength(5);
- FreeMarkerServiceResponse serviceResponse = freeMarkerService.calculateTemplateOutput(
- TRUNCATION_TEST_TEMPLATE, Collections.<String, Object>emptyMap(), null, null, null);
- assertThat(serviceResponse.isSuccesful(), is(true));
- assertThat(serviceResponse.isTemplateOutputTruncated(), is(false));
- assertThat(serviceResponse.getTemplateOutput(), equalTo(TRUNCATION_TEST_TEMPLATE));
- }
-
- @Test
- public void testResultTruncation() {
- freeMarkerService.setMaxOutputLength(4);
- FreeMarkerServiceResponse serviceResponse = freeMarkerService.calculateTemplateOutput(
- TRUNCATION_TEST_TEMPLATE, Collections.<String, Object>emptyMap(), null, null, null);
- assertThat(serviceResponse.isSuccesful(), is(true));
- assertThat(serviceResponse.isTemplateOutputTruncated(), is(true));
- assertThat(serviceResponse.getTemplateOutput(),
- startsWith(TRUNCATION_TEST_TEMPLATE.substring(0, freeMarkerService.getMaxOutputLength())));
- assertThat(serviceResponse.getTemplateOutput().charAt(freeMarkerService.getMaxOutputLength()),
- not(equalTo(TRUNCATION_TEST_TEMPLATE.charAt(freeMarkerService.getMaxOutputLength()))));
- }
-
- @Test
- public void testTemplateExecutionTimeout() throws InterruptedException, ExecutionException {
- freeMarkerService.setMaxTemplateExecutionTime(200);
-
- // To avoid blocking the CI server forever without giving error:
- Future<FreeMarkerServiceResponse> future = Executors.newSingleThreadExecutor().submit(
- new Callable<FreeMarkerServiceResponse>() {
-
- @Override
- public FreeMarkerServiceResponse call() throws Exception {
- return freeMarkerService.calculateTemplateOutput(
- "<#list 1.. as _></#list>", Collections.<String, Object>emptyMap(), null, null, null);
- }
-
- });
- FreeMarkerServiceResponse serviceResponse;
- try {
- serviceResponse = future.get(BLOCKING_TEST_TIMEOUT, TimeUnit.MILLISECONDS);
- } catch (TimeoutException e) {
- throw new AssertionError("The template execution wasn't aborted (within the timeout).");
- }
- assertThat(serviceResponse.isSuccesful(), is(false));
- assertThat(serviceResponse.getFailureReason(), instanceOf(TimeoutException.class));
- }
-
- @Test
- public void testServiceOverburden() throws InterruptedException {
- final BlockerDirective blocker = new BlockerDirective();
- final Map<String, BlockerDirective> blockerDataModel = Collections.singletonMap("blocker", blocker);
- try {
- // Fill all available task "slots":
- for (int i = 0; i < MAX_THREADS + MAX_QUEUE_LENGTH; i++) {
- new Thread(new Runnable() {
- @Override
- public void run() {
- freeMarkerService.calculateTemplateOutput("<@blocker/>", blockerDataModel, null, null, null);
- }
- }).start();
- }
-
- // Wait until all template executions has started:
- synchronized (blocker) {
- final long startTime = System.currentTimeMillis();
- while (blocker.getEntered() < MAX_THREADS) {
- // To avoid blocking the CI server forever is something goes wrong:
- if (System.currentTimeMillis() - startTime > BLOCKING_TEST_TIMEOUT) {
- fail("JUnit test timed out");
- }
- blocker.wait(1000);
- }
- }
- Thread.sleep(200);
- // Because the others are waiting in the queue, and weren't started:
- assertThat(blocker.getEntered(), not(greaterThan(MAX_THREADS)));
-
- // Souldn't accept on more tasks:
- try {
- freeMarkerService.calculateTemplateOutput("<@blocker/>", blockerDataModel, null, null, null);
- fail("Expected RejectedExecutionException, but nothing was thrown.");
- } catch (RejectedExecutionException e) {
- // Expected
- }
- } finally {
- // Ensure that the started threads will end:
- blocker.release();
- }
- }
-
- private static final class BlockerDirective implements TemplateDirectiveModel {
-
- private int entered;
- private boolean released;
-
- public synchronized void release() {
- released = true;
- notifyAll();
- }
-
- @Override
- public synchronized void execute(Environment env, @SuppressWarnings("rawtypes") Map params,
- TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException {
- entered++;
- notifyAll();
- final long startTime = System.currentTimeMillis();
- while (!released) {
- // To avoid blocking the CI server forever is something goes wrong:
- if (System.currentTimeMillis() - startTime > BLOCKING_TEST_TIMEOUT) {
- LOG.error("JUnit test timed out");
- }
- try {
- wait(1000);
- } catch (InterruptedException e) {
- LOG.error("JUnit test was interrupted");
- }
- }
- LOG.debug("Blocker released");
- }
-
- public synchronized int getEntered() {
- return entered;
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/test/java/com/kenshoo/freemarker/util/DataModelParserTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/com/kenshoo/freemarker/util/DataModelParserTest.java b/src/test/java/com/kenshoo/freemarker/util/DataModelParserTest.java
deleted file mode 100644
index f651fb8..0000000
--- a/src/test/java/com/kenshoo/freemarker/util/DataModelParserTest.java
+++ /dev/null
@@ -1,281 +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 com.kenshoo.freemarker.util;
-
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
-
-import java.math.BigDecimal;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.util.GregorianCalendar;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.junit.Test;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-import freemarker.template.utility.DateUtil;
-
-public class DataModelParserTest {
-
- @Test
- public void testEmpty() throws DataModelParsingException {
- assertTrue(DataModelParser.parse("", DateUtil.UTC).isEmpty());
- assertTrue(DataModelParser.parse(" \n ", DateUtil.UTC).isEmpty());
- }
-
- @Test
- public void testSingleAssignment() throws DataModelParsingException {
- assertEquals(ImmutableMap.of("n", "v"), DataModelParser.parse("n=v", DateUtil.UTC));
- assertEquals(ImmutableMap.of("n", "v"), DataModelParser.parse("\n\n\tn\t= v", DateUtil.UTC));
- assertEquals(ImmutableMap.of("longerN", "longer v"), DataModelParser.parse("longerN=longer v", DateUtil.UTC));
- assertEquals(ImmutableMap.of("a:b.c-d$@", "foo bar\nbaaz"), DataModelParser.parse("a:b.c-d$@ = foo bar\nbaaz", DateUtil.UTC));
- }
-
- @Test
- public void testNotBlankButHasNoAssignment() {
- try {
- DataModelParser.parse("x", DateUtil.UTC);
- fail();
- } catch (DataModelParsingException e) {
- assertThat(e.getMessage(), containsString("must start with an assignment"));
- }
- }
-
- @Test
- public void testNoLinebreakBeforeEquals() {
- try {
- DataModelParser.parse("x\n=y", DateUtil.UTC);
- fail();
- } catch (DataModelParsingException e) {
- assertThat(e.getMessage(), containsString("must start with an assignment"));
- }
- }
-
- @Test
- public void testMultipleAssignments() throws DataModelParsingException {
- assertEquals(ImmutableMap.of("n1", "v1", "n2", "v2", "n3", "v3"),
- DataModelParser.parse("n1=v1\nn2=v2\nn3=v3", DateUtil.UTC));
- assertEquals(ImmutableMap.of("n1", "v1", "n2", "v2", "n3", "v3"),
- DataModelParser.parse(" n1 = v1 \r\n\r\n\tn2=v2\nn3 = v3\n\n", DateUtil.UTC));
- assertEquals(ImmutableMap.of("n1", "=\n=v", "n2", "l1\nl2\n\nl3", "n3", "v3"),
- DataModelParser.parse("n1==\n=v \n n2=l1\nl2\n\nl3\nn3=v3", DateUtil.UTC));
- }
-
- @Test
- public void testStrings() throws DataModelParsingException {
- assertEquals(
- ImmutableMap.of(
- "a", "C:\\x",
- "b", "foo\nbar",
- "c", "foo\t\"bar\"",
- "d", "foo\t\"bar\"",
- "e", "Foo's"
- ),
- DataModelParser.parse(
- "a=C:\\x\n"
- + "b=foo\nbar\n"
- + "c=foo\t\"bar\"\n"
- + "d=\"foo\\t\\\"bar\\\"\"\n"
- + "e=\"Foo's\"",
- DateUtil.UTC));
- try {
- DataModelParser.parse("a=\"foo", DateUtil.UTC);
- fail();
- } catch (DataModelParsingException e) {
- assertThat(e.getMessage(), containsString("quoted"));
- }
- try {
- DataModelParser.parse("a='foo'", DateUtil.UTC);
- fail();
- } catch (DataModelParsingException e) {
- assertThat(e.getMessage(), containsString("quoted"));
- }
- try {
- DataModelParser.parse("a=\"\\x\"", DateUtil.UTC);
- fail();
- } catch (DataModelParsingException e) {
- assertThat(e.getMessage(), containsString("escape"));
- }
- }
-
- @Test
- public void testBasicNumbers() throws DataModelParsingException {
- assertEquals(
- ImmutableMap.of(
- "a", BigDecimal.valueOf(1),
- "b", BigDecimal.valueOf(1.5),
- "c", BigDecimal.valueOf(-1.5),
- "d", BigDecimal.valueOf(1.5),
- "e", BigDecimal.valueOf(-0.125)
- ),
- DataModelParser.parse("a=1\nb=1.5\nc=-1.5\nd=+1.5\ne=-12.5e-2", DateUtil.UTC));
- try {
- DataModelParser.parse("a=1,5", DateUtil.UTC);
- fail();
- } catch (DataModelParsingException e) {
- assertThat(e.getMessage(), containsString("Malformed number"));
- assertThat(e.getMessage(), not(containsString("ISO")));
- }
- }
-
- @Test
- public void testSpecialNumbers() throws DataModelParsingException {
- assertEquals(
- ImmutableMap.of(
- "a", Double.NaN,
- "b", Double.POSITIVE_INFINITY,
- "c", Double.NEGATIVE_INFINITY,
- "d", Double.POSITIVE_INFINITY
- ),
- DataModelParser.parse("a=NaN\nb=Infinity\nc=-Infinity\nd=+Infinity", DateUtil.UTC));
- }
-
- @Test
- public void testBooleans() throws DataModelParsingException {
- assertEquals(ImmutableMap.of("a", true, "b", false), DataModelParser.parse("a=true\nb=false", DateUtil.UTC));
- try {
- DataModelParser.parse("a=True", DateUtil.UTC);
- fail();
- } catch (DataModelParsingException e) {
- assertThat(e.getMessage(), containsString("true"));
- }
- }
-
- @Test
- public void testTemporals() throws DataModelParsingException {
- final Map<String, Object> dm = DataModelParser.parse("a=2014-02-12T01:02:03Z\nb=2014-02-12\nc=01:02:03Z", DateUtil.UTC);
-
- final GregorianCalendar cal = new GregorianCalendar(DateUtil.UTC);
- cal.clear();
-
- cal.set(2014, 1, 12, 1, 2, 3);
- Timestamp a = new Timestamp(cal.getTimeInMillis());
- assertThat(dm.get("a"), instanceOf(Timestamp.class));
- assertEquals(dm.get("a"), a);
-
- cal.set(2014, 1, 12, 0, 0, 0);
- java.sql.Date b = new java.sql.Date(cal.getTimeInMillis());
- assertThat(dm.get("b"), instanceOf(java.sql.Date.class));
- assertEquals(dm.get("b"), b);
-
- cal.set(1970, 0, 1, 1, 2, 3);
- Time c = new Time(cal.getTimeInMillis());
- assertThat(dm.get("c"), instanceOf(Time.class));
- assertEquals(dm.get("c"), c);
-
- try {
- DataModelParser.parse("a=2012T123", DateUtil.UTC);
- fail();
- } catch (DataModelParsingException e) {
- assertThat(e.getMessage(), containsString("ISO 8601 date-time"));
- }
- try {
- DataModelParser.parse("a=2012-0102", DateUtil.UTC);
- fail();
- } catch (DataModelParsingException e) {
- assertThat(e.getMessage(), containsString("ISO 8601 date"));
- }
- try {
- DataModelParser.parse("a=25:00", DateUtil.UTC);
- fail();
- } catch (DataModelParsingException e) {
- assertThat(e.getMessage(), containsString("ISO 8601 time"));
- }
- }
-
- @Test
- public void testMaps() throws DataModelParsingException {
- final Object map = DataModelParser.parse(
- "n = {\n"
- + "\t\"a\": 1,\n"
- + "\t\"b\": 2\n"
- + "}",
- DateUtil.UTC)
- .get("n");
- assertEquals(ImmutableMap.of("a", 1, "b", 2), map);
- assertThat(map, instanceOf(LinkedHashMap.class));
- try {
- DataModelParser.parse("n={1:2}", DateUtil.UTC);
- fail();
- } catch (DataModelParsingException e) {
- assertThat(e.getMessage(), containsString("JSON"));
- }
- }
-
- @Test
- public void testLists() throws DataModelParsingException {
- final Object list = DataModelParser.parse("n=[1, 2]", DateUtil.UTC).get("n");
- assertEquals(ImmutableList.of(1, 2), list);
- assertThat(list, instanceOf(List.class));
- try {
- DataModelParser.parse("n=[", DateUtil.UTC);
- fail();
- } catch (DataModelParsingException e) {
- assertThat(e.getMessage(), containsString("JSON"));
- }
- }
-
- @Test
- public void testXML() throws DataModelParsingException {
- final Object doc = DataModelParser.parse("n=<e xmlns='foo:/bar' a='123'>text</e>", DateUtil.UTC).get("n");
- assertThat(doc, instanceOf(Document.class));
- final Node firstChild = ((Document) doc).getFirstChild();
- assertEquals("e", firstChild.getNodeName());
- assertEquals("foo:/bar", firstChild.getNamespaceURI());
-
- try {
- DataModelParser.parse("n=<ns:e />", DateUtil.UTC);
- fail();
- } catch (DataModelParsingException e) {
- assertThat(e.getMessage(), containsString("XML"));
- }
- }
-
- @Test
- public void testNull() throws DataModelParsingException {
- assertNull(DataModelParser.parse("n=null", DateUtil.UTC).get("n"));
- try {
- DataModelParser.parse("a=NULL", DateUtil.UTC);
- fail();
- } catch (DataModelParsingException e) {
- assertThat(e.getMessage(), containsString("null"));
- }
- }
-
- @Test
- public void testEmptyValue() throws DataModelParsingException {
- try {
- DataModelParser.parse("n=", DateUtil.UTC);
- fail();
- } catch (DataModelParsingException e) {
- assertThat(e.getMessage(), containsString("Empty"));
- }
-
- assertEquals("", DataModelParser.parse("n=\"\"", DateUtil.UTC).get("n"));
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/test/java/com/kenshoo/freemarker/util/LengthLimitedWriterTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/com/kenshoo/freemarker/util/LengthLimitedWriterTest.java b/src/test/java/com/kenshoo/freemarker/util/LengthLimitedWriterTest.java
deleted file mode 100644
index c56d52e..0000000
--- a/src/test/java/com/kenshoo/freemarker/util/LengthLimitedWriterTest.java
+++ /dev/null
@@ -1,77 +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 com.kenshoo.freemarker.util;
-
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.io.StringWriter;
-
-import org.junit.Test;
-
-public class LengthLimitedWriterTest {
-
- private StringWriter wrappedW = new StringWriter();
- private LengthLimitedWriter w = new LengthLimitedWriter(wrappedW, 5);
-
- @Test
- public void testLimitNotExceeded() throws IOException {
- w.write("123");
- w.write("45");
- }
-
- @Test
- public void testLimitExceededWithString() throws IOException {
- w.write("123");
- try {
- w.write("456");
- fail();
- } catch (LengthLimitExceededException e) {
- assertEquals("12345", wrappedW.toString());
- }
- }
-
- @Test
- public void testLimitExceededWithCharArray() throws IOException {
- w.write(new char[] { '1', '2', '3' });
- try {
- w.write(new char[] { '4', '5', '6' });
- fail();
- } catch (LengthLimitExceededException e) {
- assertEquals("12345", wrappedW.toString());
- }
- }
-
- @Test
- public void testLimitExceededWithChar() throws IOException {
- w.write('1');
- w.write('2');
- w.write('3');
- w.write('4');
- w.write('5');
- try {
- w.write('6');
- fail();
- } catch (LengthLimitExceededException e) {
- assertEquals("12345", wrappedW.toString());
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/test/java/com/kenshoo/freemarker/view/FreeMarkerOnlineViewTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/com/kenshoo/freemarker/view/FreeMarkerOnlineViewTest.java b/src/test/java/com/kenshoo/freemarker/view/FreeMarkerOnlineViewTest.java
deleted file mode 100644
index c67b44c..0000000
--- a/src/test/java/com/kenshoo/freemarker/view/FreeMarkerOnlineViewTest.java
+++ /dev/null
@@ -1,69 +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 com.kenshoo.freemarker.view;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.Locale;
-import java.util.TimeZone;
-
-import org.junit.Test;
-
-import com.kenshoo.freemarker.services.AllowedSettingValuesMaps;
-
-import freemarker.core.HTMLOutputFormat;
-
-
-public class FreeMarkerOnlineViewTest {
-
- private static final String TEMPLATE = "Template";
- private static final String DATA_MODEL = "DataModel";
-
- @Test
- public void testVieEmptyConstrucotr() {
- 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);
- }
-
- @Test
- public void testViewWhenAllOK() {
- FreeMarkerOnlineView view = new FreeMarkerOnlineView();
-
- view.setTemplate(TEMPLATE);
- view.setDataModel(DATA_MODEL);
- String outputFormatStr = HTMLOutputFormat.INSTANCE.getName();
- view.setOutputFormat(outputFormatStr);
- String localeStr = Locale.GERMAN.toString();
- view.setLocale(localeStr);
- String timeZoneStr = TimeZone.getTimeZone("GMT+01").getID();
- view.setTimeZone(timeZoneStr);
-
- assertEquals(view.getTemplate(), TEMPLATE);
- assertEquals(view.getDataModel(), DATA_MODEL);
- assertEquals(view.getOutputFormat(), outputFormatStr);
- assertEquals(view.getLocale(), localeStr);
- assertEquals(view.getTimeZone(), timeZoneStr);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/test/java/org/apache/freemarker/onlinetester/platform/DropWizardServiceTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/freemarker/onlinetester/platform/DropWizardServiceTest.java b/src/test/java/org/apache/freemarker/onlinetester/platform/DropWizardServiceTest.java
new file mode 100644
index 0000000..f23672c
--- /dev/null
+++ b/src/test/java/org/apache/freemarker/onlinetester/platform/DropWizardServiceTest.java
@@ -0,0 +1,39 @@
+/*
+ * 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.platform;
+
+import com.google.common.io.Resources;
+import org.apache.freemarker.onlinetester.dropwizard.ApplicationStartup;
+import com.yammer.dropwizard.testing.junit.DropwizardServiceRule;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+
+public class DropWizardServiceTest {
+ @ClassRule
+ public static TestRule testRule = new DropwizardServiceRule<>(ApplicationStartup.class,
+ Resources.getResource("freemarker-online.yml").getPath());
+
+
+ @Test
+ public void testServerIsUp() throws Exception {
+ ((DropwizardServiceRule) testRule).getService();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/test/java/org/apache/freemarker/onlinetester/platform/YamlPropertiesPersister.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/freemarker/onlinetester/platform/YamlPropertiesPersister.java b/src/test/java/org/apache/freemarker/onlinetester/platform/YamlPropertiesPersister.java
new file mode 100644
index 0000000..4257e40
--- /dev/null
+++ b/src/test/java/org/apache/freemarker/onlinetester/platform/YamlPropertiesPersister.java
@@ -0,0 +1,91 @@
+/*
+ * 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.platform;
+
+import com.fasterxml.jackson.dataformat.yaml.snakeyaml.Yaml;
+import org.springframework.util.PropertiesPersister;
+import org.springframework.util.StringUtils;
+
+import java.io.*;
+import java.util.Map;
+import java.util.Properties;
+
+public class YamlPropertiesPersister implements PropertiesPersister {
+ @Override
+ public void load(Properties props, InputStream is) throws IOException {
+ load(props, new InputStreamReader(is));
+ }
+
+ /**
+ * We want to traverse map representing Yaml object and each time we find String=String pair we want to
+ * save it as Property. As we are going deeper into map we generate compound key as path-like String
+ *
+ * @see org.springframework.util.PropertiesPersister#load(java.util.Properties, java.io.Reader)
+ */
+ @Override
+ public void load(Properties props, Reader reader) throws IOException {
+ Yaml yaml = new Yaml();
+ @SuppressWarnings("unchecked")
+ Map<String, Object> map = (Map<String, Object>) yaml.load(reader);
+ // now we can populate supplied props
+ assignProperties(props, map, null);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void assignProperties(Properties props, Map<String, Object> map, String path) {
+ for (Map.Entry<String, Object> entry : map.entrySet()) {
+ String key = entry.getKey();
+ if (!StringUtils.isEmpty(path))
+ key = path + "." + key;
+ Object val = entry.getValue();
+ if (val instanceof String) {
+ // see if we need to create a compound key
+ props.put(key, val);
+ } else if (val instanceof Map) {
+ assignProperties(props, (Map<String, Object>) val, key);
+ }
+ }
+ }
+
+ @Override
+ public void store(Properties props, OutputStream os, String header) throws IOException {
+ throw new IllegalStateException("Current implementation is a read-only");
+ }
+
+ @Override
+ public void store(Properties props, Writer writer, String header) throws IOException {
+ throw new IllegalStateException("Current implementation is a read-only");
+ }
+
+ @Override
+ public void loadFromXml(Properties props, InputStream is) throws IOException {
+ throw new IllegalStateException("Use DefaultPropertiesPersister if you want to read/write XML");
+ }
+
+ @Override
+ public void storeToXml(Properties props, OutputStream os, String header) throws IOException {
+ throw new IllegalStateException("Use DefaultPropertiesPersister if you want to load/store to XML");
+ }
+
+ @Override
+ public void storeToXml(Properties props, OutputStream os, String header, String encoding) throws IOException {
+ throw new IllegalStateException("Use DefaultPropertiesPersister if you want to read/write XML");
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/test/java/org/apache/freemarker/onlinetester/resources/FreeMarkerOnlineExecuteResourceTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/freemarker/onlinetester/resources/FreeMarkerOnlineExecuteResourceTest.java b/src/test/java/org/apache/freemarker/onlinetester/resources/FreeMarkerOnlineExecuteResourceTest.java
new file mode 100644
index 0000000..d0f81cb
--- /dev/null
+++ b/src/test/java/org/apache/freemarker/onlinetester/resources/FreeMarkerOnlineExecuteResourceTest.java
@@ -0,0 +1,159 @@
+/*
+ * 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.resources;
+
+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 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.junit.Test;
+import org.springframework.web.context.ContextLoaderListener;
+import org.springframework.web.context.request.RequestContextListener;
+
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.spi.spring.container.servlet.SpringServlet;
+import com.sun.jersey.test.framework.AppDescriptor;
+import com.sun.jersey.test.framework.JerseyTest;
+import com.sun.jersey.test.framework.WebAppDescriptor;
+
+public class FreeMarkerOnlineExecuteResourceTest extends JerseyTest {
+ private static final String DATA_MODEL = "user=John";
+ private static final String TEMPLATE_WITH_VARIABLE = "Welcome ${user}";
+ private static final String TEMPLATE_PLAIN = "Welcome John";
+ private static final String MALFORMED_DATA_MODEL = "userJohn";
+ private static final String EXECUTE_API = "api/execute";
+ @Override
+ protected AppDescriptor configure() {
+ return new WebAppDescriptor.Builder("org.apache.freemarker.onlinetester.resources")
+ .contextPath("/")
+ .contextListenerClass(ContextLoaderListener.class)
+ .contextParam("contextConfigLocation", "classpath:spring/bootstrap-context.xml")
+ .servletClass(SpringServlet.class)
+ .requestListenerClass(RequestContextListener.class)
+ .build();
+ }
+
+ @Test
+ public void testSuccessRequest() throws Exception {
+ ExecuteRequest req = new ExecuteRequest(TEMPLATE_WITH_VARIABLE, DATA_MODEL);
+ ClientResponse resp = client().resource(getBaseURI().toString() + EXECUTE_API)
+ .header("Content-Type", "application/json").entity(req).post(ClientResponse.class);
+ assertEquals(200, resp.getStatus());
+ ExecuteResponse response = resp.getEntity(ExecuteResponse.class);
+ assertNull(response.getProblems());
+ }
+
+ @Test
+ public void testMalformedDataModel() throws Exception {
+ ExecuteRequest req = new ExecuteRequest(TEMPLATE_PLAIN, MALFORMED_DATA_MODEL);
+ ClientResponse resp = client().resource(getBaseURI().toString() + EXECUTE_API)
+ .header("Content-Type", "application/json").entity(req).post(ClientResponse.class);
+ assertEquals(200, resp.getStatus());
+ ExecuteResponse response = resp.getEntity(ExecuteResponse.class);
+ assertNotNull(response.getProblems());
+ assertTrue(containsProblem(response, ExecuteResourceField.DATA_MODEL));
+ }
+
+ @Test
+ public void testLongDataModel() throws Exception {
+ ExecuteRequest req = new ExecuteRequest(TEMPLATE_PLAIN, create30KString());
+ ClientResponse resp = client().resource(getBaseURI().toString() + EXECUTE_API)
+ .header("Content-Type", "application/json").entity(req).post(ClientResponse.class);
+ assertEquals(200, resp.getStatus());
+ ExecuteResponse response = resp.getEntity(ExecuteResponse.class);
+ assertNotNull(response.getProblems());
+ assertTrue(containsProblem(response, ExecuteResourceField.DATA_MODEL));
+ String problemMessage = getProblemMessage(response, ExecuteResourceField.DATA_MODEL);
+ assertThat(problemMessage, containsString("data model"));
+ assertThat(problemMessage, containsString("limit"));
+ }
+
+ @Test
+ public void testLongTemplate() throws Exception {
+ ExecuteRequest req = new ExecuteRequest(create30KString(), DATA_MODEL);
+ ClientResponse resp = client().resource(getBaseURI().toString() + EXECUTE_API)
+ .header("Content-Type", "application/json").entity(req).post(ClientResponse.class);
+ assertEquals(200, resp.getStatus());
+ ExecuteResponse response = resp.getEntity(ExecuteResponse.class);
+ assertNotNull(response.getProblems());
+ assertTrue(containsProblem(response, ExecuteResourceField.TEMPLATE));
+ String problemMessage = getProblemMessage(response, ExecuteResourceField.TEMPLATE);
+ assertThat(problemMessage, containsString("template"));
+ assertThat(problemMessage, containsString("limit"));
+ }
+
+ @Test
+ public void testMultipleErrorsDataModel() throws Exception {
+ ExecuteRequest req = new ExecuteRequest(create30KString(), create30KString());
+ req.setOutputFormat("wrongOutputFormat");
+ req.setLocale("wrongLocale");
+ req.setTimeZone("wrongTimeZone");
+
+ ClientResponse resp = client().resource(getBaseURI() + EXECUTE_API)
+ .header("Content-Type", "application/json").entity(req).post(ClientResponse.class);
+
+ assertEquals(200, resp.getStatus());
+ ExecuteResponse response = resp.getEntity(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"));
+ }
+
+ private String create30KString() {
+ final String veryLongString;
+ {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < 30000 / 10; i++) {
+ sb.append("0123456789");
+ }
+ veryLongString = sb.toString();
+ }
+ return veryLongString;
+ }
+
+ private boolean containsProblem(ExecuteResponse response, ExecuteResourceField field) {
+ for (ExecuteResourceProblem problem : response.getProblems()) {
+ if (problem.getField() == field) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private String getProblemMessage(ExecuteResponse response, ExecuteResourceField field) {
+ for (ExecuteResourceProblem problem : response.getProblems()) {
+ if (problem.getField() == field) {
+ return problem.getMessage();
+ }
+ }
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/test/java/org/apache/freemarker/onlinetester/resources/FreeMarkerOnlineResourceTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/freemarker/onlinetester/resources/FreeMarkerOnlineResourceTest.java b/src/test/java/org/apache/freemarker/onlinetester/resources/FreeMarkerOnlineResourceTest.java
new file mode 100644
index 0000000..4f6ef7c
--- /dev/null
+++ b/src/test/java/org/apache/freemarker/onlinetester/resources/FreeMarkerOnlineResourceTest.java
@@ -0,0 +1,70 @@
+/*
+ * 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.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.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 FreeMarkerOnlineResourceTest {
+
+ @InjectMocks
+ FreeMarkerOnlineResource freeMarkerOnlineResultResource;
+
+ @Mock
+ FreeMarkerService freeMarkerService;
+
+ @Test
+ public void testInitialForm() {
+ when(freeMarkerService.calculateTemplateOutput(
+ anyString(), anyMap(), any(OutputFormat.class), any(Locale.class), any(TimeZone.class)))
+ .thenThrow(new AssertionError());
+ FreeMarkerOnlineView view = freeMarkerOnlineResultResource.blankForm();
+ assertEquals(view.getTemplate(), "");
+ assertEquals(view.getDataModel(), "");
+ }
+
+ @Test
+ public void testPostedBlankForm() {
+ when(freeMarkerService.calculateTemplateOutput(
+ anyString(), anyMap(), any(OutputFormat.class), any(Locale.class), any(TimeZone.class)))
+ .thenThrow(new AssertionError());
+ FreeMarkerOnlineView view = freeMarkerOnlineResultResource.formResult(null, null, null, null, null);
+ assertEquals(view.getTemplate(), "");
+ assertEquals(view.getDataModel(), "");
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker-online-tester/blob/2f0c0424/src/test/java/org/apache/freemarker/onlinetester/services/FreeMarkerServiceResponseBuilderTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/freemarker/onlinetester/services/FreeMarkerServiceResponseBuilderTest.java b/src/test/java/org/apache/freemarker/onlinetester/services/FreeMarkerServiceResponseBuilderTest.java
new file mode 100644
index 0000000..f83a1b4
--- /dev/null
+++ b/src/test/java/org/apache/freemarker/onlinetester/services/FreeMarkerServiceResponseBuilderTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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 static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+public class FreeMarkerServiceResponseBuilderTest {
+
+ private static final String RESULT = "Result";
+
+ private final FreeMarkerServiceResponse.Builder builder = new FreeMarkerServiceResponse.Builder();
+
+ @Test
+ public void testSuccessResult() {
+ FreeMarkerServiceResponse result = builder.buildForSuccess(RESULT, false);
+ assertThat(result.getTemplateOutput(), equalTo(RESULT));
+ assertThat(result.isTemplateOutputTruncated(), is(false));
+ assertThat(result.isSuccesful(), is(true));
+ assertThat(result.getFailureReason(), nullValue());
+ }
+
+ @Test
+ public void testSuccessTruncatedResult() {
+ FreeMarkerServiceResponse result = builder.buildForSuccess(RESULT, true);
+ assertThat(result.getTemplateOutput(), equalTo(RESULT));
+ assertThat(result.isTemplateOutputTruncated(), is(true));
+ assertThat(result.isSuccesful(), is(true));
+ assertThat(result.getFailureReason(), nullValue());
+ }
+
+ @Test
+ public void testErrorResult() {
+ Throwable failureReason = new Exception();
+ FreeMarkerServiceResponse result = builder.buildForFailure(failureReason);
+ assertThat(result.getTemplateOutput(), nullValue());
+ assertThat(result.isTemplateOutputTruncated(), is(false));
+ assertThat(result.isSuccesful(), is(false));
+ assertThat(result.getFailureReason(), sameInstance(failureReason));
+ }
+
+}