Exemple #1
0
 public static boolean isCancelled(Throwable t) {
   if (t == null) {
     return false;
   }
   if (handler == null) {
     handler = (CancelHandler) DIContainerUtil.getComponentNoException(CancelHandler.class);
     if (handler == null) {
       return false;
     }
   }
   final List candidates = handler.getCancellableExceptions();
   for (Iterator itr = candidates.iterator(); itr.hasNext(); ) {
     Class tc = (Class) itr.next();
     if (t.getClass() == tc) {
       logger.log("WTDA0206", new Object[] {t});
       return true;
     }
   }
   final List nameCandidates = handler.getCancellableExceptionNames();
   for (Iterator itr = nameCandidates.iterator(); itr.hasNext(); ) {
     final String name = (String) itr.next();
     if (t.getClass().getName().endsWith(name)) {
       logger.log("WTDA0206", new Object[] {t});
       return true;
     }
   }
   return false;
 }
 private void reloadRoutes() {
   if (loading || routesIsNotFile()) {
     return;
   }
   if (lastLoaded < 0
       || checkInterval >= 0 && System.currentTimeMillis() > lastLoaded + checkInterval * 1000) {
     synchronized (this) {
       if (!loading) loading = true;
       else return;
     }
     if (loading) {
       try {
         logger.debug("check update for routes.");
         if (routes.lastModified() > lastLoaded) {
           long t1 = System.currentTimeMillis();
           Routes.load(routes);
           long t2 = System.currentTimeMillis();
           logger.debug(String.format("reload routes(%dms).", (t2 - t1)));
         }
         lastLoaded = System.currentTimeMillis();
       } finally {
         loading = false;
       }
     }
   }
 }
/**
 * コンテナに対してHTTP Servlet関連のテストを行うための情報を追加する。
 *
 * @author m_nori
 */
public class HttpServletTestInclude implements ContainerInclude {
  private static final Logger logger = Logger.getLogger(HttpServletTestInclude.class);

  public void execute(S2Container container) throws Exception {
    logger.debug("HttpServletTestInclude.execute()");
    setMockContext(container);
    container.setExternalContextComponentDefRegister(
        new HttpServletExternalContextComponentDefRegister());
    ComponentDeployerFactory.setProvider(new ExternalComponentDeployerProvider());
  }

  /**
   * Servlet等のモックを作成する。
   *
   * @return
   * @throws Exception
   */
  private void setMockContext(S2Container container) throws Exception {
    MockServletContext servletContext = new MockServletContextImpl("s2-example");
    MockHttpServletRequest request = servletContext.createRequest("/hello.html");
    MockHttpServletResponse response = new MockHttpServletResponseImpl(request);
    MockServletConfig servletConfig = new MockServletConfigImpl();
    servletConfig.setServletContext(servletContext);
    Servlet servlet = new S2ContainerServlet();
    servlet.init(servletConfig);
    container.register(servletConfig);
    container.register(servletContext);
    container.register(servlet);
    container.register(request);
    container.register(response);
  }
}
Exemple #4
0
  public static Converter findConverter(final FacesContext context, final UIOutput component) {

    Converter converter = component.getConverter();
    if (converter != null) {
      return converter;
    }
    ValueBinding vb = component.getValueBinding("value");
    if (vb != null) {
      String expression = vb.getExpressionString();
      converter = ConverterResource.getConverter(expression);
      if (converter != null) {
        return converter;
      }
    }
    final Class valueType = getValueType(context, component);
    if (ComponentUtil_.isPerformNoConversion(valueType)) {
      return null;
    }
    try {
      return context.getApplication().createConverter(valueType);
    } catch (final FacesException ex) {
      logger.log(ex);
      return null;
    }
  }
/**
 * 引数や戻り値を出力しない単純なトレース用の{@link MethodInterceptor}です。
 *
 * @author higa
 */
public class SimpleTraceInterceptor extends AbstractInterceptor {

  private static final long serialVersionUID = 1L;

  private static final Logger logger = Logger.getLogger(SimpleTraceInterceptor.class);

  public Object invoke(final MethodInvocation invocation) throws Throwable {
    if (!logger.isDebugEnabled()) {
      return invocation.proceed();
    }
    final StringBuffer buf = new StringBuffer(100);
    buf.append(getTargetClass(invocation).getName());
    buf.append("#");
    buf.append(invocation.getMethod().getName());
    logger.debug("BEGIN " + buf);
    try {
      return invocation.proceed();
    } catch (Throwable t) {
      buf.append(" Throwable:").append(t);
      throw t;
    } finally {
      logger.debug("END " + buf);
    }
  }
}
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
    HttpServletRequest req = (HttpServletRequest) request;
    HttpServletResponse res = (HttpServletResponse) response;
    String contextPath = req.getContextPath();
    if (contextPath.equals("/")) {
      contextPath = "";
    }
    String path = RequestUtil.getPath(req);
    if (!processDirectAccess(request, response, chain, path)) {
      return;
    }
    reloadRoutes();

    if (path.indexOf('.') < 0) {
      // If the request pass via reverse proxy, the original path must be gotten from HTTP header.
      if (!contextSensitive) {
        path = getOriginalPath(req);
      }
      try {
        Options options = Routes.recognizePath(path);
        String controller = options.getString("controller");
        String action = options.getString("action");
        Options params = options.except("controller", "action");

        String actionPath = ControllerUtil.fromClassNameToPath(controller);
        S2Container container = SingletonS2ContainerFactory.getContainer();
        if (container.hasComponentDef(actionPath.replace('/', '_').concat("Action"))) {
          S2ExecuteConfig executeConfig;
          if (StringUtil.equals(action, "index")) {
            executeConfig = S2ExecuteConfigUtil.findExecuteConfig("/" + actionPath, req);
            action = executeConfig.getMethod().getName();
          } else {
            executeConfig = S2ExecuteConfigUtil.findExecuteConfig("/" + actionPath, action);
          }
          if (executeConfig != null) {
            StringBuilder forwardPath = new StringBuilder(256);
            forwardPath
                .append("/")
                .append(actionPath)
                .append(".do?SAStruts.method=")
                .append(URLEncoderUtil.encode(action));
            for (String key : params.keySet()) {
              forwardPath
                  .append("&")
                  .append(URLEncoderUtil.encode(key))
                  .append("=")
                  .append(URLEncoderUtil.encode(params.getString(key)));
            }
            logger.debug(String.format("recognize route %s as %s#%s.", path, actionPath, action));
            req.getRequestDispatcher(forwardPath.toString()).forward(req, res);
            return;
          }
        }
      } catch (RoutingException e) {
        if (!fallThrough) throw e;
      }
    }
    chain.doFilter(request, response);
  }
 public void execute(S2Container container) throws Exception {
   logger.debug("HttpServletTestInclude.execute()");
   setMockContext(container);
   container.setExternalContextComponentDefRegister(
       new HttpServletExternalContextComponentDefRegister());
   ComponentDeployerFactory.setProvider(new ExternalComponentDeployerProvider());
 }
/**
 * 期待値を読み込む実装クラスです。
 *
 * <p>期待値はExcelから読み込みます。
 *
 * @author taedium
 */
public class ExpectedDataReaderImpl implements ExpectedDataReader {

  /** ロガー */
  protected static final Logger logger = Logger.getLogger(ExpectedDataReaderImpl.class);

  /** 期待値が記述されたExcelのパスのリスト */
  protected final List<String> expectedDataXlsPaths = CollectionsUtil.newArrayList();

  /** データアクセッサー */
  protected DataAccessor dataAccessor;

  /**
   * データアクセッサーを設定します。
   *
   * @param dataAccessor データアクセッサー
   */
  @Binding(bindingType = BindingType.MUST)
  public void setDataAccessor(final DataAccessor dataAccessor) {
    this.dataAccessor = dataAccessor;
  }

  /**
   * 期待値が記述されたExcelのパスを登録します。
   *
   * @param path 期待値が記述されたExcelのパス
   */
  public void addExpectedDataXlsPath(final String path) {
    expectedDataXlsPaths.add(path);
  }

  public DataSet read(TestContext testContext) {
    final String dirPath = testContext.getTestClassPackagePath();
    final boolean trimString = testContext.isTrimString();
    for (final String path : expectedDataXlsPaths) {
      if (ResourceUtil.isExist(path)) {
        return readXls(path, trimString);
      }
      final String newPath = dirPath + "/" + path;
      if (ResourceUtil.isExist(newPath)) {
        return readXls(newPath, trimString);
      }
    }
    return null;
  }

  /**
   * 指定されたExcelを読みデータセットとして返します。
   *
   * @param path Excelのパス
   * @param trimString 文字列に含まれる空白を取り除く場合<code>true</code>
   * @return Excel内のデータのデータセット表現
   */
  protected DataSet readXls(final String path, final boolean trimString) {
    if (logger.isDebugEnabled()) {
      logger.log("DSSR0104", new Object[] {path});
    }
    return dataAccessor.readXls(path, trimString);
  }
}
 public void setRollbackOnly() {
   try {
     if (userTransaction.getStatus() == STATUS_ACTIVE) {
       userTransaction.setRollbackOnly();
     }
   } catch (final Exception e) {
     logger.log("ESSR0017", new Object[] {e.getMessage()}, e);
   }
 }
 public Object invoke(final MethodInvocation invocation) throws Throwable {
   if (!logger.isDebugEnabled()) {
     return invocation.proceed();
   }
   final StringBuffer buf = new StringBuffer(100);
   buf.append(getTargetClass(invocation).getName());
   buf.append("#");
   buf.append(invocation.getMethod().getName());
   logger.debug("BEGIN " + buf);
   try {
     return invocation.proceed();
   } catch (Throwable t) {
     buf.append(" Throwable:").append(t);
     throw t;
   } finally {
     logger.debug("END " + buf);
   }
 }
 /** ステートメントをクローズします。 */
 protected void closeStatements() {
   if (statement != null) {
     try {
       statement.close();
     } catch (SQLException ignore) {
       logger.log(ignore);
     }
     statement = null;
   }
   if (preparedStatement != null) {
     try {
       preparedStatement.close();
     } catch (SQLException ignore) {
       logger.log(ignore);
     }
     preparedStatement = null;
   }
 }
 /** コネクションをクローズします。 */
 protected void closeConnection() {
   if (connection != null) {
     try {
       connection.close();
     } catch (SQLException ignore) {
       logger.log(ignore);
     }
     connection = null;
   }
 }
 /**
  * 例外を追加します。
  *
  * @param exception
  */
 public void addException(RuntimeException exception) {
   closeStatements();
   closeConnection();
   if (haltOnError) {
     throw exception;
   }
   logger.debug(exception);
   exceptionList.add(exception);
   openConnection();
 }
 /**
  * 引数を返します。
  *
  * @param argTypes
  * @return 引数
  */
 protected Object[] getArgs(Class[] argTypes) {
   Object[] args = new Object[argTypes.length];
   for (int i = 0; i < argTypes.length; ++i) {
     try {
       args[i] = getComponentDef().getContainer().getComponent(argTypes[i]);
     } catch (ComponentNotFoundRuntimeException ex) {
       logger.log(
           "WSSR0007",
           new Object[] {getComponentDef().getComponentClass().getName(), ex.getComponentKey()});
       args[i] = null;
     }
   }
   return args;
 }
  public FacesConfig configure() {
    List configs = new LinkedList();
    String path = getPath();
    if (logger_.isDebugEnabled()) {
      logger_.debug("target file path = " + path);
    }
    if (path == null) {
      return null;
    }
    String[] paths = StringUtil.split(path, FACES_CONFIG_DELIMETER);

    for (int i = 0; i < paths.length; i++) {
      final String targetPath = paths[i];
      final SaxHandlerParser parser = createSaxHandlerParser();
      InputStream is = resourceResolver_.getInputStream(targetPath.trim());
      try {
        configs.add(parser.parse(is, targetPath));
      } finally {
        InputStreamUtil.close(is);
      }
    }
    return FacesConfigUtil.collectAllFacesConfig(configs);
  }
