1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 19 package org.apache.catalina.startup; 20 21 22 import java.lang.reflect.Method; 23 import java.util.ArrayList; 24 25 import org.apache.catalina.Context; 26 import org.apache.catalina.Wrapper; 27 import org.apache.catalina.deploy.ContextHandler; 28 import org.apache.catalina.deploy.ContextService; 29 import org.apache.catalina.deploy.SecurityConstraint; 30 import org.apache.catalina.deploy.SecurityRoleRef; 31 import org.apache.tomcat.util.IntrospectionUtils; 32 import org.apache.tomcat.util.digester.CallMethodRule; 33 import org.apache.tomcat.util.digester.CallParamRule; 34 import org.apache.tomcat.util.digester.Digester; 35 import org.apache.tomcat.util.digester.Rule; 36 import org.apache.tomcat.util.digester.RuleSetBase; 37 import org.apache.tomcat.util.digester.SetNextRule; 38 import org.xml.sax.Attributes; 39 40 41 /** 42 * <p><strong>RuleSet</strong> for processing the contents of a web application 43 * deployment descriptor (<code>/WEB-INF/web.xml</code>) resource.</p> 44 * 45 * @author Craig R. McClanahan 46 * @version $Revision: 892516 $ $Date: 2009-12-19 23:35:15 +0100 (Sat, 19 Dec 2009) $ 47 */ 48 49 public class WebRuleSet extends RuleSetBase { 50 51 52 // ----------------------------------------------------- Instance Variables 53 54 55 /** 56 * The matching pattern prefix to use for recognizing our elements. 57 */ 58 protected String prefix = null; 59 60 61 /** 62 * The <code>SetSessionConfig</code> rule used to parse the web.xml 63 */ 64 protected SetSessionConfig sessionConfig; 65 66 67 /** 68 * The <code>SetLoginConfig</code> rule used to parse the web.xml 69 */ 70 protected SetLoginConfig loginConfig; 71 72 73 /** 74 * The <code>SetJspConfig</code> rule used to parse the web.xml 75 */ 76 protected SetJspConfig jspConfig; 77 78 79 // ------------------------------------------------------------ Constructor 80 81 82 /** 83 * Construct an instance of this <code>RuleSet</code> with the default 84 * matching pattern prefix. 85 */ 86 public WebRuleSet() { 87 88 this(""); 89 90 } 91 92 93 /** 94 * Construct an instance of this <code>RuleSet</code> with the specified 95 * matching pattern prefix. 96 * 97 * @param prefix Prefix for matching pattern rules (including the 98 * trailing slash character) 99 */ 100 public WebRuleSet(String prefix) { 101 102 super(); 103 this.namespaceURI = null; 104 this.prefix = prefix; 105 106 } 107 108 109 // --------------------------------------------------------- Public Methods 110 111 112 /** 113 * <p>Add the set of Rule instances defined in this RuleSet to the 114 * specified <code>Digester</code> instance, associating them with 115 * our namespace URI (if any). This method should only be called 116 * by a Digester instance.</p> 117 * 118 * @param digester Digester instance to which the new Rule instances 119 * should be added. 120 */ 121 public void addRuleInstances(Digester digester) { 122 sessionConfig = new SetSessionConfig(); 123 jspConfig = new SetJspConfig(); 124 loginConfig = new SetLoginConfig(); 125 126 digester.addRule(prefix + "web-app", 127 new SetPublicIdRule("setPublicId")); 128 digester.addRule(prefix + "web-app", 129 new IgnoreAnnotationsRule()); 130 131 digester.addCallMethod(prefix + "web-app/context-param", 132 "addParameter", 2); 133 digester.addCallParam(prefix + "web-app/context-param/param-name", 0); 134 digester.addCallParam(prefix + "web-app/context-param/param-value", 1); 135 136 digester.addCallMethod(prefix + "web-app/display-name", 137 "setDisplayName", 0); 138 139 digester.addRule(prefix + "web-app/distributable", 140 new SetDistributableRule()); 141 142 digester.addObjectCreate(prefix + "web-app/ejb-local-ref", 143 "org.apache.catalina.deploy.ContextLocalEjb"); 144 digester.addRule(prefix + "web-app/ejb-local-ref", 145 new SetNextNamingRule("addLocalEjb", 146 "org.apache.catalina.deploy.ContextLocalEjb")); 147 148 digester.addCallMethod(prefix + "web-app/ejb-local-ref/description", 149 "setDescription", 0); 150 digester.addCallMethod(prefix + "web-app/ejb-local-ref/ejb-link", 151 "setLink", 0); 152 digester.addCallMethod(prefix + "web-app/ejb-local-ref/ejb-ref-name", 153 "setName", 0); 154 digester.addCallMethod(prefix + "web-app/ejb-local-ref/ejb-ref-type", 155 "setType", 0); 156 digester.addCallMethod(prefix + "web-app/ejb-local-ref/local", 157 "setLocal", 0); 158 digester.addCallMethod(prefix + "web-app/ejb-local-ref/local-home", 159 "setHome", 0); 160 161 digester.addObjectCreate(prefix + "web-app/ejb-ref", 162 "org.apache.catalina.deploy.ContextEjb"); 163 digester.addRule(prefix + "web-app/ejb-ref", 164 new SetNextNamingRule("addEjb", 165 "org.apache.catalina.deploy.ContextEjb")); 166 167 digester.addCallMethod(prefix + "web-app/ejb-ref/description", 168 "setDescription", 0); 169 digester.addCallMethod(prefix + "web-app/ejb-ref/ejb-link", 170 "setLink", 0); 171 digester.addCallMethod(prefix + "web-app/ejb-ref/ejb-ref-name", 172 "setName", 0); 173 digester.addCallMethod(prefix + "web-app/ejb-ref/ejb-ref-type", 174 "setType", 0); 175 digester.addCallMethod(prefix + "web-app/ejb-ref/home", 176 "setHome", 0); 177 digester.addCallMethod(prefix + "web-app/ejb-ref/remote", 178 "setRemote", 0); 179 180 digester.addObjectCreate(prefix + "web-app/env-entry", 181 "org.apache.catalina.deploy.ContextEnvironment"); 182 digester.addRule(prefix + "web-app/env-entry", 183 new SetNextNamingRule("addEnvironment", 184 "org.apache.catalina.deploy.ContextEnvironment")); 185 186 digester.addCallMethod(prefix + "web-app/env-entry/description", 187 "setDescription", 0); 188 digester.addCallMethod(prefix + "web-app/env-entry/env-entry-name", 189 "setName", 0); 190 digester.addCallMethod(prefix + "web-app/env-entry/env-entry-type", 191 "setType", 0); 192 digester.addCallMethod(prefix + "web-app/env-entry/env-entry-value", 193 "setValue", 0); 194 195 digester.addObjectCreate(prefix + "web-app/error-page", 196 "org.apache.catalina.deploy.ErrorPage"); 197 digester.addSetNext(prefix + "web-app/error-page", 198 "addErrorPage", 199 "org.apache.catalina.deploy.ErrorPage"); 200 201 digester.addCallMethod(prefix + "web-app/error-page/error-code", 202 "setErrorCode", 0); 203 digester.addCallMethod(prefix + "web-app/error-page/exception-type", 204 "setExceptionType", 0); 205 digester.addCallMethod(prefix + "web-app/error-page/location", 206 "setLocation", 0); 207 208 digester.addObjectCreate(prefix + "web-app/filter", 209 "org.apache.catalina.deploy.FilterDef"); 210 digester.addSetNext(prefix + "web-app/filter", 211 "addFilterDef", 212 "org.apache.catalina.deploy.FilterDef"); 213 214 digester.addCallMethod(prefix + "web-app/filter/description", 215 "setDescription", 0); 216 digester.addCallMethod(prefix + "web-app/filter/display-name", 217 "setDisplayName", 0); 218 digester.addCallMethod(prefix + "web-app/filter/filter-class", 219 "setFilterClass", 0); 220 digester.addCallMethod(prefix + "web-app/filter/filter-name", 221 "setFilterName", 0); 222 digester.addCallMethod(prefix + "web-app/filter/large-icon", 223 "setLargeIcon", 0); 224 digester.addCallMethod(prefix + "web-app/filter/small-icon", 225 "setSmallIcon", 0); 226 227 digester.addCallMethod(prefix + "web-app/filter/init-param", 228 "addInitParameter", 2); 229 digester.addCallParam(prefix + "web-app/filter/init-param/param-name", 230 0); 231 digester.addCallParam(prefix + "web-app/filter/init-param/param-value", 232 1); 233 234 digester.addObjectCreate(prefix + "web-app/filter-mapping", 235 "org.apache.catalina.deploy.FilterMap"); 236 digester.addSetNext(prefix + "web-app/filter-mapping", 237 "addFilterMap", 238 "org.apache.catalina.deploy.FilterMap"); 239 240 digester.addCallMethod(prefix + "web-app/filter-mapping/filter-name", 241 "setFilterName", 0); 242 digester.addCallMethod(prefix + "web-app/filter-mapping/servlet-name", 243 "addServletName", 0); 244 digester.addCallMethod(prefix + "web-app/filter-mapping/url-pattern", 245 "addURLPattern", 0); 246 247 digester.addCallMethod(prefix + "web-app/filter-mapping/dispatcher", 248 "setDispatcher", 0); 249 250 digester.addCallMethod(prefix + "web-app/listener/listener-class", 251 "addApplicationListener", 0); 252 253 digester.addRule(prefix + "web-app/jsp-config", 254 jspConfig); 255 256 digester.addCallMethod(prefix + "web-app/jsp-config/jsp-property-group/url-pattern", 257 "addJspMapping", 0); 258 259 digester.addRule(prefix + "web-app/login-config", 260 loginConfig); 261 262 digester.addObjectCreate(prefix + "web-app/login-config", 263 "org.apache.catalina.deploy.LoginConfig"); 264 digester.addSetNext(prefix + "web-app/login-config", 265 "setLoginConfig", 266 "org.apache.catalina.deploy.LoginConfig"); 267 268 digester.addCallMethod(prefix + "web-app/login-config/auth-method", 269 "setAuthMethod", 0); 270 digester.addCallMethod(prefix + "web-app/login-config/realm-name", 271 "setRealmName", 0); 272 digester.addCallMethod(prefix + "web-app/login-config/form-login-config/form-error-page", 273 "setErrorPage", 0); 274 digester.addCallMethod(prefix + "web-app/login-config/form-login-config/form-login-page", 275 "setLoginPage", 0); 276 277 digester.addCallMethod(prefix + "web-app/mime-mapping", 278 "addMimeMapping", 2); 279 digester.addCallParam(prefix + "web-app/mime-mapping/extension", 0); 280 digester.addCallParam(prefix + "web-app/mime-mapping/mime-type", 1); 281 282 digester.addObjectCreate(prefix + "web-app/resource-env-ref", 283 "org.apache.catalina.deploy.ContextResourceEnvRef"); 284 digester.addRule(prefix + "web-app/resource-env-ref", 285 new SetNextNamingRule("addResourceEnvRef", 286 "org.apache.catalina.deploy.ContextResourceEnvRef")); 287 288 digester.addCallMethod(prefix + "web-app/resource-env-ref/resource-env-ref-name", 289 "setName", 0); 290 digester.addCallMethod(prefix + "web-app/resource-env-ref/resource-env-ref-type", 291 "setType", 0); 292 293 digester.addObjectCreate(prefix + "web-app/message-destination", 294 "org.apache.catalina.deploy.MessageDestination"); 295 digester.addSetNext(prefix + "web-app/message-destination", 296 "addMessageDestination", 297 "org.apache.catalina.deploy.MessageDestination"); 298 299 digester.addCallMethod(prefix + "web-app/message-destination/description", 300 "setDescription", 0); 301 digester.addCallMethod(prefix + "web-app/message-destination/display-name", 302 "setDisplayName", 0); 303 digester.addCallMethod(prefix + "web-app/message-destination/icon/large-icon", 304 "setLargeIcon", 0); 305 digester.addCallMethod(prefix + "web-app/message-destination/icon/small-icon", 306 "setSmallIcon", 0); 307 digester.addCallMethod(prefix + "web-app/message-destination/message-destination-name", 308 "setName", 0); 309 310 digester.addObjectCreate(prefix + "web-app/message-destination-ref", 311 "org.apache.catalina.deploy.MessageDestinationRef"); 312 digester.addSetNext(prefix + "web-app/message-destination-ref", 313 "addMessageDestinationRef", 314 "org.apache.catalina.deploy.MessageDestinationRef"); 315 316 digester.addCallMethod(prefix + "web-app/message-destination-ref/description", 317 "setDescription", 0); 318 digester.addCallMethod(prefix + "web-app/message-destination-ref/message-destination-link", 319 "setLink", 0); 320 digester.addCallMethod(prefix + "web-app/message-destination-ref/message-destination-ref-name", 321 "setName", 0); 322 digester.addCallMethod(prefix + "web-app/message-destination-ref/message-destination-type", 323 "setType", 0); 324 digester.addCallMethod(prefix + "web-app/message-destination-ref/message-destination-usage", 325 "setUsage", 0); 326 327 digester.addObjectCreate(prefix + "web-app/resource-ref", 328 "org.apache.catalina.deploy.ContextResource"); 329 digester.addRule(prefix + "web-app/resource-ref", 330 new SetNextNamingRule("addResource", 331 "org.apache.catalina.deploy.ContextResource")); 332 333 digester.addCallMethod(prefix + "web-app/resource-ref/description", 334 "setDescription", 0); 335 digester.addCallMethod(prefix + "web-app/resource-ref/res-auth", 336 "setAuth", 0); 337 digester.addCallMethod(prefix + "web-app/resource-ref/res-ref-name", 338 "setName", 0); 339 digester.addCallMethod(prefix + "web-app/resource-ref/res-sharing-scope", 340 "setScope", 0); 341 digester.addCallMethod(prefix + "web-app/resource-ref/res-type", 342 "setType", 0); 343 344 digester.addObjectCreate(prefix + "web-app/security-constraint", 345 "org.apache.catalina.deploy.SecurityConstraint"); 346 digester.addSetNext(prefix + "web-app/security-constraint", 347 "addConstraint", 348 "org.apache.catalina.deploy.SecurityConstraint"); 349 350 digester.addRule(prefix + "web-app/security-constraint/auth-constraint", 351 new SetAuthConstraintRule()); 352 digester.addCallMethod(prefix + "web-app/security-constraint/auth-constraint/role-name", 353 "addAuthRole", 0); 354 digester.addCallMethod(prefix + "web-app/security-constraint/display-name", 355 "setDisplayName", 0); 356 digester.addCallMethod(prefix + "web-app/security-constraint/user-data-constraint/transport-guarantee", 357 "setUserConstraint", 0); 358 359 digester.addObjectCreate(prefix + "web-app/security-constraint/web-resource-collection", 360 "org.apache.catalina.deploy.SecurityCollection"); 361 digester.addSetNext(prefix + "web-app/security-constraint/web-resource-collection", 362 "addCollection", 363 "org.apache.catalina.deploy.SecurityCollection"); 364 digester.addCallMethod(prefix + "web-app/security-constraint/web-resource-collection/http-method", 365 "addMethod", 0); 366 digester.addCallMethod(prefix + "web-app/security-constraint/web-resource-collection/url-pattern", 367 "addPattern", 0); 368 digester.addCallMethod(prefix + "web-app/security-constraint/web-resource-collection/web-resource-name", 369 "setName", 0); 370 371 digester.addCallMethod(prefix + "web-app/security-role/role-name", 372 "addSecurityRole", 0); 373 374 digester.addObjectCreate(prefix + "web-app/service-ref", 375 "org.apache.catalina.deploy.ContextService"); 376 digester.addRule(prefix + "web-app/service-ref", 377 new SetNextNamingRule("addService", 378 "org.apache.catalina.deploy.ContextService")); 379 380 digester.addCallMethod(prefix + "web-app/service-ref/description", 381 "setDescription", 0); 382 digester.addCallMethod(prefix + "web-app/service-ref/display-name", 383 "setDisplayname", 0); 384 digester.addCallMethod(prefix + "web-app/service-ref/icon", 385 "setIcon", 0); 386 digester.addCallMethod(prefix + "web-app/service-ref/service-ref-name", 387 "setName", 0); 388 digester.addCallMethod(prefix + "web-app/service-ref/service-interface", 389 "setType", 0); 390 digester.addCallMethod(prefix + "web-app/service-ref/wsdl-file", 391 "setWsdlfile", 0); 392 digester.addCallMethod(prefix + "web-app/service-ref/jaxrpc-mapping-file", 393 "setJaxrpcmappingfile", 0); 394 digester.addRule(prefix + "web-app/service-ref/service-qname", new ServiceQnameRule()); 395 396 digester.addRule(prefix + "web-app/service-ref/port-component-ref", 397 new CallMethodMultiRule("addPortcomponent", 2, 1)); 398 digester.addCallParam(prefix + "web-app/service-ref/port-component-ref/service-endpoint-interface", 0); 399 digester.addRule(prefix + "web-app/service-ref/port-component-ref/port-component-link", new CallParamMultiRule(1)); 400 401 digester.addObjectCreate(prefix + "web-app/service-ref/handler", 402 "org.apache.catalina.deploy.ContextHandler"); 403 digester.addRule(prefix + "web-app/service-ref/handler", 404 new SetNextRule("addHandler", 405 "org.apache.catalina.deploy.ContextHandler")); 406 407 digester.addCallMethod(prefix + "web-app/service-ref/handler/handler-name", 408 "setName", 0); 409 digester.addCallMethod(prefix + "web-app/service-ref/handler/handler-class", 410 "setHandlerclass", 0); 411 412 digester.addCallMethod(prefix + "web-app/service-ref/handler/init-param", 413 "setProperty", 2); 414 digester.addCallParam(prefix + "web-app/service-ref/handler/init-param/param-name", 415 0); 416 digester.addCallParam(prefix + "web-app/service-ref/handler/init-param/param-value", 417 1); 418 419 digester.addRule(prefix + "web-app/service-ref/handler/soap-header", new SoapHeaderRule()); 420 421 digester.addCallMethod(prefix + "web-app/service-ref/handler/soap-role", 422 "addSoapRole", 0); 423 digester.addCallMethod(prefix + "web-app/service-ref/handler/port-name", 424 "addPortName", 0); 425 426 digester.addRule(prefix + "web-app/servlet", 427 new WrapperCreateRule()); 428 digester.addSetNext(prefix + "web-app/servlet", 429 "addChild", 430 "org.apache.catalina.Container"); 431 432 digester.addCallMethod(prefix + "web-app/servlet/init-param", 433 "addInitParameter", 2); 434 digester.addCallParam(prefix + "web-app/servlet/init-param/param-name", 435 0); 436 digester.addCallParam(prefix + "web-app/servlet/init-param/param-value", 437 1); 438 439 digester.addCallMethod(prefix + "web-app/servlet/jsp-file", 440 "setJspFile", 0); 441 digester.addCallMethod(prefix + "web-app/servlet/load-on-startup", 442 "setLoadOnStartupString", 0); 443 digester.addCallMethod(prefix + "web-app/servlet/run-as/role-name", 444 "setRunAs", 0); 445 446 digester.addRule(prefix + "web-app/servlet/security-role-ref", 447 new SecurityRoleRefCreateRule()); 448 digester.addCallMethod( 449 prefix + "web-app/servlet/security-role-ref/role-link", 450 "setLink", 0); 451 digester.addCallMethod( 452 prefix + "web-app/servlet/security-role-ref/role-name", 453 "setName", 0); 454 455 digester.addCallMethod(prefix + "web-app/servlet/servlet-class", 456 "setServletClass", 0); 457 digester.addCallMethod(prefix + "web-app/servlet/servlet-name", 458 "setName", 0); 459 460 digester.addRule(prefix + "web-app/servlet-mapping", 461 new CallMethodMultiRule("addServletMapping", 2, 0)); 462 digester.addCallParam(prefix + "web-app/servlet-mapping/servlet-name", 1); 463 digester.addRule(prefix + "web-app/servlet-mapping/url-pattern", new CallParamMultiRule(0)); 464 465 digester.addRule(prefix + "web-app/session-config", 466 sessionConfig); 467 468 digester.addCallMethod(prefix + "web-app/session-config/session-timeout", 469 "setSessionTimeout", 1, 470 new Class[] { Integer.TYPE }); 471 digester.addCallParam(prefix + "web-app/session-config/session-timeout", 0); 472 473 digester.addCallMethod(prefix + "web-app/taglib", 474 "addTaglib", 2); 475 digester.addCallParam(prefix + "web-app/taglib/taglib-location", 1); 476 digester.addCallParam(prefix + "web-app/taglib/taglib-uri", 0); 477 478 digester.addCallMethod(prefix + "web-app/welcome-file-list/welcome-file", 479 "addWelcomeFile", 0); 480 481 digester.addCallMethod(prefix + "web-app/locale-encoding-mapping-list/locale-encoding-mapping", 482 "addLocaleEncodingMappingParameter", 2); 483 digester.addCallParam(prefix + "web-app/locale-encoding-mapping-list/locale-encoding-mapping/locale", 0); 484 digester.addCallParam(prefix + "web-app/locale-encoding-mapping-list/locale-encoding-mapping/encoding", 1); 485 486 } 487 488 /** 489 * Reset counter used for validating the web.xml file. 490 */ 491 public void recycle(){ 492 jspConfig.isJspConfigSet = false; 493 sessionConfig.isSessionConfigSet = false; 494 loginConfig.isLoginConfigSet = false; 495 } 496 } 497 498 499 // ----------------------------------------------------------- Private Classes 500 501 502 /** 503 * Rule to check that the <code>login-config</code> is occuring 504 * only 1 time within the web.xml 505 */ 506 final class SetLoginConfig extends Rule { 507 protected boolean isLoginConfigSet = false; 508 public SetLoginConfig() { 509 } 510 511 public void begin(String namespace, String name, Attributes attributes) 512 throws Exception { 513 if (isLoginConfigSet){ 514 throw new IllegalArgumentException( 515 "<login-config> element is limited to 1 occurrence"); 516 } 517 isLoginConfigSet = true; 518 } 519 520 } 521 522 523 /** 524 * Rule to check that the <code>jsp-config</code> is occuring 525 * only 1 time within the web.xml 526 */ 527 final class SetJspConfig extends Rule { 528 protected boolean isJspConfigSet = false; 529 public SetJspConfig() { 530 } 531 532 public void begin(String namespace, String name, Attributes attributes) 533 throws Exception { 534 if (isJspConfigSet){ 535 throw new IllegalArgumentException( 536 "<jsp-config> element is limited to 1 occurrence"); 537 } 538 isJspConfigSet = true; 539 } 540 541 } 542 543 544 /** 545 * Rule to check that the <code>session-config</code> is occuring 546 * only 1 time within the web.xml 547 */ 548 final class SetSessionConfig extends Rule { 549 protected boolean isSessionConfigSet = false; 550 public SetSessionConfig() { 551 } 552 553 public void begin(String namespace, String name, Attributes attributes) 554 throws Exception { 555 if (isSessionConfigSet){ 556 throw new IllegalArgumentException( 557 "<session-config> element is limited to 1 occurrence"); 558 } 559 isSessionConfigSet = true; 560 } 561 562 } 563 564 /** 565 * A Rule that calls the <code>setAuthConstraint(true)</code> method of 566 * the top item on the stack, which must be of type 567 * <code>org.apache.catalina.deploy.SecurityConstraint</code>. 568 */ 569 570 final class SetAuthConstraintRule extends Rule { 571 572 public SetAuthConstraintRule() { 573 } 574 575 public void begin(String namespace, String name, Attributes attributes) 576 throws Exception { 577 SecurityConstraint securityConstraint = 578 (SecurityConstraint) digester.peek(); 579 securityConstraint.setAuthConstraint(true); 580 if (digester.getLogger().isDebugEnabled()) { 581 digester.getLogger() 582 .debug("Calling SecurityConstraint.setAuthConstraint(true)"); 583 } 584 } 585 586 } 587 588 589 /** 590 * Class that calls <code>setDistributable(true)</code> for the top object 591 * on the stack, which must be a <code>org.apache.catalina.Context</code>. 592 */ 593 594 final class SetDistributableRule extends Rule { 595 596 public SetDistributableRule() { 597 } 598 599 public void begin(String namespace, String name, Attributes attributes) 600 throws Exception { 601 Context context = (Context) digester.peek(); 602 context.setDistributable(true); 603 if (digester.getLogger().isDebugEnabled()) { 604 digester.getLogger().debug 605 (context.getClass().getName() + ".setDistributable( true)"); 606 } 607 } 608 609 } 610 611 612 /** 613 * Class that calls a property setter for the top object on the stack, 614 * passing the public ID of the entity we are currently processing. 615 */ 616 617 final class SetPublicIdRule extends Rule { 618 619 public SetPublicIdRule(String method) { 620 this.method = method; 621 } 622 623 private String method = null; 624 625 public void begin(String namespace, String name, Attributes attributes) 626 throws Exception { 627 628 Object top = digester.peek(); 629 Class paramClasses[] = new Class[1]; 630 paramClasses[0] = "String".getClass(); 631 String paramValues[] = new String[1]; 632 paramValues[0] = digester.getPublicId(); 633 634 Method m = null; 635 try { 636 m = top.getClass().getMethod(method, paramClasses); 637 } catch (NoSuchMethodException e) { 638 digester.getLogger().error("Can't find method " + method + " in " 639 + top + " CLASS " + top.getClass()); 640 return; 641 } 642 643 m.invoke(top, (Object [])paramValues); 644 if (digester.getLogger().isDebugEnabled()) 645 digester.getLogger().debug("" + top.getClass().getName() + "." 646 + method + "(" + paramValues[0] + ")"); 647 648 } 649 650 } 651 652 653 /** 654 * A Rule that calls the factory method on the specified Context to 655 * create the object that is to be added to the stack. 656 */ 657 658 final class WrapperCreateRule extends Rule { 659 660 public WrapperCreateRule() { 661 } 662 663 public void begin(String namespace, String name, Attributes attributes) 664 throws Exception { 665 Context context = 666 (Context) digester.peek(digester.getCount() - 1); 667 Wrapper wrapper = context.createWrapper(); 668 digester.push(wrapper); 669 if (digester.getLogger().isDebugEnabled()) 670 digester.getLogger().debug("new " + wrapper.getClass().getName()); 671 } 672 673 public void end(String namespace, String name) 674 throws Exception { 675 Wrapper wrapper = (Wrapper) digester.pop(); 676 if (digester.getLogger().isDebugEnabled()) 677 digester.getLogger().debug("pop " + wrapper.getClass().getName()); 678 } 679 680 } 681 682 683 /** 684 * A Rule that can be used to call multiple times a method as many times as needed 685 * (used for addServletMapping). 686 */ 687 final class CallParamMultiRule extends CallParamRule { 688 689 public CallParamMultiRule(int paramIndex) { 690 super(paramIndex); 691 } 692 693 public void end(String namespace, String name) { 694 if (bodyTextStack != null && !bodyTextStack.empty()) { 695 // what we do now is push one parameter onto the top set of parameters 696 Object parameters[] = (Object[]) digester.peekParams(); 697 ArrayList params = (ArrayList) parameters[paramIndex]; 698 if (params == null) { 699 params = new ArrayList(); 700 parameters[paramIndex] = params; 701 } 702 params.add(bodyTextStack.pop()); 703 } 704 } 705 706 } 707 708 709 /** 710 * A Rule that can be used to call multiple times a method as many times as needed 711 * (used for addServletMapping). 712 */ 713 final class CallMethodMultiRule extends CallMethodRule { 714 715 protected int multiParamIndex = 0; 716 717 public CallMethodMultiRule(String methodName, int paramCount, int multiParamIndex) { 718 super(methodName, paramCount); 719 this.multiParamIndex = multiParamIndex; 720 } 721 722 public void end() throws Exception { 723 724 // Retrieve or construct the parameter values array 725 Object parameters[] = null; 726 if (paramCount > 0) { 727 parameters = (Object[]) digester.popParams(); 728 } else { 729 super.end(); 730 } 731 732 ArrayList multiParams = (ArrayList) parameters[multiParamIndex]; 733 734 // Construct the parameter values array we will need 735 // We only do the conversion if the param value is a String and 736 // the specified paramType is not String. 737 Object paramValues[] = new Object[paramTypes.length]; 738 for (int i = 0; i < paramTypes.length; i++) { 739 if (i != multiParamIndex) { 740 // convert nulls and convert stringy parameters 741 // for non-stringy param types 742 if(parameters[i] == null || (parameters[i] instanceof String 743 && !String.class.isAssignableFrom(paramTypes[i]))) { 744 paramValues[i] = 745 IntrospectionUtils.convert((String) parameters[i], paramTypes[i]); 746 } else { 747 paramValues[i] = parameters[i]; 748 } 749 } 750 } 751 752 // Determine the target object for the method call 753 Object target; 754 if (targetOffset >= 0) { 755 target = digester.peek(targetOffset); 756 } else { 757 target = digester.peek(digester.getCount() + targetOffset); 758 } 759 760 if (target == null) { 761 StringBuffer sb = new StringBuffer(); 762 sb.append("[CallMethodRule]{"); 763 sb.append(""); 764 sb.append("} Call target is null ("); 765 sb.append("targetOffset="); 766 sb.append(targetOffset); 767 sb.append(",stackdepth="); 768 sb.append(digester.getCount()); 769 sb.append(")"); 770 throw new org.xml.sax.SAXException(sb.toString()); 771 } 772 773 if (multiParams == null) { 774 paramValues[multiParamIndex] = null; 775 Object result = IntrospectionUtils.callMethodN(target, methodName, 776 paramValues, paramTypes); 777 return; 778 } 779 780 for (int j = 0; j < multiParams.size(); j++) { 781 Object param = multiParams.get(j); 782 if(param == null || (param instanceof String 783 && !String.class.isAssignableFrom(paramTypes[multiParamIndex]))) { 784 paramValues[multiParamIndex] = 785 IntrospectionUtils.convert((String) param, paramTypes[multiParamIndex]); 786 } else { 787 paramValues[multiParamIndex] = param; 788 } 789 Object result = IntrospectionUtils.callMethodN(target, methodName, 790 paramValues, paramTypes); 791 } 792 793 } 794 795 } 796 797 798 799 /** 800 * A Rule that check if the annotations have to be loaded. 801 * 802 */ 803 804 final class IgnoreAnnotationsRule extends Rule { 805 806 public IgnoreAnnotationsRule() { 807 } 808 809 public void begin(String namespace, String name, Attributes attributes) 810 throws Exception { 811 Context context = (Context) digester.peek(digester.getCount() - 1); 812 String value = attributes.getValue("metadata-complete"); 813 if ("true".equals(value)) { 814 context.setIgnoreAnnotations(true); 815 } else if ("false".equals(value)) { 816 context.setIgnoreAnnotations(false); 817 } 818 if (digester.getLogger().isDebugEnabled()) { 819 digester.getLogger().debug 820 (context.getClass().getName() + ".setIgnoreAnnotations( " + 821 context.getIgnoreAnnotations() + ")"); 822 } 823 } 824 825 } 826 827 /** 828 * A Rule that sets soap headers on the ContextHandler. 829 * 830 */ 831 final class SoapHeaderRule extends Rule { 832 833 public SoapHeaderRule() { 834 } 835 836 public void body(String text) 837 throws Exception { 838 String namespaceuri = null; 839 String localpart = text; 840 int colon = text.indexOf(':'); 841 if (colon >= 0) { 842 String prefix = text.substring(0,colon); 843 namespaceuri = digester.findNamespaceURI(prefix); 844 localpart = text.substring(colon+1); 845 } 846 ContextHandler contextHandler = (ContextHandler)digester.peek(); 847 contextHandler.addSoapHeaders(localpart,namespaceuri); 848 } 849 } 850 851 /** 852 * A Rule that sets service qname on the ContextService. 853 * 854 */ 855 final class ServiceQnameRule extends Rule { 856 857 public ServiceQnameRule() { 858 } 859 860 public void body(String text) 861 throws Exception { 862 String namespaceuri = null; 863 String localpart = text; 864 int colon = text.indexOf(':'); 865 if (colon >= 0) { 866 String prefix = text.substring(0,colon); 867 namespaceuri = digester.findNamespaceURI(prefix); 868 localpart = text.substring(colon+1); 869 } 870 ContextService contextService = (ContextService)digester.peek(); 871 contextService.setServiceqnameLocalpart(localpart); 872 contextService.setServiceqnameNamespaceURI(namespaceuri); 873 } 874 } 875 876 /** 877 * A Rule that adds a security-role-ref to a servlet, allowing for the fact that 878 * role-link is an optional element. 879 */ 880 final class SecurityRoleRefCreateRule extends Rule { 881 882 public SecurityRoleRefCreateRule() { 883 } 884 885 public void begin(String namespace, String name, Attributes attributes) 886 throws Exception { 887 SecurityRoleRef securityRoleRef = new SecurityRoleRef(); 888 digester.push(securityRoleRef); 889 if (digester.getLogger().isDebugEnabled()) 890 digester.getLogger().debug("new SecurityRoleRef"); 891 } 892 893 public void end(String namespace, String name) 894 throws Exception { 895 SecurityRoleRef securityRoleRef = (SecurityRoleRef) digester.pop(); 896 Wrapper wrapper = (Wrapper) digester.peek(); 897 898 wrapper.addSecurityReference(securityRoleRef.getName(), 899 securityRoleRef.getLink()); 900 901 if (digester.getLogger().isDebugEnabled()) 902 digester.getLogger().debug("pop SecurityRoleRef"); 903 } 904 }