Coverage Report - org.seasar.cubby.tags.TagUtils
 
Classes in this File Line Coverage Branch Coverage Complexity
TagUtils
96%
78/81
91%
42/46
0
 
 1  
 /*
 2  
  * Copyright 2004-2008 the Seasar Foundation and the Others.
 3  
  *
 4  
  * Licensed under the Apache License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  *     http://www.apache.org/licenses/LICENSE-2.0
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 13  
  * either express or implied. See the License for the specific language
 14  
  * governing permissions and limitations under the License.
 15  
  */
 16  
 package org.seasar.cubby.tags;
 17  
 
 18  
 import static java.lang.Boolean.TRUE;
 19  
 import static javax.servlet.jsp.PageContext.REQUEST_SCOPE;
 20  
 import static org.seasar.cubby.CubbyConstants.ATTR_PARAMS;
 21  
 import static org.seasar.cubby.CubbyConstants.ATTR_VALIDATION_FAIL;
 22  
 
 23  
 import java.util.Collection;
 24  
 import java.util.Map;
 25  
 import java.util.Map.Entry;
 26  
 
 27  
 import javax.servlet.jsp.JspContext;
 28  
 import javax.servlet.jsp.tagext.SimpleTag;
 29  
 import javax.servlet.jsp.tagext.SimpleTagSupport;
 30  
 
 31  
 import org.seasar.cubby.CubbyConstants;
 32  
 import org.seasar.cubby.action.ActionErrors;
 33  
 import org.seasar.cubby.util.CubbyUtils;
 34  
 import org.seasar.framework.util.StringUtil;
 35  
 
 36  
 /**
 37  
  * カスタムタグで使用するユーティリティクラスです。
 38  
  * 
 39  
  * @author baba
 40  
  * @since 1.0.0
 41  
  */
 42  1
 class TagUtils {
 43  
 
 44  
         /** リクエストスコープから{@link ActionErrors}を取得するためのキー。 */
 45  
         private static final String ATTR_ERRORS = "errors";
 46  
 
 47  
         /**
 48  
          * 指定されたJSPコンテキストから{@link ActionErrors}を取得します。
 49  
          * 
 50  
          * @param context
 51  
          *            JSPコンテキスト
 52  
          * @return アクションで発生したエラー
 53  
          */
 54  
         public static ActionErrors errors(final JspContext context) {
 55  37
                 return (ActionErrors) context.getAttribute(ATTR_ERRORS, REQUEST_SCOPE);
 56  
         }
 57  
 
 58  
         /**
 59  
          * 指定されたJSPコンテキストから指定されたパラメータ名に対応するリクエストパラメータを取得します。
 60  
          * 
 61  
          * @param context
 62  
          *            JSPコンテキスト
 63  
          * @param name
 64  
          *            パラメータ名
 65  
          * @return リクエストパラメータ
 66  
          */
 67  
         @SuppressWarnings("unchecked")
 68  
         private static Object[] paramValues(final JspContext context,
 69  
                         final String name) {
 70  13
                 final Map<String, Object[]> valuesMap = Map.class.cast(context
 71  
                                 .getAttribute(ATTR_PARAMS, REQUEST_SCOPE));
 72  
                 final Object[] values;
 73  13
                 if (valuesMap == null || !valuesMap.containsKey(name)) {
 74  5
                         values = new Object[0];
 75  
                 } else {
 76  8
                         values = valuesMap.get(name);
 77  
                 }
 78  13
                 return values;
 79  
         }
 80  
 
 81  
         /**
 82  
          * 指定されたフィールド名に対応するフォームのフィールドへの出力値を取得します。
 83  
          * 
 84  
          * @param context
 85  
          *            JSPコンテキスト
 86  
          * @param outputValues
 87  
          *            フォームへ出力する値
 88  
          * @param name
 89  
          *            フィールド名
 90  
          * @return フォームのフィールドへの出力値
 91  
          */
 92  
         public static Object[] multipleFormValues(final JspContext context,
 93  
                         final String[] outputValues, final String name) {
 94  17
                 return multipleFormValues(context, outputValues, name, null);
 95  
         }
 96  
 
 97  
         /**
 98  
          * 指定されたフィールド名に対応するフォームのフィールドへの出力値を取得します。
 99  
          * 
 100  
          * @param context
 101  
          *            JSPコンテキスト
 102  
          * @param outputValues
 103  
          *            フォームへ出力する値
 104  
          * @param name
 105  
          *            フィールド名
 106  
          * @param checkedValue
 107  
          *            チェック済みにする値
 108  
          * @return フォームのフィールドへの出力値
 109  
          */
 110  
         public static Object[] multipleFormValues(final JspContext context,
 111  
                         final String[] outputValues, final String name,
 112  
                         final String checkedValue) {
 113  
                 final Object[] values;
 114  32
                 if (isValidationFail(context)) {
 115  5
                         values = paramValues(context, name);
 116  
                 } else {
 117  27
                         if (checkedValue != null) {
 118  3
                                 values = new Object[] { checkedValue };
 119  24
                         } else if (outputValues == null) {
 120  2
                                 values = paramValues(context, name);
 121  
                         } else {
 122  22
                                 values = outputValues;
 123  
                         }
 124  
                 }
 125  32
                 return values;
 126  
         }
 127  
 
 128  
         /**
 129  
          * 指定されたフィールド名に対応するフォームのフィールドへの出力値を取得します。
 130  
          * 
 131  
          * @param context
 132  
          *            JSPコンテキスト
 133  
          * @param outputValuesMap
 134  
          *            フォームへ出力する値
 135  
          * @param name
 136  
          *            フィールド名
 137  
          * @param index
 138  
          *            インデックス
 139  
          * @param specifiedValue
 140  
          *            エラーがない場合に設定する値
 141  
          * @return フォームのフィールドへの出力値
 142  
          */
 143  
         public static Object formValue(final JspContext context,
 144  
                         final String[] outputValues, final String name,
 145  
                         final Integer index, final Object specifiedValue) {
 146  
                 final Object value;
 147  
 
 148  19
                 if (isValidationFail(context)) {
 149  5
                         if (specifiedValue == null) {
 150  2
                                 final Object[] values = paramValues(context, name);
 151  2
                                 value = value(values, index);
 152  2
                         } else {
 153  3
                                 final Object[] values = paramValues(context, name);
 154  3
                                 if (values.length == 0) {
 155  1
                                         value = specifiedValue;
 156  
                                 } else {
 157  2
                                         value = value(values, index);
 158  
                                 }
 159  3
                         }
 160  
                 } else {
 161  14
                         if (specifiedValue != null) {
 162  5
                                 value = specifiedValue;
 163  9
                         } else if (outputValues == null) {
 164  1
                                 final Object[] values = paramValues(context, name);
 165  1
                                 value = value(values, index);
 166  1
                         } else {
 167  8
                                 value = value(outputValues, index);
 168  
                         }
 169  
                 }
 170  
 
 171  19
                 return value;
 172  
         }
 173  
 
 174  
         /**
 175  
          * オブジェクトの配列から指定されたインデックスの値を取得します。
 176  
          * <p>
 177  
          * values が <code>null</code> の場合や index が要素数を越えていた場合は空文字を返します。index が
 178  
          * <code>null</code> の場合は配列の最初の要素を返します。
 179  
          * </p>
 180  
          * 
 181  
          * @param values
 182  
          *            オブジェクトの配列
 183  
          * @param index
 184  
          *            インデックス
 185  
          * @return 指定されたインデックスの要素
 186  
          */
 187  
         private static Object value(final Object[] values, final Integer index) {
 188  
                 final Object value;
 189  13
                 if (values == null) {
 190  0
                         value = "";
 191  
                 } else {
 192  13
                         if (index == null) {
 193  8
                                 value = getElement(values, 0);
 194  
                         } else {
 195  5
                                 value = getElement(values, index);
 196  
                         }
 197  
                 }
 198  13
                 return value;
 199  
         }
 200  
 
 201  
         /**
 202  
          * オブジェクトの配列から指定されたインデックスの要素を取得します。
 203  
          * <p>
 204  
          * index が要素数を越えていた場合は空文字を返します。
 205  
          * </p>
 206  
          * 
 207  
          * @param values
 208  
          *            オブジェクトの配列
 209  
          * @param index
 210  
          *            インデックス
 211  
          * @return 指定されたインデックスの要素
 212  
          */
 213  
         private static Object getElement(final Object[] values, final Integer index) {
 214  
                 final Object value;
 215  13
                 if (values.length <= index) {
 216  4
                         value = "";
 217  
                 } else {
 218  9
                         value = values[index];
 219  
                 }
 220  13
                 return value;
 221  
         }
 222  
 
 223  
         /**
 224  
          * 指定されたJSPコンテキストのアクションが入力検証に失敗したかどうかを示します。
 225  
          * 
 226  
          * @param context
 227  
          *            JSPコンテキスト
 228  
          * @return アクションが入力検証に失敗した場合は <code>true</code>、そうでない場合は
 229  
          *         <code>false</code>
 230  
          * @see CubbyConstants#ATTR_VALIDATION_FAIL
 231  
          */
 232  
         private static boolean isValidationFail(final JspContext context) {
 233  51
                 return TRUE.equals(context.getAttribute(ATTR_VALIDATION_FAIL,
 234  
                                 REQUEST_SCOPE));
 235  
         }
 236  
 
 237  1
         public static final Object REMOVE_ATTRIBUTE = new Object();
 238  
 
 239  
         /**
 240  
          * 指定された {@link Map} を HTML タグの属性へ変換します。
 241  
          * <p>
 242  
          * map 中の値が {@link #REMOVE_ATTRIBUTE} の場合、その属性は結果から除外します。
 243  
          * </p>
 244  
          * 
 245  
          * @param map
 246  
          *            属性のマップ
 247  
          * @return HTML タグの属性
 248  
          */
 249  
         public static String toAttr(final Map<String, Object> map) {
 250  48
                 final StringBuilder builder = new StringBuilder();
 251  48
                 for (final Entry<String, Object> entry : map.entrySet()) {
 252  20
                         final String key = entry.getKey();
 253  20
                         if (entry.getValue() == REMOVE_ATTRIBUTE) {
 254  0
                                 continue;
 255  
                         }
 256  20
                         builder.append(key);
 257  20
                         builder.append("=\"");
 258  20
                         builder.append(CubbyUtils.escapeHtml(entry.getValue()));
 259  20
                         builder.append("\" ");
 260  20
                 }
 261  47
                 return builder.toString();
 262  
         }
 263  
 
 264  
         /**
 265  
          * 指定されたオブジェクトが特定の文字列を含むかを示します。
 266  
          * <p>
 267  
          * 指定されたオブジェクトが配列や{@link Collection}の場合は、その要素の文字列表現が指定された文字列と同値かを示します。
 268  
          * 指定されたオブジェクトが配列や{@link Collection}でない場合は、そのオブジェクトの文字列表現が指定された文字列と同値かを示します。
 269  
          * </p>
 270  
          * 
 271  
          * @param obj
 272  
          *            オブジェクト
 273  
          * @param str
 274  
          *            文字列
 275  
          * @return 指定されたオブジェクトが特定の文字列を含む場合は <code>true</code>、そうでない場合は
 276  
          *         <code>false</code>
 277  
          */
 278  
         public static boolean contains(final Object obj, final String str) {
 279  60
                 if (obj instanceof Collection) {
 280  1
                         return ((Collection<?>) obj).contains(str);
 281  59
                 } else if (obj.getClass().isArray()) {
 282  95
                         for (final Object value : (Object[]) obj) {
 283  62
                                 if (equalsAsString(value, str)) {
 284  23
                                         return true;
 285  
                                 }
 286  
                         }
 287  32
                         return false;
 288  
                 } else {
 289  2
                         return equalsAsString(obj, str);
 290  
                 }
 291  
         }
 292  
 
 293  
         /**
 294  
          * 指定された値が文字列として同値かを示します。
 295  
          * 
 296  
          * @param obj1
 297  
          *            比較するオブジェクト1
 298  
          * @param obj2
 299  
          *            比較するオブジェクト2
 300  
          * @return obj1とobj2が文字列として同値の場合は <code>true</code>、そうでない場合は
 301  
          *         <code>false</code>
 302  
          */
 303  
         private static boolean equalsAsString(final Object obj1, final Object obj2) {
 304  64
                 if (obj1 == obj2) {
 305  10
                         return true;
 306  54
                 } else if (obj1 == null) {
 307  4
                         return false;
 308  
                 } else {
 309  50
                         return obj1.toString().equals(obj2.toString());
 310  
                 }
 311  
         }
 312  
 
 313  
         /**
 314  
          * Dynamic-Attributes に指定された class 属性を追加します。
 315  
          * 
 316  
          * @param dyn
 317  
          *            Dynamic-Attributes
 318  
          * @param className
 319  
          *            class属性の名前
 320  
          */
 321  
         public static void addClassName(final Map<String, Object> dyn,
 322  
                         final String className) {
 323  3
                 String classValue = (String) dyn.get("class");
 324  2
                 if (StringUtil.isEmpty(classValue)) {
 325  1
                         classValue = className;
 326  
                 } else {
 327  1
                         classValue = classValue + " " + className;
 328  
                 }
 329  2
                 dyn.put("class", classValue);
 330  2
         }
 331  
 
 332  
         /**
 333  
          * 指定されたタグの親の {@ilnk FormTag} を検索し、そこから指定されたフィールド名の値を取得します。
 334  
          * 
 335  
          * @param tag
 336  
          *            タグ
 337  
          * @param name
 338  
          *            フィールド名
 339  
          * @return 指定されたフィールド名の値
 340  
          */
 341  
         public static String[] getOutputValues(final SimpleTag tag,
 342  
                         final String name) {
 343  35
                 final FormTag formTag = (FormTag) SimpleTagSupport
 344  
                                 .findAncestorWithClass(tag, FormTag.class);
 345  35
                 if (formTag == null) {
 346  0
                         return null;
 347  
                 }
 348  35
                 final String[] outputValues = formTag.getValues(name);
 349  35
                 return outputValues;
 350  
         }
 351  
 
 352  
 }