/** @author shot */
public class ConfigFilesFacesConfigurator extends AbstractFacesConfigurator {

  private static final Logger logger_ = Logger.getLogger(ConfigFilesFacesConfigurator.class);

  private static final String FACES_CONFIG_DELIMETER = ",";

  public ConfigFilesFacesConfigurator() {
    setResourceResolver(new WebResourceResolver());
  }

  public FacesConfig configure() {
    List configs = new LinkedList();
    String path = getPath();
    if (logger_.isDebugEnabled()) {
      logger_.debug("target file path = " + path);
    }
    if (path == null) {
      return null;
    }
    String[] paths = StringUtil.split(path, FACES_CONFIG_DELIMETER);

    for (int i = 0; i < paths.length; i++) {
      final String targetPath = paths[i];
      final SaxHandlerParser parser = createSaxHandlerParser();
      InputStream is = resourceResolver_.getInputStream(targetPath.trim());
      try {
        configs.add(parser.parse(is, targetPath));
      } finally {
        InputStreamUtil.close(is);
      }
    }
    return FacesConfigUtil.collectAllFacesConfig(configs);
  }

  public String getPath() {
    return FacesConfigOptions.getConfigFiles();
  }
}
Exemple #17
0
  public void destroy() {
    if (!inited) {
      return;
    }
    final ClassLoader currentLoader = Thread.currentThread().getContextClassLoader();
    Thread.currentThread().setContextClassLoader(classLoader);
    try {
      for (int i = getComponentDefSize() - 1; 0 <= i; --i) {
        try {
          getComponentDef(i).destroy();
        } catch (Throwable t) {
          logger.error("ESSR0017", t);
        }
      }
      for (int i = getChildSize() - 1; 0 <= i; --i) {
        getChild(i).destroy();
      }

      componentDefMap = null;
      componentDefList = null;
      namespace = null;
      path = null;
      children = null;
      childPositions = null;
      parents = null;
      descendants = null;
      externalContext = null;
      externalContextComponentDefRegister = null;
      metaDefSupport = null;
      classLoader = null;
      root = this;
      inited = false;
    } finally {
      Thread.currentThread().setContextClassLoader(currentLoader);
    }
  }
  public boolean isAutoIncrement(
      Connection connection,
      String catalogName,
      String schemaName,
      String tableName,
      String columnName)
      throws SQLException {
    String fullTableName = TableUtil.buildFullTableName(catalogName, schemaName, tableName);
    String sql = "select " + columnName + " from " + fullTableName + " where 1 = 0";
    logger.debug(sql);

    PreparedStatement ps = ConnectionUtil.prepareStatement(connection, sql);
    try {
      ResultSet rs = ps.executeQuery();
      try {
        ResultSetMetaData rsMetaData = rs.getMetaData();
        return rsMetaData.isAutoIncrement(1);
      } finally {
        ResultSetUtil.close(rs);
      }
    } finally {
      StatementUtil.close(ps);
    }
  }
 public void dispatch(String requestURI) throws IOException, FacesException {
   if (logger_.isDebugEnabled()) {
     logger_.debug("dispatch called.");
   }
 }
public class MockExternalContextImpl extends MockExternalContext {

  private static final Logger logger_ = Logger.getLogger(MockExternalContextImpl.class);

  private MockServletContext mockServletContext_;

  private MockHttpServletRequest mockHttpServletRequest_;

  private MockHttpServletResponse mockHttpServletResponse_;

  private Map applicationMap_;

  private Map requestParameterMap_;

  private Map requestCookieMap_ = new HashMap();

  private Map requestHeaderMap_ = new HashMap();

  private Map sessionMap_;

  private Map requestMap_;

  private Map requestParameterValuesMap_;

  private String pathInfo;

  public MockExternalContextImpl() {}

  public MockExternalContextImpl(
      MockServletContext context,
      MockHttpServletRequest request,
      MockHttpServletResponse response) {
    mockServletContext_ = context;
    mockHttpServletRequest_ = request;
    mockHttpServletResponse_ = response;
    applicationMap_ = new MockApplicationMap(mockServletContext_);
  }

  public void addRequestCookieMap(Cookie cookie) {
    requestCookieMap_.put(cookie.getName(), cookie);
  }

  public void setRequestCookieMap(Map map) {
    requestParameterMap_ = map;
  }

  public void addRequestParameterMap(String key, String value) {
    requestParameterMap_.put(key, value);
  }

  public void setRequestParameterMap(Map map) {
    requestParameterMap_ = map;
  }

  public void dispatch(String requestURI) throws IOException, FacesException {
    if (logger_.isDebugEnabled()) {
      logger_.debug("dispatch called.");
    }
  }

  public String encodeActionURL(String sb) {
    return getMockHttpServletResponse().encodeURL(sb);
  }

  public String encodeNamespace(String aValue) {
    return aValue;
  }

  public String encodeResourceURL(String url) {
    return getMockHttpServletResponse().encodeURL(url);
  }

  public Map getApplicationMap() {
    if (applicationMap_ == null) {
      applicationMap_ = new HashMap();
    }
    return applicationMap_;
  }

  public String getAuthType() {
    return getMockHttpServletRequest().getAuthType();
  }

  public Object getContext() {
    return getMockServletContext();
  }

  public MockServletContext getMockServletContext() {
    if (mockServletContext_ == null) {
      mockServletContext_ = new MockServletContextImpl("/mock-context");
    }
    return mockServletContext_;
  }

  public void setMockServletContext(MockServletContext mockServletContext) {
    mockServletContext_ = mockServletContext;
  }

  public String getInitParameter(String name) {
    return getMockServletContext().getInitParameter(name);
  }

  public Map getInitParameterMap() {
    return getMockServletContext().getInitParameterMap();
  }

  public String getRemoteUser() {
    return getMockHttpServletRequest().getRemoteUser();
  }

  public Object getRequest() {
    return getMockHttpServletRequest();
  }

  public MockHttpServletRequest getMockHttpServletRequest() {
    if (mockHttpServletRequest_ == null) {
      mockHttpServletRequest_ =
          new MockHttpServletRequestImpl(getMockServletContext(), "/mock-path.html");
    }
    return mockHttpServletRequest_;
  }

  public void setMockHttpServletRequest(MockHttpServletRequest mockHttpServletRequest) {
    mockHttpServletRequest_ = mockHttpServletRequest;
  }

  public String getRequestContextPath() {
    return getMockHttpServletRequest().getContextPath();
  }

  public Map getRequestCookieMap() {
    return requestCookieMap_;
  }

  public Map getRequestHeaderMap() {
    return requestHeaderMap_;
  }

  public Map getRequestHeaderValuesMap() {
    throw new UnsupportedOperationException();
  }

  public Locale getRequestLocale() {
    return getMockHttpServletRequest().getLocale();
  }

  public Iterator getRequestLocales() {
    return new LocalesIterator(getMockHttpServletRequest().getLocales());
  }

  public Map getRequestMap() {
    if (requestMap_ == null) {
      requestMap_ = new HashMap();
    }
    return requestMap_;
  }

  public Map getRequestParameterMap() {
    if (requestParameterMap_ == null) {
      requestParameterMap_ = new MockServletRequestParameterMap(getMockHttpServletRequest());
    }
    return requestParameterMap_;
  }

  public Iterator getRequestParameterNames() {
    throw new UnsupportedOperationException();
  }

  public Map getRequestParameterValuesMap() {
    if (requestParameterValuesMap_ == null) {
      requestParameterValuesMap_ =
          new MockServletRequestParameterValuesMap(getMockHttpServletRequest());
    }
    return requestParameterValuesMap_;
  }

  public String getRequestPathInfo() {
    if (pathInfo != null) {
      return pathInfo;
    }
    return getMockHttpServletRequest().getPathInfo();
  }

  public void setRequestPathInfo(String pathInfo) {
    this.pathInfo = pathInfo;
  }

  public String getRequestServletPath() {
    return getMockHttpServletRequest().getServletPath();
  }

  public URL getResource(String path) throws MalformedURLException {
    return getMockServletContext().getResource(path);
  }

  public InputStream getResourceAsStream(String path) {
    return getMockServletContext().getResourceAsStream(path);
  }

  public Set getResourcePaths(String path) {
    return getMockServletContext().getResourcePaths(path);
  }

  public Object getResponse() {
    return getMockHttpServletResponse();
  }

  public MockHttpServletResponse getMockHttpServletResponse() {
    if (mockHttpServletResponse_ == null) {
      mockHttpServletResponse_ = new MockHttpServletResponseImpl(getMockHttpServletRequest());
    }
    return mockHttpServletResponse_;
  }

  public void setMockHttpServletResponse(MockHttpServletResponse mockHttpServletResponse) {
    mockHttpServletResponse_ = mockHttpServletResponse;
  }

  public Object getSession(boolean create) {
    return getMockHttpServletRequest().getSession(create);
  }

  public Map getSessionMap() {
    if (sessionMap_ == null) {
      HttpSession session = getMockHttpServletRequest().getSession(true);
      sessionMap_ = new MockSessionMap(session);
    }
    return sessionMap_;
  }

  public java.security.Principal getUserPrincipal() {
    return getMockHttpServletRequest().getUserPrincipal();
  }

  public boolean isUserInRole(String role) {
    return getMockHttpServletRequest().isUserInRole(role);
  }

  public void log(String message) {
    getMockServletContext().log(message);
  }

  public void log(String message, Throwable throwable) {
    getMockServletContext().log(message, throwable);
  }

  public void redirect(String requestURI) throws IOException {
    getMockHttpServletResponse().sendRedirect(requestURI);
  }

  private static class LocalesIterator implements Iterator {
    public LocalesIterator(Enumeration locales) {
      this.locales = locales;
    }

    private Enumeration locales;

    public boolean hasNext() {
      return locales.hasMoreElements();
    }

    public Object next() {
      return locales.nextElement();
    }

    public void remove() {
      throw new UnsupportedOperationException();
    }
  }
}
/**
 * 標準的な方言をあつかうクラスです。
 *
 * @author taedium
 */
public class StandardGenDialect implements GenDialect {

  /** ロガー */
  protected static Logger logger = Logger.getLogger(StandardGenDialect.class);

  /** SQL型をキー、{@link SqlType}を値とするマップ */
  protected Map<Integer, SqlType> sqlTypeMap = new HashMap<Integer, SqlType>();

  /** カラムの型名をキー、{@link ColumnType}を値とするマップ */
  @SuppressWarnings("unchecked")
  protected Map<Object, ColumnType> columnTypeMap = new CaseInsensitiveMap();

  /** カラムのSQL型をキー、{@link ColumnType}を値とするマップ。 */
  protected Map<Integer, ColumnType> fallbackColumnTypeMap = new HashMap<Integer, ColumnType>();

