1 29 30 package com.caucho.jsp.java; 31 32 import com.caucho.jsp.AnalyzedTag; 33 import com.caucho.jsp.TagInstance; 34 import com.caucho.xml.QName; 35 36 import javax.servlet.jsp.tagext.*; 37 import java.lang.reflect.Method ; 38 import java.util.ArrayList ; 39 40 43 public class CustomTag extends GenericTag 44 { 45 protected String _bodyContent; 46 47 52 public void generate(JspJavaWriter out) 53 throws Exception 54 { 55 String name = _tag.getId(); 56 String className = _tagInfo.getTagClassName(); 57 String tagHackVar = "_jsp_endTagHack" + _gen.uniqueId(); 58 Class cl = _tagClass; 59 60 AnalyzedTag analyzedTag = _tag.getAnalyzedTag(); 61 62 boolean isIterator = (IterationTag.class.isAssignableFrom(cl) || 63 BodyTag.class.isAssignableFrom(cl)); 64 boolean isBodyTag = BodyTag.class.isAssignableFrom(cl); 65 boolean isCatch = TryCatchFinally.class.isAssignableFrom(cl); 66 67 boolean isEmpty = isEmpty(); 68 boolean usesTagBody = isBodyTag && ! isEmpty && 69 analyzedTag.getStartReturnsBuffered(); 70 boolean hasEndTag = analyzedTag.getDoEnd(); 71 72 if ("empty".equalsIgnoreCase(_bodyContent)) { 73 if (! isEmpty) 74 throw error(L.l("<{0}> expects an empty body", getTagName())); 75 } 76 if (usesTagBody && hasEndTag) 77 out.println("com.caucho.jsp.BodyContentImpl " + tagHackVar + " = null;"); 78 else 79 tagHackVar = "out"; 80 81 if (! isDeclared()) { 82 out.println("if (" + name + " == null) {"); 83 out.pushDepth(); 84 generateTagInit(out); 85 out.popDepth(); 86 out.println("}"); 87 out.println(); 88 } 89 90 fillAttributes(out, name); 91 92 printVarDeclare(out, VariableInfo.AT_BEGIN); 93 94 String oldTag = "_jsp_writer" + _gen.uniqueId(); 95 96 if (analyzedTag.getDoCatch()) 97 out.println("javax.servlet.jsp.JspWriter " + oldTag + " = out;"); 98 99 if (analyzedTag.getDoCatch() || analyzedTag.getDoFinally()) { 100 out.println("try {"); 101 out.pushDepth(); 102 } 103 104 boolean hasStartTag = analyzedTag.getDoStart(); 105 int startCount = ((analyzedTag.getStartReturnsSkip() ? 1 : 0) + 106 (analyzedTag.getStartReturnsInclude() ? 1 : 0) + 107 (analyzedTag.getStartReturnsBuffered() ? 1 : 0)); 108 109 int thisId = _gen.uniqueId(); 110 if (! hasStartTag) { 111 } 112 else if (startCount == 1) { 113 out.println(name + ".doStartTag();"); 114 } 115 else { 116 out.println("int _jspEval" + thisId + " = " + name + ".doStartTag();"); 117 } 118 printVarAssign(out, VariableInfo.AT_BEGIN); 119 120 if (analyzedTag.getStartReturnsSkip() && 121 ! analyzedTag.getStartReturnsInclude() && 122 ! analyzedTag.getStartReturnsBuffered()) { 123 generateChildrenEmpty(); 125 } 126 else if (isEmpty) { 127 132 } 133 else { 134 if (startCount > 1 && analyzedTag.getStartReturnsSkip()) { 135 out.println("if (_jspEval" + thisId + " != javax.servlet.jsp.tagext.Tag.SKIP_BODY) {"); 136 out.pushDepth(); 137 } 138 else if ((hasVarDeclaration(VariableInfo.NESTED) || 139 childHasScriptlet()) && 140 ! (analyzedTag.getDoCatch() || 141 analyzedTag.getDoFinally() || 142 analyzedTag.getDoAfter() && 143 analyzedTag.getAfterReturnsAgain())) { 144 out.println("{"); 145 out.pushDepth(); 146 } 147 148 if (usesTagBody) { 149 if (analyzedTag.getStartReturnsBuffered() && 150 analyzedTag.getStartReturnsInclude()) { 151 out.println("if (_jspEval" + thisId + " == javax.servlet.jsp.tagext.BodyTag.EVAL_BODY_BUFFERED) {"); 152 out.pushDepth(); 153 } 154 155 out.println("out = pageContext.pushBody();"); 156 157 if (hasEndTag) { 158 out.println(tagHackVar + " = (com.caucho.jsp.BodyContentImpl) out;"); 159 out.println(name + ".setBodyContent(" + tagHackVar + ");"); 160 } 161 else 162 out.println(name + ".setBodyContent((javax.servlet.jsp.tagext.BodyContent) " + tagHackVar + ");"); 163 164 if (analyzedTag.getDoInit()) 165 out.println(name + ".doInitBody();"); 166 167 if (analyzedTag.getStartReturnsBuffered() && 168 analyzedTag.getStartReturnsInclude()) { 169 out.popDepth(); 170 out.println("}"); 171 172 179 } 180 } 181 else if (isBodyTag && _tag.getBodyContent()) 182 out.println(name + ".setBodyContent((javax.servlet.jsp.tagext.BodyContent) null);"); 183 184 if (analyzedTag.getDoAfter() && analyzedTag.getAfterReturnsAgain()) { 185 out.println("do {"); 186 out.pushDepth(); 187 } 188 189 out.setLocation(getFilename(), getStartLine()); 190 191 if (_children != null) 192 printVarDeclaration(out, VariableInfo.NESTED); 193 194 out.setLocation(getFilename(), getStartLine()); 195 196 generateChildren(out); 197 198 out.setLocation(getFilename(), getEndLine()); 199 200 if (analyzedTag.getDoAfter() && analyzedTag.getAfterReturnsAgain()) { 201 out.popDepth(); 202 out.println("} while (" + name + ".doAfterBody() == javax.servlet.jsp.tagext.IterationTag.EVAL_BODY_AGAIN);"); 203 } 204 else if (analyzedTag.getDoAfter()) { 205 out.println(name + ".doAfterBody();"); 206 } 207 208 if (usesTagBody) { 209 if (analyzedTag.getStartReturnsBuffered() && 210 analyzedTag.getStartReturnsInclude()) { 211 out.println("if (_jspEval" + thisId + " == javax.servlet.jsp.tagext.BodyTag.EVAL_BODY_BUFFERED)"); 212 213 if (hasEndTag) 214 out.println(" out = pageContext.popBody();"); 215 else 216 out.println(" out = pageContext.popAndReleaseBody();"); 217 } 218 else if (analyzedTag.getStartReturnsBuffered()) { 219 if (hasEndTag) 220 out.println("out = pageContext.popBody();"); 221 else 222 out.println("out = pageContext.popAndReleaseBody();"); 223 } 224 } 225 226 if (startCount > 1 && analyzedTag.getStartReturnsSkip()) { 227 out.popDepth(); 228 out.println("}"); 229 } 230 else if (isEmpty) { 231 } 232 else if ((hasVarDeclaration(VariableInfo.NESTED) || 233 childHasScriptlet()) && 234 ! (analyzedTag.getDoCatch() || 235 analyzedTag.getDoFinally() || 236 analyzedTag.getDoAfter() && 237 analyzedTag.getAfterReturnsAgain())) { 238 out.popDepth(); 239 out.println("}"); 240 } 241 } 242 243 out.setLocation(getFilename(), getEndLine()); 244 245 int endCount = ((analyzedTag.getEndReturnsSkip() ? 1 : 0) + 246 (analyzedTag.getEndReturnsEval() ? 1 : 0)); 247 248 String endVar = "_jsp_end_" + _gen.uniqueId(); 249 250 if (! hasEndTag) { 251 } 252 else if (endCount > 1) 253 out.println("int " + endVar + " = " + name + ".doEndTag();"); 254 else 255 out.println(name + ".doEndTag();"); 256 257 if (! hasEndTag || ! usesTagBody) { 258 } 259 else if (hasStartTag && 260 (analyzedTag.getStartReturnsSkip() || 261 analyzedTag.getStartReturnsInclude())) { 262 out.println("if (" + tagHackVar + " != null) {"); 263 out.println(" pageContext.releaseBody(" + tagHackVar + ");"); 264 out.println(" " + tagHackVar + " = null;"); 265 out.println("}"); 266 } 267 else { 268 out.println("pageContext.releaseBody(" + tagHackVar + ");"); 269 } 270 271 if (analyzedTag.getEndReturnsSkip()) { 272 if (hasEndTag && endCount > 1) 273 out.println("if (" + endVar + " == javax.servlet.jsp.tagext.Tag.SKIP_PAGE)"); 274 else 275 out.println("if (true)"); 276 277 if (_gen.isTag() || isInFragment()) 278 out.println(" throw new SkipPageException();"); 279 else 280 out.println(" return;"); 281 } 282 283 if (analyzedTag.getDoCatch()) { 284 String t = "_jsp_exn_" + _gen.uniqueId(); 285 286 out.popDepth(); 287 out.println("} catch (Throwable " + t + ") {"); 288 out.println(" pageContext.setWriter(" + oldTag + ");"); 289 out.println(" out = " + oldTag + ";"); 290 out.println(" " + name + ".doCatch(" + t + ");"); 291 out.pushDepth(); 292 } 293 294 if (analyzedTag.getDoFinally()) { 295 out.popDepth(); 296 out.println("} finally {"); 297 out.println(" " + name + ".doFinally();"); 298 out.pushDepth(); 299 } 300 301 if (analyzedTag.getDoCatch() || analyzedTag.getDoFinally()) { 302 out.popDepth(); 303 out.println("}"); 304 } 305 306 printVarDeclaration(out, VariableInfo.AT_END); 307 308 out.setLocation(getFilename(), getEndLine()); 309 } 310 311 315 private boolean tagImplementsMethod(Class cl, String name) 316 throws NoSuchMethodException 317 { 318 Method method; 319 320 try { 321 method = cl.getMethod(name, new Class [0]); 322 } catch (Exception e) { 323 return false; 324 } 325 326 if (method == null) 327 return false; 328 329 Class declaringClass = method.getDeclaringClass(); 330 331 return (! declaringClass.equals(TagSupport.class) && 332 ! declaringClass.equals(BodyTagSupport.class)); 333 } 334 335 340 private void generateTagInit(JspJavaWriter out) 341 throws Exception 342 { 343 TagInstance parent = _tag.getParent(); 344 String id = _tag.getId(); 345 346 String var = _tag.getId(); 347 String className = _tag.getTagClass().getName(); 348 349 out.print(var + " = new "); 350 out.printClass(_tag.getTagClass()); 351 out.println("();"); 352 353 if (JspIdConsumer.class.isAssignableFrom(_tag.getTagClass())) { 354 String shortName = className; 355 int p = shortName.lastIndexOf('.'); 356 if (p >= 0) 357 shortName = shortName.substring(p + 1); 358 359 out.print(var + ".setJspId(\"" + shortName + "-" + _gen.generateJspId() + "\");"); 360 } 361 362 if (_tag.getAnalyzedTag().getHasInjection()) { 363 out.println("_jsp_inject_" + _tag.getId() + ".configure(" + var + ");"); 364 } 365 366 AnalyzedTag analyzedTag = _tag.getAnalyzedTag(); 367 368 JspNode parentTagNode = getParent().getParentTagNode(); 369 370 out.println(var + ".setPageContext(pageContext);"); 371 if (parentTagNode == null) { 372 out.println(var + ".setParent((javax.servlet.jsp.tagext.Tag) null);"); 373 } 374 else if (parentTagNode.isSimpleTag()) { 375 String parentName = parentTagNode.getCustomTagName(); 376 377 out.println("if (" + parentName + "_adapter == null)"); 378 out.println(" " + parentName + "_adapter = new javax.servlet.jsp.tagext.TagAdapter(" + parentName + ");"); 379 out.println(var + ".setParent(" + parentName + "_adapter);"); 380 } 381 else { 382 String parentName = parentTagNode.getCustomTagName(); 383 384 out.println(var + ".setParent((javax.servlet.jsp.tagext.Tag) " + parentName + ");"); 385 } 386 387 ArrayList <QName> names = _tag.getAttributeNames(); 388 for (int i = 0; i < names.size(); i++) { 389 QName name = names.get(i); 390 391 String value = _tag.getAttribute(name); 392 if (value == null) 393 continue; 394 395 TagAttributeInfo attrInfo = _tag.getAttributeInfo(name.getLocalName()); 396 397 generateSetAttribute(out, var, name, value, false, false, attrInfo); 398 } 399 } 400 401 404 private boolean childHasScriptlet() 405 { 406 ArrayList <JspNode> children = getChildren(); 407 408 if (children == null) 409 return false; 410 411 for (int i = 0; i < children.size(); i++) { 412 JspNode child = children.get(i); 413 414 if (child instanceof JspScriptlet || child instanceof JspExpression) 415 return true; 416 } 417 418 return false; 419 } 420 } 421 | Popular Tags |