/* * 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 freemarker.cache; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import java.io.IOException; import java.util.Arrays; import java.util.List; import org.junit.Test; import freemarker.core.TemplateConfiguration; import freemarker.template.Configuration; public class TemplateConfigurationFactoryTest { private Configuration cfg = new Configuration(Configuration.VERSION_2_3_22); @Test public void testCondition1() throws IOException, TemplateConfigurationFactoryException { TemplateConfiguration tc = newTemplateConfiguration(1); TemplateConfigurationFactory tcf = new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*.ftlx"), tc); tcf.setConfiguration(cfg); assertNotApplicable(tcf, "x.ftl"); assertApplicable(tcf, "x.ftlx", tc); } @Test public void testCondition2() throws IOException, TemplateConfigurationFactoryException { TemplateConfiguration tc = newTemplateConfiguration(1); TemplateConfigurationFactory tcf = new ConditionalTemplateConfigurationFactory( new FileNameGlobMatcher("*.ftlx"), new ConditionalTemplateConfigurationFactory( new FileNameGlobMatcher("x.*"), tc)); tcf.setConfiguration(cfg); assertNotApplicable(tcf, "x.ftl"); assertNotApplicable(tcf, "y.ftlx"); assertApplicable(tcf, "x.ftlx", tc); } @Test public void testMerging() throws IOException, TemplateConfigurationFactoryException { TemplateConfiguration tc1 = newTemplateConfiguration(1); TemplateConfiguration tc2 = newTemplateConfiguration(2); TemplateConfiguration tc3 = newTemplateConfiguration(3); TemplateConfigurationFactory tcf = new MergingTemplateConfigurationFactory( new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*.ftlx"), tc1), new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*a*.*"), tc2), new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*b*.*"), tc3)); tcf.setConfiguration(cfg); assertNotApplicable(tcf, "x.ftl"); assertApplicable(tcf, "x.ftlx", tc1); assertApplicable(tcf, "a.ftl", tc2); assertApplicable(tcf, "b.ftl", tc3); assertApplicable(tcf, "a.ftlx", tc1, tc2); assertApplicable(tcf, "b.ftlx", tc1, tc3); assertApplicable(tcf, "ab.ftl", tc2, tc3); assertApplicable(tcf, "ab.ftlx", tc1, tc2, tc3); assertNotApplicable(new MergingTemplateConfigurationFactory(), "x.ftl"); } @Test public void testFirstMatch() throws IOException, TemplateConfigurationFactoryException { TemplateConfiguration tc1 = newTemplateConfiguration(1); TemplateConfiguration tc2 = newTemplateConfiguration(2); TemplateConfiguration tc3 = newTemplateConfiguration(3); FirstMatchTemplateConfigurationFactory tcf = new FirstMatchTemplateConfigurationFactory( new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*.ftlx"), tc1), new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*a*.*"), tc2), new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*b*.*"), tc3)); tcf.setConfiguration(cfg); try { assertNotApplicable(tcf, "x.ftl"); } catch (TemplateConfigurationFactoryException e) { assertThat(e.getMessage(), containsString("x.ftl")); } tcf.setNoMatchErrorDetails("Test details"); try { assertNotApplicable(tcf, "x.ftl"); } catch (TemplateConfigurationFactoryException e) { assertThat(e.getMessage(), containsString("Test details")); } tcf.setAllowNoMatch(true); assertNotApplicable(tcf, "x.ftl"); assertApplicable(tcf, "x.ftlx", tc1); assertApplicable(tcf, "a.ftl", tc2); assertApplicable(tcf, "b.ftl", tc3); assertApplicable(tcf, "a.ftlx", tc1); assertApplicable(tcf, "b.ftlx", tc1); assertApplicable(tcf, "ab.ftl", tc2); assertApplicable(tcf, "ab.ftlx", tc1); assertNotApplicable(new FirstMatchTemplateConfigurationFactory().allowNoMatch(true), "x.ftl"); } @Test public void testComplex() throws IOException, TemplateConfigurationFactoryException { TemplateConfiguration tcA = newTemplateConfiguration(1); TemplateConfiguration tcBSpec = newTemplateConfiguration(2); TemplateConfiguration tcBCommon = newTemplateConfiguration(3); TemplateConfiguration tcHH = newTemplateConfiguration(4); TemplateConfiguration tcHtml = newTemplateConfiguration(5); TemplateConfiguration tcXml = newTemplateConfiguration(6); TemplateConfiguration tcNWS = newTemplateConfiguration(7); TemplateConfigurationFactory tcf = new MergingTemplateConfigurationFactory( new FirstMatchTemplateConfigurationFactory( new ConditionalTemplateConfigurationFactory(new PathGlobMatcher("a/**"), tcA), new ConditionalTemplateConfigurationFactory(new PathGlobMatcher("b/**"), new MergingTemplateConfigurationFactory( new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*"), tcBCommon), new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*.s.*"), tcBSpec)))) .allowNoMatch(true), new FirstMatchTemplateConfigurationFactory( new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*.hh"), tcHH), new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*.*h"), tcHtml), new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*.*x"), tcXml)) .allowNoMatch(true), new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*.nws.*"), tcNWS)); tcf.setConfiguration(cfg); assertNotApplicable(tcf, "x.ftl"); assertApplicable(tcf, "b/x.ftl", tcBCommon); assertApplicable(tcf, "b/x.s.ftl", tcBCommon, tcBSpec); assertApplicable(tcf, "b/x.s.ftlh", tcBCommon, tcBSpec, tcHtml); assertApplicable(tcf, "b/x.s.nws.ftlx", tcBCommon, tcBSpec, tcXml, tcNWS); assertApplicable(tcf, "a/x.s.nws.ftlx", tcA, tcXml, tcNWS); assertApplicable(tcf, "a.hh", tcHH); assertApplicable(tcf, "a.nws.hh", tcHH, tcNWS); } @Test public void testSetConfiguration() { TemplateConfiguration tc = new TemplateConfiguration(); ConditionalTemplateConfigurationFactory tcf = new ConditionalTemplateConfigurationFactory(new FileNameGlobMatcher("*"), tc); assertNull(tcf.getConfiguration()); assertNull(tc.getParentConfiguration()); tcf.setConfiguration(cfg); assertEquals(cfg, tcf.getConfiguration()); assertEquals(cfg, tc.getParentConfiguration()); // Ignored: tcf.setConfiguration(cfg); try { tcf.setConfiguration(Configuration.getDefaultConfiguration()); fail(); } catch (IllegalStateException e) { assertThat(e.getMessage(), containsString("TemplateConfigurationFactory")); } } @SuppressWarnings("boxing") private TemplateConfiguration newTemplateConfiguration(int id) { TemplateConfiguration tc = new TemplateConfiguration(); tc.setCustomAttribute("id", id); tc.setCustomAttribute("contains" + id, true); return tc; } private void assertNotApplicable(TemplateConfigurationFactory tcf, String sourceName) throws IOException, TemplateConfigurationFactoryException { assertNull(tcf.get(sourceName, "dummy")); } private void assertApplicable(TemplateConfigurationFactory tcf, String sourceName, TemplateConfiguration... expectedTCs) throws IOException, TemplateConfigurationFactoryException { TemplateConfiguration mergedTC = tcf.get(sourceName, "dummy"); assertNotNull("TC should have its parents Configuration set", mergedTC.getParentConfiguration()); List<String> mergedTCAttNames = Arrays.asList(mergedTC.getCustomAttributeNames()); for (TemplateConfiguration expectedTC : expectedTCs) { Integer tcId = (Integer) expectedTC.getCustomAttribute("id"); if (tcId == null) { fail("TemplateConfiguration-s must be created with newTemplateConfiguration(id) in this test"); } if (!mergedTCAttNames.contains("contains" + tcId)) { fail("TemplateConfiguration with ID " + tcId + " is missing from the asserted value"); } } for (String attName: mergedTCAttNames) { if (!containsCustomAttr(attName, expectedTCs)) { fail("The asserted TemplateConfiguration contains an unexpected custom attribute: " + attName); } } assertEquals(expectedTCs[expectedTCs.length - 1].getCustomAttribute("id"), mergedTC.getCustomAttribute("id")); } private boolean containsCustomAttr(String attName, TemplateConfiguration... expectedTCs) { for (TemplateConfiguration expectedTC : expectedTCs) { if (expectedTC.getCustomAttribute(attName) != null) { return true; } } return false; } }