  /** インスタンスを構築します。 */
  public StandardGenDialect() {
    sqlTypeMap.put(Types.BIGINT, new BigIntType());
    sqlTypeMap.put(Types.BINARY, new BinaryType());
    sqlTypeMap.put(Types.BLOB, new BlobType());
    sqlTypeMap.put(Types.BOOLEAN, new BooleanType());
    sqlTypeMap.put(Types.CHAR, new CharType());
    sqlTypeMap.put(Types.CLOB, new ClobType());
    sqlTypeMap.put(Types.DATE, new DateType());
    sqlTypeMap.put(Types.DECIMAL, new DecimalType());
    sqlTypeMap.put(Types.DOUBLE, new DoubleType());
    sqlTypeMap.put(Types.FLOAT, new FloatType());
    sqlTypeMap.put(Types.INTEGER, new IntegerType());
    sqlTypeMap.put(Types.SMALLINT, new SmallIntType());
    sqlTypeMap.put(Types.TIME, new TimeType());
    sqlTypeMap.put(Types.TIMESTAMP, new TimestampType());
    sqlTypeMap.put(Types.VARCHAR, new VarcharType());

    columnTypeMap.put("bigint", StandardColumnType.BIGINT);
    columnTypeMap.put("binary", StandardColumnType.BINARY);
    columnTypeMap.put("bit", StandardColumnType.BIT);
    columnTypeMap.put("blob", StandardColumnType.BLOB);
    columnTypeMap.put("boolean", StandardColumnType.BOOLEAN);
    columnTypeMap.put("char", StandardColumnType.CHAR);
    columnTypeMap.put("clob", StandardColumnType.CLOB);
    columnTypeMap.put("date", StandardColumnType.DATE);
    columnTypeMap.put("decimal", StandardColumnType.DECIMAL);
    columnTypeMap.put("double", StandardColumnType.DOUBLE);
    columnTypeMap.put("float", StandardColumnType.FLOAT);
    columnTypeMap.put("integer", StandardColumnType.INTEGER);
    columnTypeMap.put("longvarbinary", StandardColumnType.LONGVARBINARY);
    columnTypeMap.put("longvarchar", StandardColumnType.LONGVARCHAR);
    columnTypeMap.put("numeric", StandardColumnType.NUMERIC);
    columnTypeMap.put("real", StandardColumnType.REAL);
    columnTypeMap.put("smallint", StandardColumnType.SMALLINT);
    columnTypeMap.put("time", StandardColumnType.TIME);
    columnTypeMap.put("timestamp", StandardColumnType.TIMESTAMP);
    columnTypeMap.put("tinyint", StandardColumnType.TINYINT);
    columnTypeMap.put("varbinary", StandardColumnType.VARBINARY);
    columnTypeMap.put("varchar", StandardColumnType.VARCHAR);

    fallbackColumnTypeMap.put(Types.BIGINT, StandardColumnType.BIGINT);
    fallbackColumnTypeMap.put(Types.BINARY, StandardColumnType.BINARY);
    fallbackColumnTypeMap.put(Types.BIT, StandardColumnType.BIT);
    fallbackColumnTypeMap.put(Types.BLOB, StandardColumnType.BLOB);
    fallbackColumnTypeMap.put(Types.BOOLEAN, StandardColumnType.BOOLEAN);
    fallbackColumnTypeMap.put(Types.CHAR, StandardColumnType.CHAR);
    fallbackColumnTypeMap.put(Types.CLOB, StandardColumnType.CLOB);
    fallbackColumnTypeMap.put(Types.DATE, StandardColumnType.DATE);
    fallbackColumnTypeMap.put(Types.DECIMAL, StandardColumnType.DECIMAL);
    fallbackColumnTypeMap.put(Types.DOUBLE, StandardColumnType.DOUBLE);
    fallbackColumnTypeMap.put(Types.FLOAT, StandardColumnType.FLOAT);
    fallbackColumnTypeMap.put(Types.INTEGER, StandardColumnType.INTEGER);
    fallbackColumnTypeMap.put(Types.LONGVARBINARY, StandardColumnType.LONGVARBINARY);
    fallbackColumnTypeMap.put(Types.LONGVARCHAR, StandardColumnType.LONGVARCHAR);
    fallbackColumnTypeMap.put(Types.NUMERIC, StandardColumnType.NUMERIC);
    fallbackColumnTypeMap.put(Types.REAL, StandardColumnType.REAL);
    fallbackColumnTypeMap.put(Types.SMALLINT, StandardColumnType.SMALLINT);
    fallbackColumnTypeMap.put(Types.TIME, StandardColumnType.TIME);
    fallbackColumnTypeMap.put(Types.TIMESTAMP, StandardColumnType.TIMESTAMP);
    fallbackColumnTypeMap.put(Types.TINYINT, StandardColumnType.TINYINT);
    fallbackColumnTypeMap.put(Types.VARBINARY, StandardColumnType.VARBINARY);
    fallbackColumnTypeMap.put(Types.VARCHAR, StandardColumnType.VARCHAR);
  }

  public String getName() {
    return null;
  }

  public String getDefaultSchemaName(String userName) {
    return userName;
  }

  public SqlType getSqlType(int sqlType) {
    return getSqlTypeInternal(sqlType);
  }

  public SqlType getSqlType(ValueTypeProvider valueTypeProvider, PropertyMeta propertyMeta) {
    ValueType valueType = valueTypeProvider.provide(propertyMeta);
    return getSqlTypeInternal(valueType.getSqlType());
  }

  /**
   * 内部的にSQL型を返します。
   *
   * @param sqlType JDBCのSQL型
   * @return SQL型
   */
  protected SqlType getSqlTypeInternal(int sqlType) {
    SqlType type = sqlTypeMap.get(sqlType);
    if (type != null) {
      return type;
    }
    throw new UnsupportedSqlTypeRuntimeException(sqlType);
  }

  public ColumnType getColumnType(String typeName, int sqlType) {
    ColumnType columnType = columnTypeMap.get(typeName);
    return columnType != null ? columnType : fallbackColumnTypeMap.get(sqlType);
  }

  public GenerationType getDefaultGenerationType() {
    return GenerationType.TABLE;
  }

  public String getOpenQuote() {
    return "\"";
  }

  public String getCloseQuote() {
    return "\"";
  }

  public String quote(String value) {
    if (value == null) {
      return null;
    }
    return getOpenQuote() + value + getCloseQuote();
  }

  public String unquote(String value) {
    String s = StringUtil.ltrim(value, getOpenQuote());
    return StringUtil.rtrim(s, getCloseQuote());
  }

  public boolean supportsSequence() {
    return false;
  }

  public boolean supportsGetIndexInfo(String catalogName, String schemaName, String tableName) {
    return true;
  }

  public String getSequenceDefinitionFragment(
      String dataType, long initialValue, int allocationSize) {
    throw new UnsupportedOperationException("getSequenceDefinitionFragment");
  }

  public String getSqlBlockDelimiter() {
    return null;
  }

  public String getIdentityColumnDefinition() {
    throw new UnsupportedOperationException("getIdentityDefinition");
  }

  public String getDropForeignKeySyntax() {
    return "drop constraint";
  }

  public String getDropUniqueKeySyntax() {
    return "drop constraint";
  }

  public boolean isTableNotFound(Throwable throwable) {
    return false;
  }

  public boolean isColumnNotFound(Throwable throwable) {
    return false;
  }

  public boolean isSequenceNotFound(Throwable throwable) {
    return false;
  }

  public SqlBlockContext createSqlBlockContext() {
    return new StandardSqlBlockContext();
  }

  public boolean supportsIdentityInsert() {
    return false;
  }

  public boolean supportsIdentityInsertControlStatement() {
    return false;
  }

  public String getIdentityInsertEnableStatement(String tableName) {
    throw new UnsupportedOperationException("getIdentityInsertOnStatement");
  }

  public String getIdentityInsertDisableStatement(String tableName) {
    throw new UnsupportedOperationException("getIdentityInsertOffStatement");
  }

  public boolean supportsNullableUnique() {
    return true;
  }

  public boolean supportsIdentity() {
    return false;
  }

  public String getSequenceNextValString(final String sequenceName, final int allocationSize) {
    throw new UnsupportedOperationException("getSequenceNextValString");
  }

  public boolean supportsCommentInCreateTable() {
    return false;
  }

  public boolean supportsCommentOn() {
    return false;
  }

  public boolean isJdbcCommentAvailable() {
    return true;
  }

  public String getTableComment(
      Connection connection, String catalogName, String schemaName, String tableName)
      throws SQLException {
    throw new UnsupportedOperationException("getTableComment");
  }

  public Map<String, String> getColumnCommentMap(
      Connection connection, String catalogName, String schemaName, String tableName)
      throws SQLException {
    throw new UnsupportedOperationException("getColumnCommentMap");
  }

  public boolean supportsReferentialDeleteRule() {
    return true;
  }

  public boolean supportsReferentialUpdateRule() {
    return true;
  }

  public boolean isAutoIncrement(
      Connection connection,
      String catalogName,
      String schemaName,
      String tableName,
      String columnName)
      throws SQLException {
    String fullTableName = TableUtil.buildFullTableName(catalogName, schemaName, tableName);
    String sql = "select " + columnName + " from " + fullTableName + " where 1 = 0";
    logger.debug(sql);

    PreparedStatement ps = ConnectionUtil.prepareStatement(connection, sql);
    try {
      ResultSet rs = ps.executeQuery();
      try {
        ResultSetMetaData rsMetaData = rs.getMetaData();
        return rsMetaData.isAutoIncrement(1);
      } finally {
        ResultSetUtil.close(rs);
      }
    } finally {
      StatementUtil.close(ps);
    }
  }

  /**
   * 例外チェーンをたどって原因となった{@link SQLException#getSQLState() SQLステート}を返します。
   *
   * <p>例外チェーンに{@link SQLException SQL例外}が存在しない場合や、SQLステートが設定されていない場合は <code>null</code>を返します。
   *
   * @param t 例外
   * @return 原因となった{@link SQLException#getSQLState() SQLステート}
   */
  protected String getSQLState(Throwable t) {
    SQLException cause = getCauseSQLException(t);
    if (cause != null && !StringUtil.isEmpty(cause.getSQLState())) {
      return cause.getSQLState();
    }
    return null;
  }

  /**
   * 例外チェーンをたどって原因となった{@link SQLException#getErrorCode() ベンダー固有の例外コード}を返します。
   *
   * <p>例外チェーンに{@link SQLException SQL例外}が存在しない場合や、例外コードが設定されていない場合は <code>null</code>を返します。
   *
   * @param t 例外
   * @return 原因となった{@link SQLException#getErrorCode() ベンダー固有の例外コード}
   */
  protected Integer getErrorCode(Throwable t) {
    SQLException cause = getCauseSQLException(t);
    if (cause != null) {
      return cause.getErrorCode();
    }
    return null;
  }

  /**
   * 例外チェーンをたどって原因となった{@link SQLException SQL例外}を返します。
   *
   * <p>例外チェーンにSQL例外が存在しない場合は<code>null</code>を返します。
   *
   * @param t 例外
   * @return 原因となった{@link SQLException SQL例外}
   */
  protected SQLException getCauseSQLException(Throwable t) {
    SQLException cause = null;
    while (t != null) {
      if (t instanceof SQLException) {
        cause = SQLException.class.cast(t);
        if (cause.getNextException() != null) {
          cause = cause.getNextException();
          t = cause;
          continue;
        }
      }
      t = t.getCause();
    }
    return cause;
  }

  /**
   * 標準の{@link ColumnType}の実装クラスです。
   *
   * @author taedium
   */
  public static class StandardColumnType implements ColumnType {

    private static StandardColumnType BIGINT = new StandardColumnType("bigint", Long.class);

    private static StandardColumnType BINARY = new StandardColumnType("binary", byte[].class);

    private static StandardColumnType BIT = new StandardColumnType("bit", Boolean.class);

