1 /** 2 * Licensed under the Artistic License; you may not use this file 3 * except in compliance with the License. 4 * You may obtain a copy of the License at 5 * 6 * http://displaytag.sourceforge.net/license.html 7 * 8 * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR 9 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 10 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 11 */ 12 package org.displaytag.tags; 13 14 import java.util.ArrayList; 15 import java.util.Arrays; 16 import java.util.List; 17 18 import javax.servlet.jsp.tagext.TagAttributeInfo; 19 import javax.servlet.jsp.tagext.TagData; 20 import javax.servlet.jsp.tagext.TagExtraInfo; 21 import javax.servlet.jsp.tagext.VariableInfo; 22 23 24 /** 25 * TEI for TableTag, defines 3 variables. 26 * <ul> 27 * <li>table uid = object contained in row</li> 28 * <li>table uid + ROWNUM_SUFFIX = row number</li> 29 * </ul> 30 * @author Fabrizio Giustina 31 * @version $Revision: 1081 $ ($Author: fgiust $) 32 */ 33 public class TableTagExtraInfo extends TagExtraInfo 34 { 35 36 /** 37 * Suffix added to id for saving row number in pagecontext. 38 */ 39 public static final String ROWNUM_SUFFIX = "_rowNum"; //$NON-NLS-1$ 40 41 /** 42 * Java keywords. 43 */ 44 private static final String[] KEYWORDS = {"abstract", //$NON-NLS-1$ 45 "assert", //$NON-NLS-1$ 46 "boolean", //$NON-NLS-1$ 47 "break", //$NON-NLS-1$ 48 "byte", //$NON-NLS-1$ 49 "case", //$NON-NLS-1$ 50 "catch", //$NON-NLS-1$ 51 "char", //$NON-NLS-1$ 52 "class", //$NON-NLS-1$ 53 "const", //$NON-NLS-1$ 54 "continue", //$NON-NLS-1$ 55 "default", //$NON-NLS-1$ 56 "do", //$NON-NLS-1$ 57 "double", //$NON-NLS-1$ 58 "else", //$NON-NLS-1$ 59 "enum", //$NON-NLS-1$ 60 "extends", //$NON-NLS-1$ 61 "false", //$NON-NLS-1$ 62 "final", //$NON-NLS-1$ 63 "finally", //$NON-NLS-1$ 64 "float", //$NON-NLS-1$ 65 "for", //$NON-NLS-1$ 66 "goto", //$NON-NLS-1$ 67 "if", //$NON-NLS-1$ 68 "implements", //$NON-NLS-1$ 69 "import", //$NON-NLS-1$ 70 "instanceof", //$NON-NLS-1$ 71 "int", //$NON-NLS-1$ 72 "interface", //$NON-NLS-1$ 73 "long", //$NON-NLS-1$ 74 "native", //$NON-NLS-1$ 75 "new", //$NON-NLS-1$ 76 "null", //$NON-NLS-1$ 77 "package", //$NON-NLS-1$ 78 "private", //$NON-NLS-1$ 79 "protected", //$NON-NLS-1$ 80 "public", //$NON-NLS-1$ 81 "return", //$NON-NLS-1$ 82 "short", //$NON-NLS-1$ 83 "static", //$NON-NLS-1$ 84 "strictfp", //$NON-NLS-1$ 85 "super", //$NON-NLS-1$ 86 "switch", //$NON-NLS-1$ 87 "synchronized", //$NON-NLS-1$ 88 "this", //$NON-NLS-1$ 89 "throw", //$NON-NLS-1$ 90 "throws", //$NON-NLS-1$ 91 "transient", //$NON-NLS-1$ 92 "true", //$NON-NLS-1$ 93 "try", //$NON-NLS-1$ 94 "void", //$NON-NLS-1$ 95 "volatile", //$NON-NLS-1$ 96 "while"}; //$NON-NLS-1$ 97 98 /** 99 * Variables TableTag makes available in the pageContext. 100 * @param data TagData 101 * @return VariableInfo[] 102 * @see javax.servlet.jsp.tagext.TagData 103 * @see javax.servlet.jsp.tagext.VariableInfo 104 */ 105 public VariableInfo[] getVariableInfo(TagData data) 106 { 107 List variables = new ArrayList(2); 108 109 Object idObj = data.getAttribute(TagAttributeInfo.ID); 110 111 // handle both the id and uid attributes 112 if (idObj == null) 113 { 114 idObj = data.getAttribute("uid"); //$NON-NLS-1$ 115 } 116 117 // avoid errors, but "id" and "id_rownum" will not be defined 118 if (idObj != TagData.REQUEST_TIME_VALUE && idObj != null) 119 { 120 String tagId = idObj.toString(); 121 122 // don't try to add variables if id is not a valid java identifier. 123 if (isJavaId(tagId)) 124 { 125 // current row 126 variables.add(new VariableInfo(tagId, Object.class.getName(), true, VariableInfo.NESTED)); 127 // current row number 128 variables.add(new VariableInfo( 129 tagId + ROWNUM_SUFFIX, 130 Integer.class.getName(), 131 true, 132 VariableInfo.NESTED)); 133 } 134 } 135 136 return (VariableInfo[]) variables.toArray(new VariableInfo[]{}); 137 } 138 139 /** 140 * isJavaId Returns true if the name is a valid java identifier. 141 * @param id to check 142 * @return boolean true/false 143 */ 144 public static boolean isJavaId(String id) 145 { 146 if (id == null 147 || id.length() == 0 148 || Arrays.binarySearch(KEYWORDS, id) >= 0 149 || !Character.isJavaIdentifierStart(id.charAt(0))) 150 { 151 return false; 152 } 153 154 for (int j = 1; j < id.length(); j++) 155 { 156 if (!Character.isJavaIdentifierPart(id.charAt(j))) 157 { 158 return false; 159 } 160 } 161 return true; 162 } 163 164 }