/* * Copyright 2008-2010 the T2 Project ant the Others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.t2framework.confeito.method.impl; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.Map; import java.util.Map.Entry; import java.util.regex.Pattern; import org.t2framework.confeito.action.ActionContext; import org.t2framework.confeito.annotation.ActionParam; import org.t2framework.confeito.contexts.Request; import org.t2framework.confeito.internal.ActionUtil; import org.t2framework.confeito.internal.VariablesUtil; import org.t2framework.confeito.method.AbstractActionMethodResolver; import org.t2framework.confeito.util.StringUtil; /** * * <#if locale="en"> * <p> * ActionParamResolver is a concrete class of ActionMethodResolver. This class * handles @ActionParam. * </p> * <#else> * <p> * {@code ActionParamResolver} は@ActionParamを処理するリゾルバです. * </p> * </#if> * * @author shot * @see org.t2framework.confeito.method.ActionMethodResolver * */ public class ActionParamResolver extends AbstractActionMethodResolver { /** * <#if locale="en"> * <p> * True if request parameter contains template key.Ajax request never * reaches true. * </p> * <#else> * <p> * リクエストパラメータがテンプレートのキーを持つかチェックします.例外的にAjaxリクエスト( * {@link ActionUtil#isAjaxRequest(ActionContext, MethodDesc)} * にマッチするリクエスト)は取り扱いません. * </p> * </#if> */ @Override public boolean isMatch(final ActionContext actionContext, final Annotation annotation, final Method targetMethodDesc) { if (ActionUtil.isAjaxRequest(actionContext, targetMethodDesc)) { return false; } final String pair = getKeyValuePair(annotation, targetMethodDesc); final String keyPart = getKeyPart(pair); final String valuePart = getValuePart(pair); final Pattern keyPattern = VariablesUtil.toPattern(keyPart); final Pattern valuePattern = (valuePart == null) ? null : VariablesUtil .toPattern(valuePart); final Request request = actionContext.getRequest(); for (String paramKey : request.getParameterNames()) { if (keyPattern.matcher(paramKey).matches() == false) { continue; } String[] values = request.getParameters(paramKey); if (valuePattern != null) { for (int i = 0; i < values.length; i++) { if (valuePattern.matcher(values[i]).matches()) { return true; } } } else { return true; } } return false; } /** * <#if locale="en"> * <p> * Resolve action method by request parameter. * </p> * <#else> * <p> * POSTされたリクエストパラメータとアノテーションで指定されたテンプレートとマッチングを行い、マッチした場合このテンプレートの情報を保管し、 * アクションメソッドの呼び出しに備えます. * * </p> * </#if> */ @Override public void resolve(ActionContext actionContext, Annotation annotation, Method targetMethodDesc) { final String keyValuePair = getKeyValuePair(annotation, targetMethodDesc); final String keyPart = getKeyPart(keyValuePair); final String valuePart = getValuePart(keyValuePair); resolveActionParameters(actionContext, keyPart, valuePart); } protected void resolveActionParameters(ActionContext actionContext, String keyPart, String valuePart) { final Request request = actionContext.getRequest(); final Pattern keyPattern = VariablesUtil.toPattern(keyPart); final Pattern valuePattern = (valuePart == null) ? null : VariablesUtil .toPattern(valuePart); for (String paramKey : request.getParameterNames()) { if (keyPattern.matcher(paramKey).matches() == false) { continue; } String[] values = request.getParameters(paramKey); appendRequestParameterVariables(actionContext, paramKey, keyPart, valuePart, valuePattern, values); } } protected void appendRequestParameterVariables(ActionContext actionContext, String paramKey, String keyPart, String valuePart, Pattern valuePattern, String[] values) { if (valuePattern != null) { for (int i = 0; i < values.length; i++) { final String s = values[i]; if (valuePattern.matcher(s).matches()) { final Map<String, String> keyVariables = VariablesUtil .createVarMap(keyPart, paramKey); appendVariables(actionContext, keyVariables); final Map<String, String> valueVariables = VariablesUtil .createVarMap(valuePart, s); appendVariables(actionContext, valueVariables); return; } } } else { final Map<String, String> keyVariables = VariablesUtil .createVarMap(keyPart, paramKey); appendVariables(actionContext, keyVariables); } } protected String getKeyValuePair(Annotation annotation, Method targetMethodDesc) { final ActionParam actionParam = (ActionParam) annotation; final String pair = actionParam.value(); return (StringUtil.isEmpty(pair) == false) ? pair : targetMethodDesc .getName(); } protected String getKeyPart(String value) { int eq = value.indexOf("="); if (eq != -1) { value = value.substring(0, eq); } return value.trim(); } protected String getValuePart(String value) { int eq = value.indexOf("="); if (eq != -1) { return value.substring(eq + 1).trim(); } else { return null; } } protected void appendVariables(ActionContext actionContext, Map<String, String> varMap) { for (Entry<String, String> entrySet : varMap.entrySet()) { actionContext.addVariables(entrySet.getKey(), entrySet.getValue()); } } }