    private static StandardColumnType BLOB = new StandardColumnType("blob", byte[].class, true);

    private static StandardColumnType BOOLEAN = new StandardColumnType("boolean", Boolean.class);

    private static StandardColumnType CHAR = new StandardColumnType("char($l)", String.class);

    private static StandardColumnType CLOB = new StandardColumnType("clob", String.class, true);

    private static StandardColumnType DATE = new StandardColumnType("date", java.sql.Date.class);

    private static StandardColumnType DECIMAL = new StandardColumnType("decimal", BigDecimal.class);

    private static StandardColumnType DOUBLE = new StandardColumnType("double", Double.class);

    private static StandardColumnType FLOAT = new StandardColumnType("float", Float.class);

    private static StandardColumnType INTEGER = new StandardColumnType("integer", Integer.class);

    private static StandardColumnType LONGVARBINARY =
        new StandardColumnType("longvarbinary", byte[].class);

    private static StandardColumnType LONGVARCHAR =
        new StandardColumnType("longvarchar", String.class);

    private static StandardColumnType NUMERIC = new StandardColumnType("numeric", BigDecimal.class);

    private static StandardColumnType REAL = new StandardColumnType("real", Float.class);

    private static StandardColumnType SMALLINT = new StandardColumnType("smallint", Short.class);

    private static StandardColumnType TIME = new StandardColumnType("time", java.sql.Time.class);

    private static StandardColumnType TIMESTAMP =
        new StandardColumnType("timestamp", Timestamp.class);

    private static StandardColumnType TINYINT = new StandardColumnType("tinyint", Short.class);

    private static StandardColumnType VARBINARY =
        new StandardColumnType("varbinary($l)", byte[].class);

    private static StandardColumnType VARCHAR = new StandardColumnType("varchar($l)", String.class);

    /** カラム定義 */
    protected String dataType;

    /** 属性のクラス */
    protected Class<?> attributeClass;

    /** LOBの場合{@code true} */
    protected boolean lob;

    /** 時制の種別 */
    protected TemporalType temporalType;

    /**
     * インスタンスを構築します。
     *
     * @param dataType データ型
     * @param attributeClass 属性のクラス
     */
    protected StandardColumnType(String dataType, Class<?> attributeClass) {
      this(dataType, attributeClass, false);
    }

    /**
     * インスタンスを構築します。
     *
     * @param dataType カラム定義
     * @param attributeClass 属性のクラス
     * @param lob LOBの場合{@code true}
     */
    protected StandardColumnType(String dataType, Class<?> attributeClass, boolean lob) {
      this(dataType, attributeClass, lob, null);
    }

    /**
     * インスタンスを構築します。
     *
     * @param dataType カラム定義
     * @param attributeClass 属性のクラス
     * @param lob LOBの場合{@code true}
     * @param temporalType 時制の種別
     */
    protected StandardColumnType(
        String dataType, Class<?> attributeClass, boolean lob, TemporalType temporalType) {
      this.dataType = dataType;
      this.attributeClass = attributeClass;
      this.lob = lob;
      this.temporalType = temporalType;
    }

    public String getColumnDefinition(int length, int precision, int scale, String defaultValue) {
      String completeDataType = ColumnUtil.formatDataType(dataType, length, precision, scale);
      return getColumnDefinitionInternal(completeDataType, defaultValue);
    }

    /**
     * カラム定義を返します。
     *
     * @param completeDataType 完全なデータ型
     * @param defaultValue デフォルト値、存在しない場合は{@code null}
     * @return カラム定義
     */
    protected String getColumnDefinitionInternal(String completeDataType, String defaultValue) {
      if (defaultValue == null) {
        return completeDataType;
      }
      return completeDataType + " default " + defaultValue;
    }

    public Class<?> getAttributeClass(int length, int precision, int scale) {
      return attributeClass;
    }

    public boolean isLob() {
      return lob;
    }

    public TemporalType getTemporalType() {
      return temporalType;
    }
  }

  /**
   * 標準の{@link StandardColumnType}の実装クラスです。
   *
   * @author taedium
   */
  public static class StandardSqlBlockContext implements SqlBlockContext {

    /** SQLブロックの開始を表すキーワードの連なりのリスト */
    protected List<List<String>> sqlBlockStartKeywordsList = new ArrayList<List<String>>();

    /** 追加されたキーワードの連なり */
    protected List<String> keywords = new ArrayList<String>();

    /** SQLブロックの内側の場合{@code true} */
    protected boolean inSqlBlock;

    public void addKeyword(String keyword) {
      if (!inSqlBlock) {
        keywords.add(keyword);
        check();
      }
    }

    /** ブロックの内側かどうかチェックします。 */
    protected void check() {
      for (List<String> startKeywords : sqlBlockStartKeywordsList) {
        if (startKeywords.size() > keywords.size()) {
          continue;
        }
        for (int i = 0; i < startKeywords.size(); i++) {
          String word1 = startKeywords.get(i);
          String word2 = keywords.get(i);
          inSqlBlock = word1.equalsIgnoreCase(word2);
          if (!inSqlBlock) {
            break;
          }
        }
        if (inSqlBlock) {
          break;
        }
      }
    }

    public boolean isInSqlBlock() {
      return inSqlBlock;
    }
  }
}
/**
 * {@link SqlExecutionContext}の実装クラスです。
 *
 * @author taedium
 */
public class SqlExecutionContext {

  /** ロガー */
  protected static final Logger logger = Logger.getLogger(SqlExecutionContext.class);

  /** {@link RuntimeException}のリスト */
  protected List<RuntimeException> exceptionList = new ArrayList<RuntimeException>();

  /** データソース */
  protected DataSource dataSource;

  /** コネクション */
  protected Connection connection;

  /** エラー発生時に処理を即座に中断する場合{@code true}、中断しない場合{@code false} */
  protected boolean haltOnError;

  /** ステートメント */
  protected Statement statement;

  /** 準備されたステートメント */
  protected PreparedStatement preparedStatement;

  /**
   * @param dataSource データソース
   * @param haltOnError エラー発生時に処理を即座に中断する場合{@code true}、中断しない場合{@code false}
   */
  public SqlExecutionContext(DataSource dataSource, boolean haltOnError) {
    if (dataSource == null) {
      throw new NullPointerException("dataSource");
    }
    this.dataSource = dataSource;
    this.haltOnError = haltOnError;
    openConnection();
  }

  /**
   * ステートメントを返します。
   *
   * @return ステートメント
   */
  public Statement getStatement() {
    if (statement != null) {
      return statement;
    }
    statement = ConnectionUtil.createStatement(connection);
    return statement;
  }

  /**
   * 準備されたステートメントを返します。
   *
   * @param sql SQL
   * @return 準備されたステートメント
   */
  public PreparedStatement getPreparedStatement(String sql) {
    if (connection != null && preparedStatement != null) {
      StatementUtil.close(preparedStatement);
    }
    preparedStatement = ConnectionUtil.prepareStatement(connection, sql);
    return preparedStatement;
  }

  /**
   * 例外のリストを返します。
   *
   * @return 例外のリスト
   */
  public List<RuntimeException> getExceptionList() {
    return Collections.unmodifiableList(exceptionList);
  }

  /**
   * 例外を追加します。
   *
   * @param exception
   */
  public void addException(RuntimeException exception) {
    closeStatements();
    closeConnection();
    if (haltOnError) {
      throw exception;
    }
    logger.debug(exception);
    exceptionList.add(exception);
    openConnection();
  }

  /** 例外を通知します。 */
  public void notifyException() {
    closeStatements();
    closeConnection();
    openConnection();
  }

  /** 破棄します。 */
  public void destroy() {
    if (connection == null) {
      return;
    }
    closeStatements();
    closeConnection();
    exceptionList.clear();
  }

  /** ステートメントをクローズします。 */
  protected void closeStatements() {
    if (statement != null) {
      try {
        statement.close();
      } catch (SQLException ignore) {
        logger.log(ignore);
      }
      statement = null;
    }
    if (preparedStatement != null) {
      try {
        preparedStatement.close();
      } catch (SQLException ignore) {
        logger.log(ignore);
      }
      preparedStatement = null;
    }
  }

  /** コネクションをクローズします。 */
  protected void closeConnection() {
    if (connection != null) {
      try {
        connection.close();
      } catch (SQLException ignore) {
        logger.log(ignore);
      }
      connection = null;
    }
  }

  /** コネクションをオープンします。 */
  protected void openConnection() {
    connection = DataSourceUtil.getConnection(dataSource);
  }
}
 /**
  * 指定されたExcelを読みデータセットとして返します。
  *
  * @param path Excelのパス
  * @param trimString 文字列に含まれる空白を取り除く場合<code>true</code>
  * @return Excel内のデータのデータセット表現
  */
 protected DataSet readXls(final String path, final boolean trimString) {
   if (logger.isDebugEnabled()) {
     logger.log("DSSR0104", new Object[] {path});
   }
   return dataAccessor.readXls(path, trimString);
 }
/**
 * Routing filter like Ruby on Rails.
 *
 * @author kawasima
 */
public class AdvancedRoutingFilter implements Filter {
  private static final Logger logger = Logger.getLogger(AdvancedRoutingFilter.class);
  private static volatile boolean loading = false;
  /** 最後にroutes設定を読み込んだ時刻が入ります。 */
  private static long lastLoaded = -1;

  /** JSPのダイレクトアクセスを許すかどうかです。 */
  protected boolean jspDirectAccess = false;

  /** ルート定義ファイルのパスです。 */
  protected File routes;

  /** ルート定義ファイルの更新チェックをする時間を決めます。 */
  protected Long checkInterval;

  /**
   * If contextSensitive is true, recognize the path after context path and generate the path with
   * context path.
   */
  protected boolean contextSensitive = false;

  /** Header name stands for request-uri. This parameter is used with a reverse proxy. */
  protected String requestUriHeader;

  /** Whether the routing exception fall through. */
  protected boolean fallThrough = false;

  public void init(FilterConfig config) throws ServletException {
    String access = config.getInitParameter("jspDirectAccess");
    if (StringUtil.isNotBlank(access)) {
      jspDirectAccess = Boolean.valueOf(access);
    }

    String routesPath = config.getInitParameter("routes");
    if (StringUtil.isNotEmpty(routesPath)) {
      String realRoutesPath = config.getServletContext().getRealPath(routesPath);
      if (realRoutesPath != null) {
        routes = new File(realRoutesPath);
      }
      InputStream routesStream = config.getServletContext().getResourceAsStream(routesPath);
      try {
        Routes.load(routesStream);
      } finally {
        InputStreamUtil.close(routesStream);
      }
      lastLoaded = System.currentTimeMillis();
    }

    String interval = config.getInitParameter("checkInterval");
    if (StringUtil.isNotEmpty(interval)) {
      checkInterval = LongConversionUtil.toLong(interval);
    }
    if (checkInterval == null || checkInterval < 0) {
      checkInterval = -1L;
    }

    String contextSensitiveParam = config.getInitParameter("contextSensitive");
    if (StringUtil.isNotBlank(contextSensitiveParam)) {
      contextSensitive = Boolean.valueOf(contextSensitiveParam);
    }
    if (contextSensitive) {
      try {
        Method getContextPath = ReflectionUtil.getMethod(ServletContext.class, "getContextPath");
        UrlRewriter.contextPath =
            (String) MethodUtil.invoke(getContextPath, config.getServletContext(), null);
      } catch (NoSuchMethodRuntimeException e) {
        UrlRewriter.contextPath = config.getServletContext().getServletContextName();
      }
    }
    requestUriHeader = config.getInitParameter("requestUriHeader");

    String fallThroughParam = config.getInitParameter("fallThrough");
    if (StringUtil.isNotBlank(fallThroughParam)) {
      fallThrough = Boolean.valueOf(fallThroughParam);
    }
  }

