Save This Page
Home » sitemesh-2.3 » com.opensymphony.module » sitemesh » mapper » [javadoc | source]
    1   /*
    2    * Title:        LanguageDecoratorMapper
    3    * Description:
    4    *
    5    * This software is published under the terms of the OpenSymphony Software
    6    * License version 1.1, of which a copy has been included with this
    7    * distribution in the LICENSE.txt file.
    8    */
    9   
   10   package com.opensymphony.module.sitemesh.mapper;
   11   
   12   import com.opensymphony.module.sitemesh.Config;
   13   import com.opensymphony.module.sitemesh.Decorator;
   14   import com.opensymphony.module.sitemesh.DecoratorMapper;
   15   import com.opensymphony.module.sitemesh.Page;
   16   
   17   import javax.servlet.http.HttpServletRequest;
   18   import java.io.File;
   19   import java.util.HashMap;
   20   import java.util.Iterator;
   21   import java.util.Map;
   22   import java.util.Properties;
   23   
   24   /**
   25    * The LanguageDecoratorMapper can determine the preferred language set in the
   26    * browser requesting a page, and map to a suitable Decorator (using the
   27    * "Accept-Language" HTTP header).
   28    *
   29    * <p>This can be useful for supplying different versions of the same content
   30    * for different languages.</p>
   31    *
   32    * <p>When LanguageDecoratorMapper is in the chain, it will request the appropriate Decorator
   33    * from its parent. It will then add an extention to the filename of the Decorator, and
   34    * if that file exists it shall be used as the Decorator instead. For example, if the
   35    * Decorator path is <code>/blah.jsp</code> and the detected preferred language is <code>en</code>,
   36    * the path <code>/blah-en.jsp</code> shall be used.</p>
   37    *
   38    * <p>The language mappings are configured by passing properties with <code>match.</code> as a prefix.
   39    * For example: 'match.en'=engl , 'match.nl'=dutch .</p>
   40    *
   41    * @author <a href="mailto:pathos@pandora.be">Mathias Bogaert</a>
   42    *
   43    * @see com.opensymphony.module.sitemesh.DecoratorMapper
   44    */
   45   public final class LanguageDecoratorMapper extends AbstractDecoratorMapper {
   46       private Map map = null;
   47   
   48       public void init(Config config, Properties properties, DecoratorMapper parent) throws InstantiationException {
   49           super.init(config, properties, parent);
   50           map = new HashMap();
   51           initMap(properties);
   52       }
   53   
   54       public Decorator getDecorator(HttpServletRequest request, Page page) {
   55           try {
   56               Decorator result = null;
   57               final Decorator d = super.getDecorator(request, page);
   58               String path = modifyPath(d.getPage(), getExt(request.getHeader("Accept-Language")));
   59   
   60               File decFile = new File(config.getServletContext().getRealPath(path));
   61   
   62               if (decFile.isFile()) {
   63                   result = new DefaultDecorator(d.getName(), path, null) {
   64                       public String getInitParameter(String paramName) {
   65                           return d.getInitParameter(paramName);
   66                       }
   67                   };
   68               }
   69               return result == null ? super.getDecorator(request, page) : result;
   70           }
   71           catch (NullPointerException e) {
   72               return super.getDecorator(request, page);
   73           }
   74       }
   75   
   76       /** Get extention for the language. */
   77       private String getExt(String acceptLanguage) {
   78           Iterator i = map.entrySet().iterator();
   79           while (i.hasNext()) {
   80               Map.Entry entry = (Map.Entry) i.next();
   81   
   82              // Get the first language (preferred one) in the header, and
   83               // only check the first two chars (the acceptLanguage could be en-gb, but
   84               // we don't support this for now).
   85               if (acceptLanguage.substring(0, 2).equals(entry.getKey())) {
   86                   return (String) entry.getValue();
   87               }
   88   
   89               // When the user-agent has multiple accept-languages (separated by ;),
   90               // these are ignored because the site creator may wish that if the
   91               // preferred language is not supported, the page uses the default
   92               // decorator (in the default language), and not in some other
   93               // language given by the browser (most of them are specified by
   94               // default at install).
   95           }
   96           return null;
   97       }
   98   
   99       /** Change /abc/def.jsp into /abc/def-XYZ.jsp */
  100       private static String modifyPath(String path, String ext) {
  101           int dot = path.indexOf('.');
  102           if (dot > -1) {
  103               return path.substring(0, dot) + '-' + ext + path.substring(dot);
  104           }
  105           else {
  106               return path + '-' + ext;
  107           }
  108       }
  109   
  110       /** Initialize language mappings. */
  111       private void initMap(Properties props) {
  112           Iterator i = props.entrySet().iterator();
  113           while (i.hasNext()) {
  114               Map.Entry entry = (Map.Entry) i.next();
  115               String key = (String) entry.getKey();
  116               if (key.startsWith("match.")) {
  117                   String match = key.substring(6);
  118                  map.put(match, entry.getValue());
  119               }
  120           }
  121       }
  122   }

Save This Page
Home » sitemesh-2.3 » com.opensymphony.module » sitemesh » mapper » [javadoc | source]