001package org.apache.turbine.services.template.mapper; 002 003 004/* 005 * Licensed to the Apache Software Foundation (ASF) under one 006 * or more contributor license agreements. See the NOTICE file 007 * distributed with this work for additional information 008 * regarding copyright ownership. The ASF licenses this file 009 * to you under the Apache License, Version 2.0 (the 010 * "License"); you may not use this file except in compliance 011 * with the License. You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, 016 * software distributed under the License is distributed on an 017 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 018 * KIND, either express or implied. See the License for the 019 * specific language governing permissions and limitations 020 * under the License. 021 */ 022 023 024import java.util.ArrayList; 025import java.util.Arrays; 026import java.util.List; 027 028import org.apache.commons.lang3.StringUtils; 029import org.apache.logging.log4j.LogManager; 030import org.apache.logging.log4j.Logger; 031import org.apache.turbine.services.TurbineServices; 032import org.apache.turbine.services.template.TemplateEngineService; 033import org.apache.turbine.services.template.TemplateService; 034 035/** 036 * This is a pretty simple mapper which returns template pathes for 037 * a supplied template name. If the path does not exist, it looks for 038 * a templated called "Default" in the same package. 039 * This path can be used by the TemplateEngine to access 040 * a certain resource to actually render the template. 041 * 042 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a> 043 * @version $Id$ 044 */ 045 046public class ScreenDefaultTemplateMapper 047 extends BaseTemplateMapper 048 implements Mapper 049{ 050 /** Logging */ 051 private static final Logger log = LogManager.getLogger(ScreenDefaultTemplateMapper.class); 052 053 /** 054 * Default C'tor. If you use this C'tor, you must use 055 * the bean setter to set the various properties needed for 056 * this mapper before first usage. 057 */ 058 public ScreenDefaultTemplateMapper() 059 { 060 // empty 061 } 062 063 /** 064 * Look for a given Template, then try the 065 * default. 066 * 067 * @param template The template name. 068 * @return The parsed module name. 069 */ 070 @Override 071 public String doMapping(String template) 072 { 073 log.debug("doMapping({})", template); 074 // Copy our elements into an array 075 List<String> components 076 = new ArrayList<>(Arrays.asList(StringUtils.split( 077 template, 078 String.valueOf(TemplateService.TEMPLATE_PARTS_SEPARATOR)))); 079 int componentSize = components.size() - 1 ; 080 081 // This method never gets an empty string passed. 082 // So this is never < 0 083 String templateName = components.get(componentSize); 084 components.remove(componentSize--); 085 086 log.debug("templateName is {}", templateName); 087 088 // Last element decides, which template Service to use... 089 TemplateService templateService = (TemplateService)TurbineServices.getInstance().getService(TemplateService.SERVICE_NAME); 090 TemplateEngineService tes = templateService.getTemplateEngineService(templateName); 091 092 if (tes == null) 093 { 094 return null; 095 } 096 097 String defaultName = "Default.vm"; 098 099 // This is an optimization. If the name we're looking for is 100 // already the default name for the template, don't do a "first run" 101 // which looks for an exact match. 102 boolean firstRun = !templateName.equals(defaultName); 103 104 for(;;) 105 { 106 String templatePackage = StringUtils.join(components.iterator(), String.valueOf(separator)); 107 108 log.debug("templatePackage is now: {}", templatePackage); 109 110 StringBuilder testName = new StringBuilder(); 111 112 if (!components.isEmpty()) 113 { 114 testName.append(templatePackage); 115 testName.append(separator); 116 } 117 118 testName.append((firstRun) 119 ? templateName 120 : defaultName); 121 122 // But the Templating service must look for the name with prefix 123 StringBuilder templatePath = new StringBuilder(); 124 if (StringUtils.isNotEmpty(prefix)) 125 { 126 templatePath.append(prefix); 127 templatePath.append(separator); 128 } 129 templatePath.append(testName); 130 131 log.debug("Looking for {}", templatePath); 132 133 if (tes.templateExists(templatePath.toString())) 134 { 135 log.debug("Found it, returning {}", testName); 136 return testName.toString(); 137 } 138 139 if (firstRun) 140 { 141 firstRun = false; 142 } 143 else 144 { 145 // We run this loop only two times. The 146 // first time with the 'real' name and the 147 // second time with "Default". The second time 148 // we will end up here and break the for(;;) loop. 149 break; 150 } 151 } 152 153 log.debug("Returning default"); 154 return getDefaultName(template); 155 } 156}