  public void destroy() {}

  private void reloadRoutes() {
    if (loading || routesIsNotFile()) {
      return;
    }
    if (lastLoaded < 0
        || checkInterval >= 0 && System.currentTimeMillis() > lastLoaded + checkInterval * 1000) {
      synchronized (this) {
        if (!loading) loading = true;
        else return;
      }
      if (loading) {
        try {
          logger.debug("check update for routes.");
          if (routes.lastModified() > lastLoaded) {
            long t1 = System.currentTimeMillis();
            Routes.load(routes);
            long t2 = System.currentTimeMillis();
            logger.debug(String.format("reload routes(%dms).", (t2 - t1)));
          }
          lastLoaded = System.currentTimeMillis();
        } finally {
          loading = false;
        }
      }
    }
  }

  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
    HttpServletRequest req = (HttpServletRequest) request;
    HttpServletResponse res = (HttpServletResponse) response;
    String contextPath = req.getContextPath();
    if (contextPath.equals("/")) {
      contextPath = "";
    }
    String path = RequestUtil.getPath(req);
    if (!processDirectAccess(request, response, chain, path)) {
      return;
    }
    reloadRoutes();

    if (path.indexOf('.') < 0) {
      // If the request pass via reverse proxy, the original path must be gotten from HTTP header.
      if (!contextSensitive) {
        path = getOriginalPath(req);
      }
      try {
        Options options = Routes.recognizePath(path);
        String controller = options.getString("controller");
        String action = options.getString("action");
        Options params = options.except("controller", "action");

        String actionPath = ControllerUtil.fromClassNameToPath(controller);
        S2Container container = SingletonS2ContainerFactory.getContainer();
        if (container.hasComponentDef(actionPath.replace('/', '_').concat("Action"))) {
          S2ExecuteConfig executeConfig;
          if (StringUtil.equals(action, "index")) {
            executeConfig = S2ExecuteConfigUtil.findExecuteConfig("/" + actionPath, req);
            action = executeConfig.getMethod().getName();
          } else {
            executeConfig = S2ExecuteConfigUtil.findExecuteConfig("/" + actionPath, action);
          }
          if (executeConfig != null) {
            StringBuilder forwardPath = new StringBuilder(256);
            forwardPath
                .append("/")
                .append(actionPath)
                .append(".do?SAStruts.method=")
                .append(URLEncoderUtil.encode(action));
            for (String key : params.keySet()) {
              forwardPath
                  .append("&")
                  .append(URLEncoderUtil.encode(key))
                  .append("=")
                  .append(URLEncoderUtil.encode(params.getString(key)));
            }
            logger.debug(String.format("recognize route %s as %s#%s.", path, actionPath, action));
            req.getRequestDispatcher(forwardPath.toString()).forward(req, res);
            return;
          }
        }
      } catch (RoutingException e) {
        if (!fallThrough) throw e;
      }
    }
    chain.doFilter(request, response);
  }

  /**
   * ダイレクトアクセスを処理します。
   *
   * @param request リクエスト
   * @param response レスポンス
   * @param chain フィルタチェイン
   * @param path パス
   * @return JSPのダイレクトアクセスのチェックがNGの場合は、 falseを返します。
   * @throws IOException IO例外が発生した場合。
   */
  protected boolean processDirectAccess(
      ServletRequest request, ServletResponse response, FilterChain chain, String path)
      throws IOException {
    if (!jspDirectAccess
        && ((HttpServletRequest) request).getMethod().equalsIgnoreCase("get")
        && path.endsWith(".jsp")) {
      String message = "Direct access for JSP is not permitted.";
      if (path.endsWith("index.jsp")) {
        message += " Remove \"index.jsp\" from welcome-file-list of (default) \"web.xml\".";
      }
      ((HttpServletResponse) response).sendError(HttpServletResponse.SC_BAD_REQUEST, message);
      return false;
    }
    return true;
  }

  /**
   * Strutsのサーブレットにフォワードします。
   *
   * @param request リクエスト
   * @param response レスポンス
   * @param actionPath アクションパス
   * @param paramPath パラメータのパス
   * @param executeConfig 実行設定
   * @throws IOException IO例外が発生した場合
   * @throws ServletException サーブレット例外が発生した場合
   */
  protected void forward(
      HttpServletRequest request,
      HttpServletResponse response,
      String actionPath,
      String paramPath,
      S2ExecuteConfig executeConfig)
      throws IOException, ServletException {
    String forwardPath = actionPath + ".do";
    if (executeConfig != null) {
      forwardPath = forwardPath + executeConfig.getQueryString(paramPath);
    }
    request.getRequestDispatcher(forwardPath).forward(request, response);
  }

  protected String getOriginalPath(HttpServletRequest req) {
    String path =
        StringUtil.isEmpty(requestUriHeader)
            ? req.getRequestURI()
            : req.getHeader(requestUriHeader);
    if (path == null) return "";

    int len = path.length();
    int i = 0;
    for (; i < len; i++) if (path.charAt(i) == '?' || path.charAt(i) == ';') break;
    if (i != len) path = path.substring(0, i);
    return path;
  }

  private boolean routesIsNotFile() {
    return routes == null;
  }
}
/**
 * {@link SequenceDescFactory}の実装クラスです。
 *
 * @author taedium
 */
public class SequenceDescFactoryImpl implements SequenceDescFactory {

  /** ロガー */
  protected static Logger logger = Logger.getLogger(SequenceDescFactoryImpl.class);

  /** 方言 */
  protected GenDialect dialect;

  /** {@link ValueType}の提供者 */
  protected ValueTypeProvider valueTypeProvider;

  /**
   * インスタンスを構築します。
   *
   * @param dialect 方言
   * @param valueTypeProvider {@link ValueType}の提供者
   */
  public SequenceDescFactoryImpl(GenDialect dialect, ValueTypeProvider valueTypeProvider) {
    if (dialect == null) {
      throw new NullPointerException("dialect");
    }
    if (valueTypeProvider == null) {
      throw new NullPointerException("valueTypeResolver");
    }
    this.dialect = dialect;
    this.valueTypeProvider = valueTypeProvider;
  }

  public SequenceDesc getSequenceDesc(EntityMeta entityMeta, PropertyMeta propertyMeta) {
    GenerationType generationType = propertyMeta.getGenerationType();
    if (generationType == GenerationType.AUTO) {
      generationType = dialect.getDefaultGenerationType();
    }
    if (generationType == GenerationType.SEQUENCE) {
      if (!dialect.supportsSequence()) {
        throw new UnsupportedGenerationTypeRuntimeException(
            GenerationType.SEQUENCE, entityMeta.getName(), propertyMeta.getName());
      }
      SequenceGenerator generator = getSequenceGenerator(entityMeta, propertyMeta);
      SequenceDesc sequenceDesc = new SequenceDesc();
      String sequenceName = getSequenceName(entityMeta, propertyMeta, generator);
      sequenceDesc.setSequenceName(sequenceName);
      sequenceDesc.setInitialValue(generator.initialValue());
      sequenceDesc.setAllocationSize(generator.allocationSize());
      sequenceDesc.setDataType(getDataType(propertyMeta));
      return sequenceDesc;
    }
    return null;
  }

  /**
   * シーケンスジェネレータを返します。
   *
   * @param entityMeta エンティティメタデータ
   * @param propertyMeta プロパティメタデータ
   * @return シーケンスジェネレータ
   */
  protected SequenceGenerator getSequenceGenerator(
      EntityMeta entityMeta, PropertyMeta propertyMeta) {
    Field field = propertyMeta.getField();
    GeneratedValue generatedValue = field.getAnnotation(GeneratedValue.class);
    if (generatedValue == null) {
      throw new IllegalStateException("@GeneratedValue not found.");
    }
    String name = generatedValue.generator();
    if (StringUtil.isEmpty(name)) {
      return AnnotationUtil.getDefaultSequenceGenerator();
    }
    SequenceGenerator sequenceGenerator = field.getAnnotation(SequenceGenerator.class);
    if (sequenceGenerator != null && name.equals(sequenceGenerator.name())) {
      return sequenceGenerator;
    }
    sequenceGenerator = entityMeta.getEntityClass().getAnnotation(SequenceGenerator.class);
    if (sequenceGenerator != null && name.equals(sequenceGenerator.name())) {
      return sequenceGenerator;
    }
    throw new IllegalStateException("@SequenceGenerator not found.");
  }

  /**
   * シーケンスの名前を返します。
   *
   * @param entityMeta エンティティメタデータ
   * @param propertyMeta プロパティメタデータ
   * @param sequenceGenerator シーケンスジェネレータ
   * @return シーケンスの名前
   */
  protected String getSequenceName(
      EntityMeta entityMeta, PropertyMeta propertyMeta, SequenceGenerator sequenceGenerator) {
    String sequenceName = sequenceGenerator.sequenceName();
    if (!StringUtil.isEmpty(sequenceName)) {
      return sequenceName;
    }
    return entityMeta.getTableMeta().getName() + "_" + propertyMeta.getColumnMeta().getName();
  }

  /**
   * シーケンスのデータ型を返します。
   *
   * @param propertyMeta プロパティメタデータ
   * @return シーケンスのデータ型
   */
  protected String getDataType(PropertyMeta propertyMeta) {
    ValueType valueType = valueTypeProvider.provide(propertyMeta);
    int sqlType = valueType.getSqlType();
    Column column = getColumn(propertyMeta);
    return dialect
        .getSqlType(sqlType)
        .getDataType(column.length(), column.precision(), column.scale(), false);
  }

  /**
   * カラムを返します。
   *
   * @param propertyMeta プロパティメタデータ
   * @return カラム
   */
  protected Column getColumn(PropertyMeta propertyMeta) {
    Field field = propertyMeta.getField();
    Column column = field.getAnnotation(Column.class);
    return column != null ? column : AnnotationUtil.getDefaultColumn();
  }
}
/**
 * JTAの{@link TransactionManager}を使用してトランザクションを制御する、 {@link TransactionManagerAdapter}の実装です。
 *
 * @author koichik
 * @since 2.4.18
 */
public class JTATransactionManagerAdapter implements TransactionManagerAdapter, Status {

  private static final Logger logger = Logger.getLogger(JTATransactionManagerAdapter.class);

  /** ユーザトランザクション */
  protected final UserTransaction userTransaction;

  /** トランザクションマネージャ */
  protected final TransactionManager transactionManager;

  /**
   * インスタンスを構築します。
   *
   * @param userTransaction ユーザトランザクション
   * @param transactionManager トランザクションマネージャ
   */
  public JTATransactionManagerAdapter(
      final UserTransaction userTransaction, final TransactionManager transactionManager) {
    this.userTransaction = userTransaction;
    this.transactionManager = transactionManager;
  }

  public Object required(final TransactionCallback callback) throws Throwable {
    final boolean began = begin();
    try {
      return callback.execute(this);
    } finally {
      if (began) {
        end();
      }
    }
  }

  public Object requiresNew(final TransactionCallback callback) throws Throwable {
    final Transaction tx = suspend();
    try {
      begin();
      try {
        return callback.execute(this);
      } finally {
        end();
      }
    } finally {
      if (tx != null) {
        resume(tx);
      }
    }
  }

  public Object mandatory(final TransactionCallback callback) throws Throwable {
    if (!hasTransaction()) {
      throw new SIllegalStateException("ESSR0311", null);
    }
    return callback.execute(this);
  }

