1 16 17 package org.apache.taglibs.standard.tlv; 18 19 import java.util.Set ; 20 import java.util.Stack ; 21 22 import javax.servlet.jsp.tagext.PageData ; 23 import javax.servlet.jsp.tagext.ValidationMessage ; 24 25 import org.apache.taglibs.standard.resources.Resources; 26 import org.xml.sax.Attributes ; 27 import org.xml.sax.helpers.DefaultHandler ; 28 29 43 public class JstlXmlTLV extends JstlBaseTLV { 44 45 48 68 69 70 73 private final String CHOOSE = "choose"; 75 private final String WHEN = "when"; 76 private final String OTHERWISE = "otherwise"; 77 private final String PARSE = "parse"; 78 private final String PARAM = "param"; 79 private final String TRANSFORM = "transform"; 80 private final String JSP_TEXT = "jsp:text"; 81 82 private final String VALUE = "value"; 84 private final String SOURCE = "xml"; 85 86 87 public ValidationMessage [] validate( 90 String prefix, String uri, PageData page) { 91 return super.validate( TYPE_XML, prefix, uri, page ); 92 } 93 94 95 98 protected DefaultHandler getHandler() { 99 return new Handler (); 100 } 101 102 103 106 107 private class Handler extends DefaultHandler { 108 109 private int depth = 0; 111 private Stack chooseDepths = new Stack (); 112 private Stack chooseHasOtherwise = new Stack (); 113 private Stack chooseHasWhen = new Stack (); 114 private String lastElementName = null; 115 private boolean bodyNecessary = false; 116 private boolean bodyIllegal = false; 117 private Stack transformWithSource = new Stack (); 118 119 public void startElement( 121 String ns, String ln, String qn, Attributes a) { 122 123 if (ln == null) 125 ln = getLocalPart(qn); 126 127 if (qn.equals(JSP_TEXT)) 130 return; 131 132 if (bodyIllegal) 134 fail(Resources.getMessage("TLV_ILLEGAL_BODY", lastElementName)); 135 136 Set expAtts; 138 if (qn.startsWith(prefix + ":") 139 && (expAtts = (Set ) config.get(ln)) != null) { 140 for (int i = 0; i < a.getLength(); i++) { 141 String attName = a.getLocalName(i); 142 if (expAtts.contains(attName)) { 143 String vMsg = 144 validateExpression( 145 ln, 146 attName, 147 a.getValue(i)); 148 if (vMsg != null) 149 fail(vMsg); 150 } 151 } 152 } 153 154 if (qn.startsWith(prefix + ":") && !hasNoInvalidScope(a)) 156 fail(Resources.getMessage("TLV_INVALID_ATTRIBUTE", 157 SCOPE, qn, a.getValue(SCOPE))); 158 if (qn.startsWith(prefix + ":") && hasEmptyVar(a)) 159 fail(Resources.getMessage("TLV_EMPTY_VAR", qn)); 160 if (qn.startsWith(prefix + ":") && hasDanglingScope(a)) 161 fail(Resources.getMessage("TLV_DANGLING_SCOPE", qn)); 162 163 if (chooseChild()) { 165 if (isXmlTag(ns, ln, WHEN)) { 167 chooseHasWhen.pop(); 168 chooseHasWhen.push(Boolean.TRUE); 169 } 170 171 if(!isXmlTag(ns, ln, WHEN) && !isXmlTag(ns, ln, OTHERWISE)) { 173 fail(Resources.getMessage("TLV_ILLEGAL_CHILD_TAG", 174 prefix, CHOOSE, qn)); 175 } 176 177 if (((Boolean ) chooseHasOtherwise.peek()).booleanValue()) { 179 fail(Resources.getMessage("TLV_ILLEGAL_ORDER", 180 qn, prefix, OTHERWISE, CHOOSE)); 181 } 182 if (isXmlTag(ns, ln, OTHERWISE)) { 183 chooseHasOtherwise.pop(); 184 chooseHasOtherwise.push(Boolean.TRUE); 185 } 186 187 } 188 189 if (!transformWithSource.empty() && 191 topDepth(transformWithSource) == (depth - 1)) { 192 if (!isXmlTag(ns, ln, PARAM)) 194 fail(Resources.getMessage("TLV_ILLEGAL_BODY", 195 prefix + ":" + TRANSFORM)); 196 197 } 200 201 203 if (isXmlTag(ns, ln, CHOOSE)) { 205 chooseDepths.push(new Integer (depth)); 206 chooseHasWhen.push(Boolean.FALSE); 207 chooseHasOtherwise.push(Boolean.FALSE); 208 } 209 210 bodyIllegal = false; 212 bodyNecessary = false; 213 if (isXmlTag(ns, ln, PARSE)) { 214 if (hasAttribute(a, SOURCE)) 215 bodyIllegal = true; 216 } else if (isXmlTag(ns, ln, PARAM)) { 217 if (hasAttribute(a, VALUE)) 218 bodyIllegal = true; 219 else 220 bodyNecessary = true; 221 } else if (isXmlTag(ns, ln, TRANSFORM)) { 222 if (hasAttribute(a, SOURCE)) 223 transformWithSource.push(new Integer (depth)); 224 } 225 226 lastElementName = qn; 228 lastElementId = a.getValue("http://java.sun.com/JSP/Page", "id"); 229 230 depth++; 232 } 233 234 public void characters(char[] ch, int start, int length) { 235 236 bodyNecessary = false; 238 String s = new String (ch, start, length).trim(); 240 if (s.equals("")) 241 return; 242 243 if (bodyIllegal) 245 fail(Resources.getMessage("TLV_ILLEGAL_BODY", lastElementName)); 246 247 if (chooseChild()) { 249 String msg = 250 Resources.getMessage("TLV_ILLEGAL_TEXT_BODY", 251 prefix, CHOOSE, 252 (s.length() < 7 ? s : s.substring(0,7))); 253 fail(msg); 254 } 255 256 if (!transformWithSource.empty() 258 && topDepth(transformWithSource) == (depth - 1)) { 259 fail(Resources.getMessage("TLV_ILLEGAL_BODY", 260 prefix + ":" + TRANSFORM)); 261 } 262 } 263 264 public void endElement(String ns, String ln, String qn) { 265 266 if (qn.equals(JSP_TEXT)) 268 return; 269 270 if (bodyNecessary) 272 fail(Resources.getMessage("TLV_MISSING_BODY", 273 lastElementName)); 274 bodyIllegal = false; 276 if (isXmlTag(ns, ln, CHOOSE)) { 278 Boolean b = (Boolean ) chooseHasWhen.pop(); 279 if (!b.booleanValue()) 280 fail(Resources.getMessage("TLV_PARENT_WITHOUT_SUBTAG", 281 CHOOSE, WHEN)); 282 chooseDepths.pop(); 283 chooseHasOtherwise.pop(); 284 } 285 286 if (!transformWithSource.empty() 288 && topDepth(transformWithSource) == (depth - 1)) 289 transformWithSource.pop(); 290 291 depth--; 293 } 294 295 private boolean chooseChild() { 297 return (!chooseDepths.empty() 298 && (depth - 1) == ((Integer ) chooseDepths.peek()).intValue()); 299 } 300 301 private int topDepth(Stack s) { 303 return ((Integer ) s.peek()).intValue(); 304 } 305 } 306 } 307 | Popular Tags |