You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@turbine.apache.org by jv...@apache.org on 2001/03/27 20:55:50 UTC

cvs commit: jakarta-turbine/src/java/org/apache/turbine/services/template TemplateEngineService.java TurbineTemplateService2.java

jvanzyl     01/03/27 10:55:50

  Added:       src/java/org/apache/turbine/services/template
                        TemplateEngineService.java
                        TurbineTemplateService2.java
  Log:
  - just housing these, they do not interfere with anything. just
    want to keep them safe while working on them.
  
  Revision  Changes    Path
  1.1                  jakarta-turbine/src/java/org/apache/turbine/services/template/TemplateEngineService.java
  
  Index: TemplateEngineService.java
  ===================================================================
  package org.apache.turbine.services.template;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and 
   *    "Apache Turbine" must not be used to endorse or promote products 
   *    derived from this software without prior written permission. For 
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without 
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /**
   * This is the interface that all template engine services
   * must adhere to. This include Velocity, WebMacro, FreeMarker
   * and the JSP service.
   *
   * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
   * @version $Id: TemplateEngineService.java,v 1.1 2001/03/27 18:55:50 jvanzyl Exp $
   */
  public interface TemplateEngineService
  {
      /**
       * Use the specific template engine to determine whether
       * a given template exists. This allows Turbine the TemplateService
       * to delegate the search for a template to the template
       * engine being used for the view. This gives us the
       * advantage of fully utilizing the capabilities of
       * template engine with respect to retrieving templates
       * from arbitrary sources.
       *
       * @param String template
       * @return boolean
       */
      public boolean templateExists(String template);
  }
  
  
  
  1.1                  jakarta-turbine/src/java/org/apache/turbine/services/template/TurbineTemplateService2.java
  
  Index: TurbineTemplateService2.java
  ===================================================================
  package org.apache.turbine.services.template;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and 
   *    "Apache Turbine" must not be used to endorse or promote products 
   *    derived from this software without prior written permission. For 
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without 
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.util.ArrayList;
  import java.util.Hashtable;
  import java.util.List;
  import java.util.Stack;
  import java.util.StringTokenizer;
  
  import java.io.File;
  
  import org.apache.turbine.modules.NavigationLoader;
  import org.apache.turbine.modules.ScreenLoader;
  import org.apache.turbine.util.Log;
  import org.apache.turbine.services.TurbineBaseService;
  import org.apache.turbine.services.TurbineServices;
  import org.apache.turbine.services.InitializationException;
  import org.apache.turbine.services.resources.TurbineResources;
  import org.apache.turbine.services.resources.ResourceService;
  import org.apache.turbine.services.servlet.TurbineServlet;
  
  import org.apache.velocity.runtime.configuration.Configuration;
  
  /**
   * This service provides a method for mapping templates to their
   * appropriate Screens or Navigations.  It also allows templates to
   * define a layout/navigations/screen modularization within the
   * template structure.  It also performs caching if turned on in the
   * properties file.
   *
   * Since everything is keyed off the template variable, 
   * if data.getParameters().getString("template") returns
   * /about_us/directions/driving.vm, the search for the 
   * Screen class is as follows (in order):
   * 
   * 1. about_us.directions.Driving 
   * 2. about_us.directions.Default 
   * 3. about_us.Default 
   * 4. Default 
   * 5. VelocityScreen
   *
   * If the template variable does not exist, then VelocityScreen will be 
   * executed and templates/screens/index.vm will be executed. 
   * If index.vm is not found or if the template is invalid or Velocity 
   * execution throws an exception of any reason, then
   * templates/screens/error.vm will be executed. 
   * 
   * For the Layouts and Navigations, the following paths will be 
   * searched in the layouts and navigations template
   * subdirectories (in order): 
   * 
   * 1./about_us/directions/driving.vm 
   * 2./about_us/directions/default.vm 
   * 3./about_us/default.vm 
   * 4./default.vm 
   *
   * @author <a href="mailto:john.mcnally@clearink.com">John D. McNally</a>
   * @author <a href="mailto:mbryson@mont.mindspring.com">Dave Bryson</a>
   * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
   * @version $Id: TurbineTemplateService2.java,v 1.1 2001/03/27 18:55:50 jvanzyl Exp $
   */
  public class TurbineTemplateService2 extends TurbineBaseService
      implements TemplateService, TemplateEngineService
  {
      /** 
       * The hashtable used to cache Screen names. 
       */
      private Hashtable screenCache = null;
  
      /** 
       * The hashtable used to cache screen template names. 
       */
      private Hashtable templateCache = null;
  
      /** 
       * The hashtable used to cache Navigation names. 
       */
      private Hashtable navigationCache = null;
  
      /** 
       * The hashtable used to cache layout template names. 
       */
      private Hashtable layoutCache = null;
  
      /** 
       * Flag set if cache is to be used. 
       */
      private boolean useCache = false;
  
      /** 
       * Default extension for templates. 
       */
      private String extension;
  
      /** 
       * Default layout template. 
       */
      private String defaultLayoutTemplate;
  
      /** 
       * Default Navigation module. 
       */
      private String defaultNavigation;
  
      /** 
       * Default Screen module. 
       */
      private String defaultScreen;
  
      /**
       * Called the first time the Service is used.
       *
       * @exception InitializationException
       */
      public void init() throws InitializationException
      {
          try
          {
              initTemplate();
              setInit(true);
          }
          catch (Exception e)
          {
              throw new InitializationException(
                  "TurbineTemplateService failed to initialize", e);
          }
      }
  
      /**
       * Initialize the template service.
       *
       * @param config A ServletConfig.
       * @exception Exception, a generic exception.
       */
      private void initTemplate() throws Exception
      {
          /*
           * Get the configuration for the template service.
           */
          Configuration config = getConfiguration();
          
          /*
           * Check to see if we are going to be caching modules.
           */
          useCache = TurbineResources.getBoolean("module.cache", true);
          
          if (useCache)
          {
              int layoutSize = config.getInt("layout.cache.size",5);
              int navigationSize = config.getInt("navigation.cache.size", 10);
              int screenSize = config.getInt("screen.cache.size", 5);
              int templateSize = config.getInt("screen.cache.size", 50);
              
              layoutCache = new Hashtable((int) (1.25*layoutSize) + 1);
              navigationCache = new Hashtable((int) (1.25*navigationSize) + 1);
              screenCache = new Hashtable((int) (1.25*screenSize) + 1);
              templateCache = new Hashtable((int) (1.25*templateSize) + 1);
          }
          
          /*
           * The extension that is added to layout templates.
           */
          extension = config.getString("default.extension", "vm");
  
          /*
           * The default navigation module.
           */
          defaultNavigation = config.getString(
              "default.navigation", "TemplateNavigation");
          
          /*
           * The default screen.
           */
          defaultScreen = config.getString("default.screen", "TemplateScreen");
          
          /*
           * The default layout template.
           */
          defaultLayoutTemplate = config.getString(
              "default.layout.template", "/default." + extension);
          
          if (defaultLayoutTemplate.indexOf('.') == -1)
          {
              defaultLayoutTemplate = defaultLayoutTemplate + "." + extension;
          }
      }
  
      /**
       *  Adds the object into the hashtable.
       *
       * @param key The String key for the object.
       * @param value The Object.
       * @param h The Hashtable.
       */
      private void addToCache ( String key,
                                Object value,
                                Hashtable h )
      {
          if (useCache && value != null)
          {
              h.put(key, value);
          }
      }
  
      /**
       * Get the Screen template given in the properties file.
       *
       * @return A String which is the value of the TemplateService 
       * default.screen property.
       */
      public String getDefaultScreen()
      {
          return defaultScreen;
      }
      
      /**
       * Get the default Navigation given in the properties file.
       *
       * @return A String which is the value of the TemplateService 
       * default.navigation property.
       */
      public String getDefaultNavigation()
      {
          return defaultNavigation;
      }
  
      /**
       * Get the default layout template given in the properties file.
       *
       * @return A String which is the value of the TemplateService 
       * default.layout.template property.
       */
      public String getDefaultLayoutTemplate()
      {
          return defaultLayoutTemplate;
      }
  
      /**
       * Locate and return the name of a screen template.
       *
       *
       * @param name A String which is the key to the template.
       * @return A String with the screen template path.
       * @exception Exception, a generic exception.
       */
      public String getScreenTemplateName(String key) throws Exception
      {
          if (key == null)
          {
              throw new Exception ("TurbineTemplateService: " + 
                  "getScreenTemplateName() was passed in a null value.");
          }                
  
          String screenTemplate = null;
  
          if (  useCache && templateCache.containsKey(key) )
          {
              screenTemplate = (String) templateCache.get(key);
          }
          else
          {
              String[] names = parseScreenTemplate(key);
              screenTemplate = names[2];
              addToCache( key, names[0], screenCache );
              addToCache( key, names[1], layoutCache );
              addToCache( key, names[2], templateCache );
          }
          return screenTemplate;
      }
      
      /**
       * Locate and return the name of a layout template.
       *
       *
       * @param name A String with the name of the template.
       * @return A String with the layout template path.
       * @exception Exception, a generic exception.
       */
      public String getLayoutTemplateName(String key) throws Exception
      {
          if (key == null)
          {
              throw new Exception ("TurbineTemplateService: " + 
                  "getLayoutTemplateName() was passed in a null value.");
          }                
  
          String layoutName = null;
  
          if (  useCache && layoutCache.containsKey(key) )
          {
              layoutName = (String) layoutCache.get(key);
          }
          else
          {
              String[] names = parseScreenTemplate(key);
              layoutName = names[1];
              addToCache( key, names[0], screenCache );
              addToCache( key, names[1], layoutCache );
              addToCache( key, names[2], templateCache );
          }
          return layoutName;
      }
  
      /**
       * Locate and return the name of a Navigation module.
       *
       * @param name A String with the name of the template.
       * @return A String with the name of the navigation.
       * @exception Exception, a generic exception.
       */
      public String getNavigationName(String key) throws Exception
      {
          if (key == null)
          {
              throw new Exception ("TurbineTemplateService: " + 
                  "getNavigationName() was passed in a null value.");
          }                
  
          String navigationName = null;
  
          if ( useCache && navigationCache.containsKey(key) )
          {
              navigationName = (String) navigationCache.get(key);
          }
          else
          {
              navigationName = parseNavigationTemplate(key);
              addToCache( key, navigationName, navigationCache );
          }
          return navigationName;
      }
  
      /**
       * Locate and return the name of a Screen module.
       *
       * @param name A String with the name of the template.
       * @return A String with the name of the screen.
       * @exception Exception, a generic exception.
       */
      public String getScreenName(String name) throws Exception
      {
  
          if (name == null)
          {
              throw new Exception ("TurbineTemplateService: " + 
                  "getScreenName() was passed in a null value.");
          }                
  
          String screenName = null;
  
          if (  useCache && screenCache.containsKey(name) )
          {
              screenName = (String)screenCache.get(name);
          }
          else
          {
              String[] names = parseScreenTemplate(name);
              screenName = names[0];
              addToCache( name, names[0], screenCache );
              addToCache( name, names[1], layoutCache );
              addToCache( name, names[2], templateCache );
          }
          return screenName;
      }
  
      /**
       * Get the default extension given in the properties file.
       *
       * @return A String with the extension.
       */
      public String getDefaultExtension()
      {
          return extension;
      }
  
      /**
       * This method takes the template parameter and parses it, so that
       * relevant Screen/Layout-template information can be extracted.
       *
       * @param template A String with the template name.
       * @return A String[] where the first element is the Screen name
       *         and the second element is the layout template.
       */
      protected String[] parseScreenTemplate( String template ) throws Exception
      {
          /*
           * Check if an extension was included. 
           * If not, add the default.
           */
          if ( template.indexOf('.') == -1 )
          {
              template = template + "." + getDefaultExtension(); 
          }
          
          /*
           * Remove any leading "/" characters because we
           * are already appending one here. Don't want
           * the duplicate "//" sequence in the path.
           */
          if (template.startsWith("/"))
          {
              template = template.substring(1);
          }                
              
          if (!templateExists("screens/" + template))
          {
              /*
               * We should ask the template engine where it
               * looked for templates.
               */
              throw new Exception("can't find template: " + template);
          }
  
          Stack tokens = processTemplateName(template);
          String className = (String) tokens.pop();
          String fileName = (String) tokens.pop();
          
          /*
           * Here we are producing two arrays, the first is
           * a list of the paths where the template might
           * live, and the second is a list of where the
           * screen classes may live in the classpath.
           */
          String[] paths = new String[tokens.size() + 2];
          String[] pkgs = new String[tokens.size() + 2];
          int arrayIndex = 0;
          for (int i=tokens.size(); i>=0;  i--)
          {
              StringBuffer path = new StringBuffer();
              StringBuffer pkg = new StringBuffer();
              for (int j=0; j<i; j++)
              {
                  path.append("/").append((String)tokens.get(j));
                  pkg.append((String)tokens.get(j)).append('.');
              }
              if ( i == tokens.size() )
              {
                  StringBuffer distinctPath = new StringBuffer(path.toString());
                  StringBuffer distinctPkg = new StringBuffer(pkg.toString());
                  paths[arrayIndex] = distinctPath.append('/').append(fileName).toString();
                  pkgs[arrayIndex] = distinctPkg.append(className).toString();
                  arrayIndex++;
              }
              paths[arrayIndex] = path.append(defaultLayoutTemplate).toString();
              pkgs[arrayIndex] = pkg.append("Default").toString();
              arrayIndex++;
          }
  
          String[] holder = new String[3];
          holder[0] = getScreenName(pkgs);
          holder[1] = getLayoutTemplateName(paths);
          holder[2] = template;
          return holder;
      }
      
      /**
       * Use the companion template engine service to
       * determine whether a template exists.
       *
       * @param String template to search for
       * @return boolean
       */
      public boolean templateExists(String template)
      {
          String engine = "TurbineVelocityService";
          
          TemplateEngineService e = (TemplateEngineService)
              TurbineServices.getInstance().getService(engine);
          
          return e.templateExists(template);
      }        
  
      /**
       * Parse the template name out to a package path to locate the
       * Navigation module.  This is different than the Screen/Layout
       * parser in that it only looks for packages.  Note: If caching is
       * enabled, this is only performed once for each unique template.
       *
       * @param String The template name (i.e folder/headernav.wm).
       * @return A String with the name of the Navigation module to use
       * for the template.
       */
      protected String parseNavigationTemplate( String template )
      {
          Stack tokens = processTemplateName(template);
          String className = (String) tokens.pop();
          String fileName = (String) tokens.pop();
          
          String[] pkgs = new String[tokens.size() + 2];
          int arrayIndex = 0;
          for (int i=tokens.size(); i>=0;  i--)
          {
              StringBuffer pkg = new StringBuffer();
              for (int j=0; j<i; j++)
              {
                  pkg.append((String)tokens.get(j)).append('.');
              }
              if ( i == tokens.size() )
              {
                  StringBuffer distinctPkg = new StringBuffer(pkg.toString());
                  pkgs[arrayIndex] = distinctPkg.append(className).toString();
                  arrayIndex++;
              }
              pkgs[arrayIndex] = pkg.append("Default").toString();
              arrayIndex++;
          }
          return getNavigationName(pkgs);
      }
  
      /**
       * Process the template name and return a List that
       * contains the tokenized bits of the path to
       * the template, the fileName of the template,
       * and the class name of the screen that goes
       * along with the template.
       *
       * @param String template
       * @return List 
       */
      private Stack processTemplateName(String template)
      {
          /*
           * Look at the template name that we have been given,
           * say for example:
           *
           * /about_us/directions/driving.vm
           *
           * and try to determine where a matching Screen
           * class might be found.
           */
          StringTokenizer st = new StringTokenizer(template, "/");
          Stack tokens = new Stack();
          
          /*
           * Using our example above we are going to turn:
           *
           * /about_us/directions/driving.vm
           *
           * into
           *
           * [about_us, directions, driving.vm]
           */
          while(st.hasMoreTokens())
          {
              String token = st.nextToken();
              if (!token.equals(""))
              {
                  tokens.add(token);
              }
          }
          
          /*
           * The last element in the list is the name of
           * our template.
           */
          String fileName = (String)tokens.pop();
          int dot = fileName.lastIndexOf('.');
          String className = null;
          
          if (dot>0)
          {
              className = fileName.substring(0, dot);
          }
          else
          {
              className = fileName;
          }
          
          tokens.push(fileName);
          tokens.push(className);
          
          return tokens;
      }
  
      /**
       * Extract possible layouts paths.
       *
       * @param possiblePaths A String[] with possible paths to search.
       * @return A String with the name of the layout template.
       */
      private String getLayoutTemplateName(String[] possiblePaths)
      {
          for (int i = 0; i < possiblePaths.length; i++)
          {
              /*
               * We are not adjusting anything here "/" character
               * wise because the possiblePaths are coming in
               * with a prefix of "/".
               */
              if (templateExists("layouts" + possiblePaths[i]))
              {
                  return possiblePaths[i];
              }
          }
  
          return defaultLayoutTemplate;
      }
  
      /**
       * Extract a possible Screen from the packages.
       *
       * @param possibleScreens A String[] with possible paths to
       * search.
       * @return A String with the name of the Screen class to use.
       */
      private String getScreenName( String[] possibleScreens)
      {
          for (int i = 0; i < possibleScreens.length; i++)
          {
              try
              {
                  ScreenLoader.getInstance().getInstance(possibleScreens[i]);
                  return possibleScreens[i];
              }
              catch (Exception e) 
              {
                  /*
                   * do nothing.
                   */
              }
          }
          return defaultScreen;
      }
  
  
      /**
       * Seaches for the Navigation class that may match the
       * name of the Navigation template.
       *
       * @param possibleNavigations A String[] with possible navigation
       * packages.
       * @return A String with the name of the Navigation class to use.
       */
      private String getNavigationName( String[] possibleNavigations)
      {
          for (int i = 0; i < possibleNavigations.length; i++)
          {
              try
              {
                  NavigationLoader.getInstance().getInstance(possibleNavigations[i]);
                  return possibleNavigations[i];
              }
              catch (Exception e) 
              {
                  /*
                   * do nothing.
                   */
              }
          }
          return defaultNavigation;
      }
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: turbine-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: turbine-dev-help@jakarta.apache.org