  public Object notSupported(final TransactionCallback callback) throws Throwable {
    final Transaction tx = suspend();
    try {
      return callback.execute(this);
    } finally {
      if (tx != null) {
        resume(tx);
      }
    }
  }

  public Object never(final TransactionCallback callback) throws Throwable {
    if (hasTransaction()) {
      throw new SIllegalStateException("ESSR0317", null);
    }
    return callback.execute(this);
  }

  public void setRollbackOnly() {
    try {
      if (userTransaction.getStatus() == STATUS_ACTIVE) {
        userTransaction.setRollbackOnly();
      }
    } catch (final Exception e) {
      logger.log("ESSR0017", new Object[] {e.getMessage()}, e);
    }
  }

  /**
   * 現在のスレッド上でトランザクションがアクティブな場合は<code>true</code>を、それ以外の場合は<code>false</code>を返します。
   *
   * @return 現在のスレッド上でトランザクションがアクティブな場合は<code>true</code>
   * @throws SystemException トランザクションマネージャで例外が発生した場合にスローされます
   * @see javax.transaction.UserTransaction#getStatus()
   */
  protected boolean hasTransaction() throws SystemException {
    final int status = userTransaction.getStatus();
    return status != STATUS_NO_TRANSACTION && status != STATUS_UNKNOWN;
  }

  /**
   * トランザクションを開始します。
   *
   * <p>新しいトランザクションを開始した場合は<code>true</code>、それ以外の場合は<code>false</code>を返します。
   *
   * @return 新しいトランザクションを開始した場合は<code>true</code>
   * @throws Exception トランザクションマネージャで例外が発生した場合にスローされます
   * @see javax.transaction.TransactionManager#begin()
   */
  protected boolean begin() throws Exception {
    if (hasTransaction()) {
      return false;
    }
    userTransaction.begin();
    return true;
  }

  /**
   * トランザクションをコミットまたはロールバックします。
   *
   * <p>現在のスレッドに関連づけられているトランザクションがアクティブな場合は、 トランザクションをコミットします。 それ以外の場合はトランザクションをロールバックします。
   *
   * @throws Exception トランザクションマネージャで例外が発生した場合にスローされます
   * @see javax.transaction.TransactionManager#commit()
   * @see javax.transaction.TransactionManager#rollback()
   */
  protected void end() throws Exception {
    if (userTransaction.getStatus() == STATUS_ACTIVE) {
      userTransaction.commit();
    } else {
      userTransaction.rollback();
    }
  }

  /**
   * トランザクションを中断します。
   *
   * <p>現在のスレッド上でトランザクションが開始されていなければ<code>null</code>を返します。
   *
   * @return 中断された{@link javax.transaction.Transaction トランザクション}
   * @throws Exception トランザクションマネージャで例外が発生した場合にスローされます
   * @see javax.transaction.TransactionManager#suspend()
   */
  protected Transaction suspend() throws Exception {
    return hasTransaction() ? transactionManager.suspend() : null;
  }

  /**
   * トランザクションを再開します。
   *
   * @param transaction 再開する{@link javax.transaction.Transaction トランザクション}
   * @throws Exception トランザクションマネージャで例外が発生した場合にスローされます
   * @see javax.transaction.TransactionManager#resume(Transaction)
   */
  protected void resume(final Transaction transaction) throws Exception {
    transactionManager.resume(transaction);
  }
}
Exemple #27
0
/** @author manhole */
public class RendererUtil {

  private static final Logger logger = Logger.getLogger(RendererUtil.class);

  public static boolean containsAttributesForRender(
      final UIComponent component, final String[] attributeNames) {
    final Map attributes = component.getAttributes();
    for (int i = 0, len = attributeNames.length; i < len; i++) {
      final String attributeName = attributeNames[i];
      /*
       * don't use UIComponent#containsKey method.
       *
       * because when attributeName matches a property of this
       * UIComponent, containsKey returns false. See
       * UIComponent#getAttributes API document.
       */
      final Object value = attributes.get(attributeName);
      if (shouldRenderAttribute(attributeName, value)) {
        return true;
      }
    }
    return false;
  }

  public static boolean renderAttributes(
      final ResponseWriter writer, final UIComponent component, final String[] attributeNames)
      throws IOException {

    boolean somethingDone = false;
    for (int i = 0, len = attributeNames.length; i < len; i++) {
      final String attrName = attributeNames[i];
      if (renderAttribute(writer, component, attrName)) {
        somethingDone = true;
      }
    }
    return somethingDone;
  }

  static boolean renderAttribute(
      final ResponseWriter writer, final UIComponent component, final String attributeName)
      throws IOException {

    final Object value = component.getAttributes().get(attributeName);
    return renderAttribute(writer, attributeName, value, attributeName);
  }

  public static void renderAttribute(
      final ResponseWriter writer, final String attributeName, final Object value)
      throws IOException {
    renderAttribute(writer, attributeName, value, attributeName);
  }

  public static boolean renderAttribute(
      final ResponseWriter writer, String attributeName, Object value, final String propertyName)
      throws IOException {
    if (!shouldRenderAttribute(attributeName, value)) {
      return false;
    }
    attributeName = toHtmlAttributeName(attributeName);
    value = convertValue(attributeName, value);
    writer.writeAttribute(attributeName, value, propertyName);
    return true;
  }

  private static Object convertValue(final String attributeName, final Object value) {
    if (JsfConstants.CHECKED_ATTR.equals(attributeName)) {
      return JsfConstants.CHECKED_ATTR;
    } else if (JsfConstants.SELECTED_ATTR.equals(attributeName)) {
      return JsfConstants.SELECTED_ATTR;
    } else if (JsfConstants.DISABLED_ATTR.equals(attributeName)) {
      return JsfConstants.DISABLED_ATTR;
    } else if (JsfConstants.READONLY_ATTR.equals(attributeName)) {
      return JsfConstants.READONLY_ATTR;
    }
    return value;
  }

  private static String toHtmlAttributeName(final String attributeName) {
    if (attributeName.equalsIgnoreCase(JsfConstants.STYLE_CLASS_ATTR)) {
      return JsfConstants.CLASS_ATTR;
    } else if (attributeName.equalsIgnoreCase(JsfConstants.ACCEPTCHARSET_ATTR)) {
      return JsfConstants.ACCEPT_CHARSET_ATTR;
    } else {
      return attributeName;
    }
  }

  public static boolean shouldRenderAttribute(final String attributeName, final Object value) {
    if (isDefaultAttributeValue(value)) {
      return false;
    }
    if (JsfConstants.COLSPAN_ATTR.equals(attributeName)) {
      final Integer integerValue = IntegerConversionUtil.toInteger(value);
      if (integerValue == null) {
        return false;
      }
      if (integerValue.intValue() <= 1) {
        return false;
      }
    }
    if (JsfConstants.ESCAPE_ATTR.equals(attributeName)) {
      return false;
    }
    if (JsfConstants.ID_ATTR.equals(attributeName)) {
      return shouldRenderIdAttribute(value.toString());
    }
    return true;
  }

  static boolean isDefaultAttributeValue(final Object value) {
    if (value == null) {
      return true;
    }
    if (value instanceof Boolean) {
      return UIDefaultAttribute.isDefaultBoolean(((Boolean) value).booleanValue());
    }
    if (value instanceof Integer) {
      return UIDefaultAttribute.isDefaultInt(((Integer) value).intValue());
    }
    return false;
  }

  public static boolean shouldRenderIdAttribute(final UIComponent component) {
    return shouldRenderIdAttribute(component.getId());
  }

  private static boolean shouldRenderIdAttribute(final String id) {
    if ((id != null) && !id.startsWith(UIViewRoot.UNIQUE_ID_PREFIX)) {
      return true;
    }
    return false;
  }

  public static void renderIdAttributeIfNecessary(
      final ResponseWriter writer, final UIComponent component, final String idValue)
      throws IOException {
    if (RendererUtil.shouldRenderIdAttribute(component)) {
      RendererUtil.renderAttribute(writer, JsfConstants.ID_ATTR, idValue);
    }
  }

  public static Object getConvertedValue(
      final FacesContext context, final UIInput component, final Object submittedValue) {
    try {
      final Renderer renderer = getRenderer(context, component);
      if (renderer != null) {
        return renderer.getConvertedValue(context, component, submittedValue);
      } else if (submittedValue instanceof String) {
        return getConvertedUIOutputValue(context, component, submittedValue);
      }
    } catch (final ConverterException e) {
      final FacesMessage facesMessage = e.getFacesMessage();
      if (facesMessage != null) {
        context.addMessage(component.getClientId(context), facesMessage);
      } else {
        final Object[] args = new Object[] {UIComponentUtil.getLabel(component)};
        context.addMessage(
            component.getClientId(context),
            FacesMessageUtil.getMessage(context, UIInput.CONVERSION_MESSAGE_ID, args));
      }
      component.setValid(false);
    }
    return submittedValue;
  }

  static Renderer getRenderer(final FacesContext context, final UIComponent component) {
    final String rendererType = component.getRendererType();
    if (rendererType == null) {
      return null;
    }
    final RenderKit renderKit = RenderKitUtil.getRenderKit(context);
    return renderKit.getRenderer(component.getFamily(), rendererType);
  }

  public static Object getConvertedUIOutputValue(
      final FacesContext context, final UIOutput output, final Object submittedValue)
      throws ConverterException {
    if (submittedValue == null) {
      return null;
    }
    final Converter converter = findConverter(context, output);
    if (converter == null) {
      return submittedValue;
    }
    return converter.getAsObject(
        context, output, (submittedValue instanceof String) ? (String) submittedValue : null);
  }

  public static Object getConvertedUIOutputValues(
      final FacesContext context, final UIOutput output, final Object submittedValue) {
    if (submittedValue == null) {
      return null;
    }
    final Converter converter = findConverter(context, output);
    if (converter == null) {
      return submittedValue;
    }
    final int length = Array.getLength(submittedValue);
    final Class valueType = getValueType(context, output);
    final Object ret = Array.newInstance(valueType, length);
    for (int i = 0; i < length; ++i) {
      final Object target = Array.get(submittedValue, i);
      final String value = (target instanceof String) ? (String) target : null;
      final Object o = converter.getAsObject(context, output, value);
      ArrayUtil.setArrayValue(ret, valueType, o, i);
    }
    return ret;
  }

  public static Converter findConverter(final FacesContext context, final UIOutput component) {

    Converter converter = component.getConverter();
    if (converter != null) {
      return converter;
    }
    ValueBinding vb = component.getValueBinding("value");
    if (vb != null) {
      String expression = vb.getExpressionString();
      converter = ConverterResource.getConverter(expression);
      if (converter != null) {
        return converter;
      }
    }
    final Class valueType = getValueType(context, component);
    if (ComponentUtil_.isPerformNoConversion(valueType)) {
      return null;
    }
    try {
      return context.getApplication().createConverter(valueType);
    } catch (final FacesException ex) {
      logger.log(ex);
      return null;
    }
  }

  static Class getValueType(final FacesContext context, final UIOutput component) {
    final ValueBinding vb = component.getValueBinding("value");
    if (vb == null) {
      return null;
    }
    final Class valueType = vb.getType(context);
    if (valueType == null) {
      return null;
    }
    if (valueType.isArray()) {
      return valueType.getComponentType();
    } else {
      return valueType;
    }
  }

  public static void renderChild(FacesContext context, UIComponent child) throws IOException {
    AssertionUtil.assertNotNull("context", context);
    AssertionUtil.assertNotNull("child", child);
    if (!child.isRendered()) {
      return;
    }
    child.encodeBegin(context);
    if (child.getRendersChildren()) {
      child.encodeChildren(context);
    } else {
      renderChildren(context, child);
    }
    child.encodeEnd(context);
  }

