    001    package 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
    024    import java.util.ArrayList;
    025    import java.util.Arrays;
    026    import java.util.List;
    027
    028    import org.apache.commons.lang.StringUtils;
    029    import org.apache.commons.logging.Log;
    030    import org.apache.commons.logging.LogFactory;
    031    import org.apache.turbine.services.template.TemplateEngineService;
    032    import org.apache.turbine.services.template.TemplateService;
    033    import org.apache.turbine.services.template.TurbineTemplate;
    034
    035    /**
    036     * This mapper is responsible for the lookup of templates for the Layout
    037     * It tries to look in various packages for a match:
    038     *
    039     * 1. about,directions,Driving.vm      &lt;- exact match
    040     * 2. about,directions,Default.vm      &lt;- package match, Default name
    041     * 3. about,Default.vm                 &lt;- stepping up in the hierarchy
    042     * 4. Default.vm                       &lt;- The name configured as default.layout.template
    043     *                                        in the corresponding Templating Engine
    044
    045     *
    046     * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
    047     * @version $Id: LayoutTemplateMapper.java 1071091 2011-02-15 22:06:55Z tv $
    048     */
    049
    050    public class LayoutTemplateMapper
    051        extends BaseTemplateMapper
    052        implements Mapper
    053    {
    054        /** Logging */
    055        private static Log log = LogFactory.getLog(LayoutTemplateMapper.class);
    056
    057        /**
    058         * Default C'tor. If you use this C'tor, you must use
    059         * the bean setter to set the various properties needed for
    060         * this mapper before first usage.
    061         */
    062        public LayoutTemplateMapper()
    063        {
    064            // empty
    065        }
    066
    067        /**
    068         * Look for a given Template, then try the
    069         * defaults until we hit the root.
    070         *
    071         * @param template The template name.
    072         * @return The parsed module name.
    073         */
    074        public String doMapping(String template)
    075        {
    076            log.debug("doMapping(" + template + ")");
    077            // Copy our elements into an array
    078            List<String> components
    079                = new ArrayList<String>(Arrays.asList(StringUtils.split(
    080                                                  template,
    081                                                  String.valueOf(TemplateService.TEMPLATE_PARTS_SEPARATOR))));
    082            int componentSize = components.size() - 1 ;
    083
    084            // This method never gets an empty string passed.
    085            // So this is never < 0
    086            String templateName = components.get(componentSize);
    087            components.remove(componentSize--);
    088
    089            log.debug("templateName is " + templateName);
    090
    091            // Last element decides, which template Service to use...
    092            TemplateEngineService tes = TurbineTemplate.getTemplateEngineService(templateName);
    093
    094            if (tes == null)
    095            {
    096                return null;
    097            }
    098
    099            String defaultName =
    100                TurbineTemplate.getDefaultLayoutTemplateName(templateName); // We're, after all, a Layout Template Mapper...
    101
    102            // This is an optimization. If the name we're looking for is
    103            // already the default name for the template, don't do a "first run"
    104            // which looks for an exact match.
    105            boolean firstRun = !templateName.equals(defaultName);
    106
    107            for(;;)
    108            {
    109                String templatePackage = StringUtils.join(components.iterator(), String.valueOf(separator));
    110
    111                log.debug("templatePackage is now: " + templatePackage);
    112
    113                StringBuffer testName = new StringBuffer();
    114
    115                if (!components.isEmpty())
    116                {
    117                    testName.append(templatePackage);
    118                    testName.append(separator);
    119                }
    120
    121                testName.append((firstRun)
    122                    ? templateName
    123                    : defaultName);
    124
    125                // But the Templating service must look for the name with prefix
    126                StringBuffer templatePath = new StringBuffer();
    127                if (StringUtils.isNotEmpty(prefix))
    128                {
    129                    templatePath.append(prefix);
    130                    templatePath.append(separator);
    131                }
    132                templatePath.append(testName);
    133
    134                log.debug("Looking for " + templatePath);
    135
    136                if (tes.templateExists(templatePath.toString()))
    137                {
    138                    log.debug("Found it, returning " + testName);
    139                    return testName.toString();
    140                }
    141
    142                if (firstRun)
    143                {
    144                    firstRun = false;
    145                }
    146                else
    147                {
    148                    // We're no longer on the first Run (so we
    149                    // already tested the "Default" template)
    150                    // and the package is empty (we've hit the
    151                    // root. So we now break the endless loop.
    152                    if (components.isEmpty())
    153                    {
    154                        break; // for(;;)
    155                    }
    156                    // We still have components. Remove the
    157                    // last one and go through the loop again.
    158                    components.remove(componentSize--);
    159                }
    160            }
    161
    162            log.debug("Returning default");
    163            return getDefaultName(template);
    164        }
    165    }