Sitemesh에서 기본적으로 제공하는 ConfigDecoratorMapper는 파일 하나만 달랑 읽게 하고 있다.

좀 당황스럽게 왜 하나만 읽게 하냐는 말이지. 여러개 파일을 읽고, 다양하게 나눠서 읽는 마당에..

 

  <mapper class="com.opensymphony.module.sitemesh.mapper.ConfigDecoratorMapper">
   <param name="config" value="${decorators-file}" />
  </mapper>

 

여러개의 파일을 다음과 같이 사용한다.

 

         <mapper class="com.google.common.sitemesh.mapper.MultipleConfigDecoratorMapper">
                <param name="config1" value="/common/decorators/decorators.xml" />
                <param name="config2" value="/WEB-INF/decorators.xml" />
         </mapper>

 

ConfigDecoratorMapper를 수정한 소스는 다음과 같다.

 

package com.google.common.sitemesh.mapper;

import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
import java.util.Properties;
import java.util.SortedSet;
import java.util.TreeSet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.opensymphony.module.sitemesh.Config;
import com.opensymphony.module.sitemesh.Decorator;
import com.opensymphony.module.sitemesh.DecoratorMapper;
import com.opensymphony.module.sitemesh.Page;
import com.opensymphony.module.sitemesh.mapper.AbstractDecoratorMapper;
import com.opensymphony.module.sitemesh.mapper.ConfigLoader;

/**
 * Reads decorators and mapping from the <code>param</code> property.
 * If param is not given, read default file('WEB-INF/decorators.xml')
 * <br>
 * It is extended for multiple config file for ConfigDecoratorMapper<br>
 * <br>
 * Example below <br>
 * <mapper class="com.google.common.sitemesh.mapper.MultipleConfigDecoratorMapper"> <br>
 *  <param name="config2" value="/WEB-INF/common-decorators.xml" /> <br>
 *  <param name="config1" value="/WEB-INF/decorators.xml" /> <br>
 * </mapper> <br>
 *
 * @author knight76
 *
 */
public class MultipleConfigDecoratorMapper extends AbstractDecoratorMapper {
 private static Log log = LogFactory.getLog(MultipleConfigDecoratorMapper.class);

 private List<ConfigLoader> configLoaderList = null;

 /** Create new ConfigLoader using '/WEB-INF/decorators.xml' file. */
 public void init(Config config, Properties properties, DecoratorMapper parent) throws InstantiationException {
         super.init(config, properties, parent);
         configLoaderList = new ArrayList<ConfigLoader>();
         try {
          // property의 모든 데이터 키값을 오름차순으로 받아  configLoader에 저장한다.
          String[] props = properties.keySet().toArray(new String[0]);
          Arrays.sort(props);
          for (Object propertyName : props) {
           String fileName = properties.getProperty((String)propertyName, "/WEB-INF/decorators.xml");
           ConfigLoader configLoader = new ConfigLoader(fileName, config);
           configLoaderList.add(configLoader);
          }
         }
         catch (Exception e) {
             log.error(e);
         }
     }

 /**
  * Retrieve {@link com.opensymphony.module.sitemesh.Decorator} based on
  * 'pattern' tag.
  */
 public Decorator getDecorator(HttpServletRequest request, Page page) {
  String thisPath = request.getServletPath();

  // getServletPath() returns null unless the mapping corresponds to a
  // servlet
  if (thisPath == null) {
   String requestURI = request.getRequestURI();
   if (request.getPathInfo() != null) {
    // strip the pathInfo from the requestURI
    thisPath = requestURI.substring(0, requestURI.indexOf(request
      .getPathInfo()));
   } else {
    thisPath = requestURI;
   }
  }

  String name = null;
  try {
   name = getMappedName(thisPath);
  } catch (ServletException e) {
   log.warn(e);
  }

  Decorator result = getNamedDecorator(request, name);
  return result == null ? super.getDecorator(request, page) : result;
 }

 /**
  * 주어진 thispath를 받아 해당 thispath에 매핑된 decorator 이름을 가져온다.
  * @param thisPath
  * @return
  * @throws ServletException
  */
 private String getMappedName(String thisPath) throws ServletException {
  String name = null;
  for (ConfigLoader loader : configLoaderList) {
   name = loader.getMappedName(thisPath);
   if (name != null) {
    return name;
   }
  }
  return name;
 }

 /**
  * Retrieve Decorator named in 'name' attribute. Checks the role if
  * specified.
  */
 public Decorator getNamedDecorator(HttpServletRequest request, String name) {
  Decorator result = null;
  try {
   result = getDecoratorByName(name);
  } catch (ServletException e) {
   log.warn(e);
  }

  if (result == null
    || (result.getRole() != null && !request.isUserInRole(result
      .getRole()))) {
   // if the result is null or the user is not in the role
   return super.getNamedDecorator(request, name);
  } else {
   return result;
  }
 }

 /**
  * 주어진 name을 받아 decorator를 얻어온다.
  * @param name
  * @return
  * @throws ServletException
  */
 private Decorator getDecoratorByName(String name) throws ServletException {
  Decorator result = null;
  for (ConfigLoader configLoader : configLoaderList) {
   result = configLoader.getDecoratorByName(name);
   if (result != null) {
    return result;
   }
  }
  return result;
 }
}

Posted by '김용환'
,