  public static void renderChildren(FacesContext context, UIComponent component)
      throws IOException {
    AssertionUtil.assertNotNull("context", context);
    AssertionUtil.assertNotNull("child", component);
    if (component.getChildCount() > 0) {
      for (Iterator it = component.getChildren().iterator(); it.hasNext(); ) {
        UIComponent child = (UIComponent) it.next();
        renderChild(context, child);
      }
    }
  }

  public static void renderHidden(
      UIComponent component, ResponseWriter writer, String name, Object value) throws IOException {
    writer.startElement(JsfConstants.INPUT_ELEM, component);
    RendererUtil.renderAttribute(writer, JsfConstants.TYPE_ATTR, JsfConstants.HIDDEN_VALUE);
    RendererUtil.renderAttribute(writer, JsfConstants.NAME_ATTR, name);
    RendererUtil.renderAttribute(writer, JsfConstants.VALUE_ATTR, value);
    writer.endElement(JsfConstants.INPUT_ELEM);
  }
}
Exemple #28
0
/**
 * {@link S2Container}の実装クラスです。
 *
 * @author higa
 */
public class S2ContainerImpl implements S2Container, ContainerConstants {

  private static final Logger logger = Logger.getLogger(S2ContainerImpl.class);

  private Map componentDefMap = new HashMap();

  private List componentDefList = new ArrayList();

  private String namespace;

  private String path;

  private boolean initializeOnCreate;

  private List children = new ArrayList();

  private Map childPositions = new HashMap();

  private List parents = new ArrayList();

  private CaseInsensitiveMap descendants = new CaseInsensitiveMap();

  private S2Container root;

  private ExternalContext externalContext;

  private ExternalContextComponentDefRegister externalContextComponentDefRegister;

  private MetaDefSupport metaDefSupport = new MetaDefSupport(this);

  private boolean inited = false;

  private ClassLoader classLoader = null;

  static {
    OgnlRuntime.setPropertyAccessor(S2Container.class, new S2ContainerPropertyAccessor());
    Desc.useContextClassLoader = true;
    ProxyFactory.classLoaderProvider =
        new ClassLoaderProvider() {
          public ClassLoader get(ProxyFactory proxyFactory) {
            return Thread.currentThread().getContextClassLoader();
          }
        };
  }

  /** {@link S2ContainerImpl}を作成します。 */
  public S2ContainerImpl() {
    root = this;
    register0(new SimpleComponentDef(this, CONTAINER_NAME));
    classLoader = Thread.currentThread().getContextClassLoader();
  }

  public S2Container getRoot() {
    return root;
  }

  public void setRoot(S2Container root) {
    this.root = root != null ? root : this;
  }

  /** @see org.seasar.framework.container.S2Container#getComponent(java.lang.Object) */
  public Object getComponent(Object componentKey) {
    assertParameterIsNotNull(componentKey, "componentKey");
    ComponentDef cd = S2ContainerBehavior.acquireFromGetComponent(this, componentKey);
    if (cd == null) {
      return null;
    }
    return cd.getComponent();
  }

  /** @see org.seasar.framework.container.S2Container#getComponent(java.lang.Object) */
  public Object[] findComponents(Object componentKey) {
    assertParameterIsNotNull(componentKey, "componentKey");
    ComponentDef[] componentDefs = findComponentDefs(componentKey);
    return toComponentArray(componentKey, componentDefs);
  }

  /*
   * (non-Javadoc)
   *
   * @see org.seasar.framework.container.S2Container#findAllComponents(java.lang.Object)
   */
  public Object[] findAllComponents(Object componentKey) throws CyclicReferenceRuntimeException {
    assertParameterIsNotNull(componentKey, "componentKey");
    ComponentDef[] componentDefs = findAllComponentDefs(componentKey);
    return toComponentArray(componentKey, componentDefs);
  }

  /** @see org.seasar.framework.container.S2Container#findLocalComponents(java.lang.Object) */
  public Object[] findLocalComponents(Object componentKey) throws CyclicReferenceRuntimeException {
    assertParameterIsNotNull(componentKey, "componentKey");
    ComponentDef[] componentDefs = findLocalComponentDefs(componentKey);
    return toComponentArray(componentKey, componentDefs);
  }

  /**
   * コンポーネントの配列に変換します。
   *
   * @param componentKey
   * @param componentDefs
   * @return コンポーネントの配列
   */
  protected Object[] toComponentArray(Object componentKey, ComponentDef[] componentDefs) {
    int length = componentDefs.length;
    Object[] components =
        (componentKey instanceof Class)
            ? (Object[]) Array.newInstance((Class) componentKey, length)
            : new Object[length];
    for (int i = 0; i < length; ++i) {
      components[i] = componentDefs[i].getComponent();
    }
    return components;
  }

  /** @see org.seasar.framework.container.S2Container#injectDependency(java.lang.Object) */
  public void injectDependency(Object outerComponent) {
    injectDependency(outerComponent, outerComponent.getClass());
  }

  /**
   * @see org.seasar.framework.container.S2Container#injectDependency(java.lang.Object,
   *     java.lang.Class)
   */
  public void injectDependency(Object outerComponent, Class componentClass) {
    assertParameterIsNotNull(outerComponent, "outerComponent");
    assertParameterIsNotNull(componentClass, "componentClass");
    ComponentDef cd = S2ContainerBehavior.acquireFromInjectDependency(this, componentClass);
    if (cd != null) {
      cd.injectDependency(outerComponent);
    }
  }

  /**
   * @see org.seasar.framework.container.S2Container#injectDependency(java.lang.Object,
   *     java.lang.String)
   */
  public void injectDependency(Object outerComponent, String componentName) {
    assertParameterIsNotNull(outerComponent, "outerComponent");
    assertParameterIsNotEmpty(componentName, "componentName");
    ComponentDef cd = S2ContainerBehavior.acquireFromInjectDependency(this, componentName);
    if (cd != null) {
      cd.injectDependency(outerComponent);
    }
  }

  /** @see org.seasar.framework.container.S2Container#register(java.lang.Object) */
  public void register(Object component) {
    assertParameterIsNotNull(component, "component");
    register(new SimpleComponentDef(component));
  }

  public void register(Object component, String componentName) {
    assertParameterIsNotNull(component, "component");
    assertParameterIsNotEmpty(componentName, "componentName");
    register(new SimpleComponentDef(component, componentName));
  }

  /** @see org.seasar.framework.container.S2Container#register(java.lang.Class) */
  public void register(Class componentClass) {
    assertParameterIsNotNull(componentClass, "componentClass");
    register(new ComponentDefImpl(componentClass));
  }

  /** @see org.seasar.framework.container.S2Container#register(java.lang.Class, java.lang.String) */
  public void register(Class componentClass, String componentName) {
    assertParameterIsNotNull(componentClass, "componentClass");
    assertParameterIsNotEmpty(componentName, "componentName");
    register(new ComponentDefImpl(componentClass, componentName));
  }

  /**
   * @see
   *     org.seasar.framework.container.S2Container#register(org.seasar.framework.container.ComponentDef)
   */
  public void register(ComponentDef componentDef) {
    assertParameterIsNotNull(componentDef, "componentDef");
    register0(componentDef);
    componentDefList.add(componentDef);
  }

  /**
   * {@link ComponentDef}を登録します。
   *
   * @param componentDef
   */
  public void register0(ComponentDef componentDef) {
    if (componentDef.getContainer() == null) {
      componentDef.setContainer(this);
    }
    registerByClass(componentDef);
    registerByName(componentDef);
  }

  /**
   * {@link Class}をキーにして {@link ComponentDef}を登録します。
   *
   * @param componentDef
   */
  protected void registerByClass(ComponentDef componentDef) {
    Class[] classes = S2ContainerUtil.getAssignableClasses(componentDef.getComponentClass());
    for (int i = 0; i < classes.length; ++i) {
      registerMap(classes[i], componentDef);
    }
  }

  /**
   * 名前をキーにして {@link ComponentDef}を登録します。
   *
   * @param componentDef
   */
  protected void registerByName(ComponentDef componentDef) {
    String componentName = componentDef.getComponentName();
    if (componentName != null) {
      registerMap(componentName, componentDef);
    }
  }

  /**
   * キャッシュに {@link ComponentDef}を登録します。
   *
   * @param key
   * @param componentDef
   */
  protected void registerMap(Object key, ComponentDef componentDef) {
    registerMap(key, componentDef, this);
  }

  public void registerMap(Object key, ComponentDef componentDef, S2Container container) {
    int position = getContainerPosition(container);
    ComponentDefHolder holder = (ComponentDefHolder) componentDefMap.get(key);
    if (holder == null) {
      holder = new ComponentDefHolder(position, componentDef);
      componentDefMap.put(key, holder);
    } else if (position > holder.getPosition()) {
      return;
    } else if (position < holder.getPosition()) {
      holder.setPosition(position);
      holder.setComponentDef(componentDef);
    } else if (container != this) {
      holder.setComponentDef(componentDef);
    } else {
      holder.setComponentDef(
          createTooManyRegistration(key, holder.getComponentDef(), componentDef));
    }

    registerParent(key, holder.getComponentDef());
  }

  /**
   * {@link S2Container}のネストが深くなってもパフォーマンスが落ちないように親に {@link ComponentDef}を登録します。
   *
   * @param key
   * @param componentDef
   */
  protected void registerParent(Object key, ComponentDef componentDef) {
    for (int i = 0; i < getParentSize(); i++) {
      S2Container parent = (S2Container) getParent(i);
      parent.registerMap(key, componentDef, this);
      if (isNeedNS(key, componentDef)) {
        parent.registerMap(namespace + NS_SEP + key, componentDef, this);
      }
    }
  }

  /** @see org.seasar.framework.container.S2Container#getComponentDefSize() */
  public int getComponentDefSize() {
    return componentDefList.size();
  }

  /** @see org.seasar.framework.container.S2Container#getComponentDef(int) */
  public ComponentDef getComponentDef(int index) {
    return (ComponentDef) componentDefList.get(index);
  }

  /** @see org.seasar.framework.container.S2Container#getComponentDef(java.lang.Object) */
  public ComponentDef getComponentDef(Object key) throws ComponentNotFoundRuntimeException {
    assertParameterIsNotNull(key, "key");
    return S2ContainerBehavior.acquireFromGetComponentDef(this, key);
  }

  /** @see org.seasar.framework.container.S2Container#findComponentDefs(java.lang.Object) */
  public ComponentDef[] findComponentDefs(Object key) throws ComponentNotFoundRuntimeException {
    assertParameterIsNotNull(key, "key");
    ComponentDef cd = internalGetComponentDef(key);
    return toComponentDefArray(cd);
  }

  /** @see org.seasar.framework.container.S2Container#findAllComponentDefs(java.lang.Object) */
  public ComponentDef[] findAllComponentDefs(final Object componentKey) {
    assertParameterIsNotNull(componentKey, "componentKey");
    final List componentDefs = new ArrayList();
    Traversal.forEachContainer(
        this,
        new Traversal.S2ContainerHandler() {
          public Object processContainer(S2Container container) {
            componentDefs.addAll(Arrays.asList(container.findLocalComponentDefs(componentKey)));
            return null;
          }
        });
    return (ComponentDef[]) componentDefs.toArray(new ComponentDef[componentDefs.size()]);
  }

  /** @see org.seasar.framework.container.S2Container#findLocalComponentDefs(java.lang.Object) */
  public ComponentDef[] findLocalComponentDefs(Object componentKey) {
    ComponentDefHolder holder = (ComponentDefHolder) componentDefMap.get(componentKey);
    if (holder == null || holder.getPosition() > 0) {
      return new ComponentDef[0];
    }
    return toComponentDefArray(holder.getComponentDef());
  }

  /**
   * {@link ComponentDef}の配列に変換します。
   *
   * @param cd
   * @return {@link ComponentDef}の配列
   */
  protected ComponentDef[] toComponentDefArray(ComponentDef cd) {
    if (cd == null) {
      return new ComponentDef[0];
    } else if (cd instanceof TooManyRegistrationComponentDefImpl) {
      return ((TooManyRegistrationComponentDefImpl) cd).getComponentDefs();
    }
    return new ComponentDef[] {cd};
  }

  /**
   * 内部的なgetComponentDefの実装です。
   *
   * @param key
   * @return {@link ComponentDef}
   */
  protected ComponentDef internalGetComponentDef(Object key) {
    ComponentDefHolder holder = (ComponentDefHolder) componentDefMap.get(key);
    if (holder != null) {
      return holder.getComponentDef();
    }
    if (key instanceof String) {
      String name = (String) key;
      int index = name.indexOf(NS_SEP);
      if (index > 0) {
        String ns = name.substring(0, index);
        name = name.substring(index + 1);
        if (ns.equals(namespace)) {
          return internalGetComponentDef(name);
        }
      }
    }
    return null;
  }

  /** @see org.seasar.framework.container.S2Container#hasComponentDef(java.lang.Object) */
  public boolean hasComponentDef(Object componentKey) {
    assertParameterIsNotNull(componentKey, "componentKey");
    return S2ContainerBehavior.acquireFromHasComponentDef(this, componentKey) != null;
  }

  /** @see org.seasar.framework.container.S2Container#hasDescendant(java.lang.String) */
  public boolean hasDescendant(String path) {
    assertParameterIsNotEmpty(path, "path");
    return descendants.containsKey(path);
  }

  public S2Container getDescendant(String path) {
    S2Container descendant = (S2Container) descendants.get(path);
    if (descendant != null) {
      return descendant;
    }
    throw new ContainerNotRegisteredRuntimeException(path);
  }

  public void registerDescendant(S2Container descendant) {
    assertParameterIsNotNull(descendant, "descendant");
    descendants.put(descendant.getPath(), descendant);
  }

  /**
   * @see
   *     org.seasar.framework.container.S2Container#include(org.seasar.framework.container.S2Container)
   */
  public void include(S2Container child) {
    assertParameterIsNotNull(child, "child");
    children.add(child);
    childPositions.put(child, new Integer(children.size()));
    child.setRoot(getRoot());
    child.addParent(this);
  }

  /**
   * 子供の位置を返します。
   *
   * @param container
   * @return 子供の位置
   */
  protected int getContainerPosition(S2Container container) {
    if (container == this) {
      return 0;
    }
    return ((Integer) childPositions.get(container)).intValue();
  }

  /**
   * 名前空間が必要かどうかを返します。
   *
   * @param key
   * @param cd
   * @return 名前空間が必要かどうか
   */
  protected boolean isNeedNS(Object key, ComponentDef cd) {
    return key instanceof String && namespace != null;
  }

  public int getChildSize() {
    return children.size();
  }

  public S2Container getChild(int index) {
    return (S2Container) children.get(index);
  }

  public int getParentSize() {
    return parents.size();
  }

  public S2Container getParent(int index) {
    return (S2Container) parents.get(index);
  }

  public void addParent(S2Container parent) {
    parents.add(parent);
    for (Iterator it = componentDefMap.entrySet().iterator(); it.hasNext(); ) {
      Entry entry = (Entry) it.next();
      Object key = entry.getKey();
      ComponentDefHolder holder = (ComponentDefHolder) entry.getValue();
      ComponentDef cd = holder.getComponentDef();
      parent.registerMap(key, cd, this);
      if (isNeedNS(key, cd)) {
        parent.registerMap(namespace + NS_SEP + key, cd, this);
      }
    }
  }

  public void init() {
    if (inited) {
      return;
    }
    final ExternalContextComponentDefRegister register =
        getRoot().getExternalContextComponentDefRegister();
    if (register != null) {
      register.registerComponentDefs(this);
    }
    final ClassLoader currentLoader = Thread.currentThread().getContextClassLoader();
    Thread.currentThread().setContextClassLoader(classLoader);
    try {
      for (int i = 0; i < getChildSize(); ++i) {
        getChild(i).init();
      }
      for (int i = 0; i < getComponentDefSize(); ++i) {
        getComponentDef(i).init();
      }
      inited = true;
    } finally {
      Thread.currentThread().setContextClassLoader(currentLoader);
    }
  }

  public void destroy() {
    if (!inited) {
      return;
    }
    final ClassLoader currentLoader = Thread.currentThread().getContextClassLoader();
    Thread.currentThread().setContextClassLoader(classLoader);
    try {
      for (int i = getComponentDefSize() - 1; 0 <= i; --i) {
        try {
          getComponentDef(i).destroy();
        } catch (Throwable t) {
          logger.error("ESSR0017", t);
        }
      }
      for (int i = getChildSize() - 1; 0 <= i; --i) {
        getChild(i).destroy();
      }

      componentDefMap = null;
      componentDefList = null;
      namespace = null;
      path = null;
      children = null;
      childPositions = null;
      parents = null;
      descendants = null;
      externalContext = null;
      externalContextComponentDefRegister = null;
      metaDefSupport = null;
      classLoader = null;
      root = this;
      inited = false;
    } finally {
      Thread.currentThread().setContextClassLoader(currentLoader);
    }
  }

  public String getNamespace() {
    return namespace;
  }

  public void setNamespace(String namespace) {
    componentDefMap.remove(namespace);
    this.namespace = namespace;
    registerMap(namespace, new S2ContainerComponentDef(this, namespace));
  }

  public boolean isInitializeOnCreate() {
    return initializeOnCreate;
  }

  public void setInitializeOnCreate(boolean initializeOnCreate) {
    this.initializeOnCreate = initializeOnCreate;
  }

  public String getPath() {
    return path;
  }

  public void setPath(String path) {
    this.path = path;
  }

  public ExternalContext getExternalContext() {
    return externalContext;
  }

  public void setExternalContext(ExternalContext externalContext) {
    this.externalContext = externalContext;
  }

  public ExternalContextComponentDefRegister getExternalContextComponentDefRegister() {
    return externalContextComponentDefRegister;
  }

  public void setExternalContextComponentDefRegister(ExternalContextComponentDefRegister register) {
    this.externalContextComponentDefRegister = register;
  }

  public void addMetaDef(MetaDef metaDef) {
    metaDefSupport.addMetaDef(metaDef);
  }

  public MetaDef getMetaDef(int index) {
    return metaDefSupport.getMetaDef(index);
  }

  public MetaDef getMetaDef(String name) {
    return metaDefSupport.getMetaDef(name);
  }

  public MetaDef[] getMetaDefs(String name) {
    return metaDefSupport.getMetaDefs(name);
  }

  public int getMetaDefSize() {
    return metaDefSupport.getMetaDefSize();
  }

  public ClassLoader getClassLoader() {
    return classLoader;
  }

  public void setClassLoader(ClassLoader classLoader) {
    this.classLoader = classLoader;
  }

  /**
   * {@link TooManyRegistrationComponentDef}を作成します。
   *
   * @param key
   * @param currentComponentDef
   * @param newComponentDef
   * @return {@link TooManyRegistrationComponentDef}
   */
  public static ComponentDef createTooManyRegistration(
      Object key, ComponentDef currentComponentDef, ComponentDef newComponentDef) {

    if (currentComponentDef instanceof TooManyRegistrationComponentDef) {
      ((TooManyRegistrationComponentDef) currentComponentDef).addComponentDef(newComponentDef);
      return currentComponentDef;
    } else {
      TooManyRegistrationComponentDef tmrcf = new TooManyRegistrationComponentDefImpl(key);
      tmrcf.addComponentDef(currentComponentDef);
      tmrcf.addComponentDef(newComponentDef);
      return tmrcf;
    }
  }

  /**
   * パラメータが<code>null</code>でないことを表明します。
   *
   * @param parameter
   * @param name
   */
  protected void assertParameterIsNotNull(Object parameter, String name) {
    if (parameter == null) {
      throw new IllegalArgumentException(name);
    }
  }

  /**
   * パラメータが空でないことを表明します。
   *
   * @param parameter
   * @param name
   */
  protected void assertParameterIsNotEmpty(String parameter, String name) {
    if (StringUtil.isEmpty(parameter)) {
      throw new IllegalArgumentException(name);
    }
  }

  /** 子供の位置を保持するクラスです。 */
  static class ComponentDefHolder {
    private int position;

    private ComponentDef componentDef;

    /**
     * {@link ComponentDefHolder}を作成します。
     *
     * @param position
     * @param componentDef
     */
    public ComponentDefHolder(int position, ComponentDef componentDef) {
      this.position = position;
      this.componentDef = componentDef;
    }

    /**
     * 位置を返します。
     *
     * @return 位置
     */
    public int getPosition() {
      return position;
    }

    /**
     * 位置を設定します。
     *
     * @param position
     */
    public void setPosition(int position) {
      this.position = position;
    }

    /**
     * {@link ComponentDef}を返します。
     *
     * @return {@link ComponentDef}
     */
    public ComponentDef getComponentDef() {
      return componentDef;
    }

    /**
     * {@link ComponentDef}を設定します。
     *
     * @param componentDef
     */
    public void setComponentDef(ComponentDef componentDef) {
      this.componentDef = componentDef;
    }
  }
}
/**
 * コンポーネントアセンブラの抽象クラスです。
 *
 * @author higa
 */
public abstract class AbstractAssembler {

  private static Logger logger = Logger.getLogger(AbstractAssembler.class);

  private ComponentDef componentDef;

  /**
   * {@link AbstractAssembler}のコンストラクタです。
   *
   * @param componentDef
   */
  public AbstractAssembler(ComponentDef componentDef) {
    this.componentDef = componentDef;
  }

  /**
   * {@link ComponentDef}を返します。
   *
   * @return {@link ComponentDef}
   */
  protected final ComponentDef getComponentDef() {
    return componentDef;
  }

  /**
   * {@link BeanDesc}を返します。
   *
   * @param component
   * @return {@link BeanDesc}
   * @see BindingUtil#getBeanDesc(ComponentDef, Object)
   */
  protected BeanDesc getBeanDesc(Object component) {
    return BindingUtil.getBeanDesc(getComponentDef(), component);
  }

  /**
   * コンポーネントのクラスを返します。
   *
   * @param component
   * @return コンポーネントのクラス
   * @see BindingUtil#getComponentClass(ComponentDef, Object)
   */
  protected Class getComponentClass(Object component) {
    return BindingUtil.getComponentClass(getComponentDef(), component);
  }

  /**
   * 引数を返します。
   *
   * @param argTypes
   * @return 引数
   */
  protected Object[] getArgs(Class[] argTypes) {
    Object[] args = new Object[argTypes.length];
    for (int i = 0; i < argTypes.length; ++i) {
      try {
        args[i] = getComponentDef().getContainer().getComponent(argTypes[i]);
      } catch (ComponentNotFoundRuntimeException ex) {
        logger.log(
            "WSSR0007",
            new Object[] {getComponentDef().getComponentClass().getName(), ex.getComponentKey()});
        args[i] = null;
      }
    }
    return args;
  }
}