001 // Copyright 2005 The Apache Software Foundation 002 // 003 // Licensed under the Apache License, Version 2.0 (the "License"); 004 // you may not use this file except in compliance with the License. 005 // You may obtain a copy of the License at 006 // 007 // http://www.apache.org/licenses/LICENSE-2.0 008 // 009 // Unless required by applicable law or agreed to in writing, software 010 // distributed under the License is distributed on an "AS IS" BASIS, 011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012 // See the License for the specific language governing permissions and 013 // limitations under the License. 014 015 package org.apache.tapestry.resolver; 016 017 import org.apache.commons.logging.Log; 018 import org.apache.hivemind.ApplicationRuntimeException; 019 import org.apache.hivemind.Location; 020 import org.apache.hivemind.Resource; 021 import org.apache.tapestry.BaseComponent; 022 import org.apache.tapestry.INamespace; 023 import org.apache.tapestry.IRequestCycle; 024 import org.apache.tapestry.engine.ISpecificationSource; 025 import org.apache.tapestry.services.ClassFinder; 026 import org.apache.tapestry.spec.IComponentSpecification; 027 import static org.easymock.EasyMock.*; 028 import org.testng.annotations.Test; 029 030 import java.net.URL; 031 032 /** 033 * Tests for {@link org.apache.tapestry.resolver.ComponentSpecificationResolverImpl}. 034 * 035 * @author Howard M. Lewis Ship 036 * @since 4.0 037 */ 038 @Test 039 public class TestComponentSpecificationResolver extends AbstractSpecificationResolverTestCase 040 { 041 private void trainIsDeprecated(IComponentSpecification spec, 042 boolean isDeprecated) 043 { 044 expect(spec.isDeprecated()).andReturn(isDeprecated); 045 } 046 047 protected ISpecificationSource newSource(Resource resource, IComponentSpecification spec) 048 { 049 ISpecificationSource source = newMock(ISpecificationSource.class); 050 051 expect(source.getComponentSpecification(resource)).andReturn(spec); 052 053 return source; 054 } 055 056 protected ISpecificationSource newSource(INamespace framework) 057 { 058 ISpecificationSource source = newMock(ISpecificationSource.class); 059 060 expect(source.getFrameworkNamespace()).andReturn(framework); 061 062 return source; 063 } 064 065 private ISpecificationResolverDelegate newDelegate(IRequestCycle cycle, INamespace namespace, 066 String type, IComponentSpecification spec) 067 { 068 ISpecificationResolverDelegate delegate = newMock(ISpecificationResolverDelegate.class); 069 checkOrder(delegate, false); 070 071 expect(delegate.findComponentSpecification(cycle, namespace, type)).andReturn(spec).anyTimes(); 072 073 return delegate; 074 } 075 076 public void test_Not_Found_In_Any_Namespace() 077 { 078 IRequestCycle cycle = newCycle(); 079 Location l = newLocation(); 080 081 INamespace namespace = newMock(INamespace.class); 082 083 ApplicationRuntimeException exception = new ApplicationRuntimeException(""); 084 085 expect(namespace.getChildNamespace("invalid")).andThrow(exception); 086 087 replay(); 088 089 ComponentSpecificationResolverImpl resolver = new ComponentSpecificationResolverImpl(); 090 091 try 092 { 093 resolver.resolve(cycle, namespace, "invalid:MyComponent", l); 094 unreachable(); 095 } 096 catch (ApplicationRuntimeException ex) 097 { 098 assertSame(ex.getCause(), exception); 099 } 100 101 verify(); 102 } 103 104 public void test_Found_In_Namespace() 105 { 106 IRequestCycle cycle = newCycle(); 107 Location l = newLocation(); 108 109 IComponentSpecification spec = newSpec(); 110 INamespace namespace = newMock(INamespace.class); 111 112 expect(namespace.containsComponentType("MyComponent")).andReturn(true); 113 114 expect(namespace.getComponentSpecification("MyComponent")).andReturn(spec); 115 116 trainIsDeprecated(spec, false); 117 118 replay(); 119 120 ComponentSpecificationResolverImpl resolver = new ComponentSpecificationResolverImpl(); 121 122 resolver.resolve(cycle, namespace, "MyComponent", l); 123 124 assertSame(spec, resolver.getSpecification()); 125 assertSame(namespace, resolver.getNamespace()); 126 127 verify(); 128 } 129 130 public void test_Deprecated() 131 { 132 IRequestCycle cycle = newCycle(); 133 Location l = newLocation(); 134 135 IComponentSpecification spec = newSpec(); 136 INamespace namespace = newMock(INamespace.class); 137 138 expect(namespace.containsComponentType("MyComponent")).andReturn(true); 139 140 expect(namespace.getComponentSpecification("MyComponent")).andReturn(spec); 141 142 trainIsDeprecated(spec, true); 143 144 Log log = newMock(Log.class); 145 146 log.warn(startsWith("Component 'MyComponent' (")); 147 // at classpath:/org/apache/tapestry/resolver/TestComponentSpecificationResolver, line 1) is deprecated, and will likely 148 // be removed in a later release. Consult its documentation to find a replacement component."); 149 150 replay(); 151 152 ComponentSpecificationResolverImpl resolver = new ComponentSpecificationResolverImpl(); 153 resolver.setLog(log); 154 155 resolver.resolve(cycle, namespace, "MyComponent", l); 156 157 assertSame(spec, resolver.getSpecification()); 158 assertSame(namespace, resolver.getNamespace()); 159 160 verify(); 161 } 162 163 public void test_Found_In_Child_Namespace() 164 { 165 IRequestCycle cycle = newCycle(); 166 Location l = newLocation(); 167 168 IComponentSpecification spec = newSpec(); 169 INamespace namespace = newMock(INamespace.class); 170 INamespace library = newMock(INamespace.class); 171 172 expect(namespace.getChildNamespace("lib")).andReturn(library); 173 174 expect(library.containsComponentType("MyComponent")).andReturn(true); 175 176 expect(library.getComponentSpecification("MyComponent")).andReturn(spec); 177 178 trainIsDeprecated(spec, false); 179 180 replay(); 181 182 ComponentSpecificationResolverImpl resolver = new ComponentSpecificationResolverImpl(); 183 184 resolver.resolve(cycle, namespace, "lib:MyComponent", l); 185 186 assertSame(spec, resolver.getSpecification()); 187 assertSame(library, resolver.getNamespace()); 188 189 verify(); 190 } 191 192 public void test_Search_Found_Relative() 193 { 194 IRequestCycle cycle = newCycle(); 195 Location l = newLocation(); 196 197 IComponentSpecification spec = newSpec(); 198 INamespace namespace = newMock(INamespace.class); 199 200 Log log = newMock(Log.class); 201 202 Resource namespaceLocation = newResource("LibraryStandin.library"); 203 Resource specLocation = namespaceLocation.getRelativeResource("MyComponent.jwc"); 204 205 expect(namespace.containsComponentType("MyComponent")).andReturn(false); 206 207 train(log, ResolverMessages.resolvingComponent("MyComponent", namespace)); 208 209 expect(namespace.getSpecificationLocation()).andReturn(namespaceLocation); 210 211 train(log, ResolverMessages.checkingResource(specLocation)); 212 213 ISpecificationSource source = newSource(specLocation, spec); 214 215 train(log, ResolverMessages.installingComponent("MyComponent", namespace, spec)); 216 217 namespace.installComponentSpecification("MyComponent", spec); 218 219 trainIsDeprecated(spec, false); 220 221 replay(); 222 223 ComponentSpecificationResolverImpl resolver = new ComponentSpecificationResolverImpl(); 224 resolver.setLog(log); 225 resolver.setSpecificationSource(source); 226 227 resolver.resolve(cycle, namespace, "MyComponent", l); 228 229 assertSame(spec, resolver.getSpecification()); 230 assertSame(namespace, resolver.getNamespace()); 231 232 verify(); 233 } 234 235 public void test_Found_In_Framework_Namespace() 236 { 237 IRequestCycle cycle = newCycle(); 238 Location l = newLocation(); 239 240 IComponentSpecification spec = newSpec(); 241 INamespace namespace = newMock(INamespace.class); 242 ISpecificationResolverDelegate delegate = newMock(ISpecificationResolverDelegate.class); 243 244 Log log = newMock(Log.class); 245 INamespace framework = newMock(INamespace.class); 246 247 Resource namespaceLocation = newResource("LibraryStandin.library"); 248 249 expect(namespace.containsComponentType("FrameworkComponent")).andReturn(false); 250 251 train(log, ResolverMessages.resolvingComponent("FrameworkComponent", namespace)); 252 253 expect(namespace.getSpecificationLocation()).andReturn(namespaceLocation); 254 255 train(log, ResolverMessages.checkingResource(namespaceLocation 256 .getRelativeResource("FrameworkComponent.jwc"))); 257 258 expect(namespace.isApplicationNamespace()).andReturn(false); 259 260 expect(delegate.findComponentSpecification(cycle, namespace, "FrameworkComponent")).andReturn(null); 261 262 trainGetPackages(namespace, "org.foo"); 263 264 ClassFinder finder = newClassFinder("org.foo", "FrameworkComponent", null); 265 266 ISpecificationSource source = newSource(framework); 267 268 expect(framework.containsComponentType("FrameworkComponent")).andReturn(true); 269 270 expect(framework.getComponentSpecification("FrameworkComponent")).andReturn(spec); 271 272 train(log, ResolverMessages 273 .installingComponent("FrameworkComponent", namespace, spec)); 274 namespace.installComponentSpecification("FrameworkComponent", spec); 275 276 trainIsDeprecated(spec, false); 277 278 replay(); 279 280 ComponentSpecificationResolverImpl resolver = new ComponentSpecificationResolverImpl(); 281 resolver.setLog(log); 282 resolver.setSpecificationSource(source); 283 resolver.setClassFinder(finder); 284 resolver.setDelegate(delegate); 285 286 resolver.resolve(cycle, namespace, "FrameworkComponent", l); 287 288 assertSame(spec, resolver.getSpecification()); 289 assertSame(namespace, resolver.getNamespace()); 290 291 verify(); 292 } 293 294 public void test_Provided_By_Delegate() 295 { 296 IRequestCycle cycle = newCycle(); 297 Location l = newLocation(); 298 299 IComponentSpecification spec = newSpec(); 300 INamespace namespace = newMock(INamespace.class); 301 302 Log log = newMock(Log.class); 303 //INamespace framework = newMock(INamespace.class); 304 305 ISpecificationResolverDelegate delegate = newDelegate( 306 cycle, 307 namespace, 308 "DelegateComponent", 309 spec); 310 311 expect(namespace.containsComponentType("DelegateComponent")).andReturn(false); 312 313 train(log, ResolverMessages.resolvingComponent("DelegateComponent", namespace)); 314 315 Resource namespaceLocation = newResource("LibraryStandin.library"); 316 317 expect(namespace.getSpecificationLocation()).andReturn(namespaceLocation); 318 319 train(log, ResolverMessages.checkingResource(namespaceLocation 320 .getRelativeResource("DelegateComponent.jwc"))); 321 322 expect(namespace.isApplicationNamespace()).andReturn(false); 323 324 expect(log.isDebugEnabled()).andReturn(false); 325 326 namespace.installComponentSpecification("DelegateComponent", spec); 327 328 trainIsDeprecated(spec, false); 329 330 replay(); 331 332 ComponentSpecificationResolverImpl resolver = new ComponentSpecificationResolverImpl(); 333 resolver.setLog(log); 334 resolver.setDelegate(delegate); 335 336 resolver.resolve(cycle, namespace, "DelegateComponent", l); 337 338 assertSame(spec, resolver.getSpecification()); 339 assertSame(namespace, resolver.getNamespace()); 340 341 verify(); 342 } 343 344 private void trainGetPackages(INamespace namespace, String packages) 345 { 346 expect(namespace.getPropertyValue("org.apache.tapestry.component-class-packages")) 347 .andReturn(packages); 348 } 349 350 private ClassFinder newClassFinder(String packages, String className, Class result) 351 { 352 ClassFinder finder = newMock(ClassFinder.class); 353 354 expect(finder.findClass(packages, className)).andReturn(result); 355 356 return finder; 357 } 358 359 public void test_Not_Found() 360 { 361 IRequestCycle cycle = newCycle(); 362 Location l = newLocation(); 363 364 Log log = newMock(Log.class); 365 366 INamespace namespace = newMock(INamespace.class); 367 INamespace framework = newMock(INamespace.class); 368 369 ISpecificationResolverDelegate delegate = newDelegate( 370 cycle, 371 namespace, 372 "NotFoundComponent", 373 null); 374 375 Resource namespaceLocation = newResource("LibraryStandin.library"); 376 377 expect(namespace.containsComponentType("NotFoundComponent")).andReturn(false); 378 379 train(log, ResolverMessages.resolvingComponent("NotFoundComponent", namespace)); 380 381 expect(namespace.getSpecificationLocation()).andReturn(namespaceLocation); 382 383 train(log, ResolverMessages.checkingResource(namespaceLocation 384 .getRelativeResource("NotFoundComponent.jwc"))); 385 386 expect(namespace.isApplicationNamespace()).andReturn(false); 387 388 ISpecificationSource source = newSource(framework); 389 390 expect(framework.containsComponentType("NotFoundComponent")).andReturn(false); 391 392 ClassFinder finder = newClassFinder("org.foo", "NotFoundComponent", null); 393 trainGetPackages(namespace, "org.foo"); 394 395 replay(); 396 397 ComponentSpecificationResolverImpl resolver = new ComponentSpecificationResolverImpl(); 398 resolver.setLog(log); 399 resolver.setSpecificationSource(source); 400 resolver.setDelegate(delegate); 401 resolver.setClassFinder(finder); 402 403 try 404 { 405 resolver.resolve(cycle, namespace, "NotFoundComponent", l); 406 unreachable(); 407 } 408 catch (ApplicationRuntimeException ex) 409 { 410 assertEquals( 411 "Component 'NotFoundComponent' not found in EasyMock for interface org.apache.tapestry.INamespace.", 412 ex.getMessage()); 413 assertSame(l, ex.getLocation()); 414 } 415 416 verify(); 417 } 418 419 /** 420 * Test for checking inside the WEB-INF/app folder (app is the application id, i.e., the servlet 421 * name). 422 */ 423 424 public void test_Found_In_App_Folder() 425 { 426 IRequestCycle cycle = newCycle(); 427 Location l = newLocation(); 428 429 IComponentSpecification spec = newSpec(); 430 Log log = newLog(); 431 432 Resource contextRoot = newResource("context/"); 433 434 INamespace namespace = newMock(INamespace.class); 435 436 Resource namespaceLocation = newResource("LibraryStandin.library"); 437 Resource specLocation = contextRoot.getRelativeResource("WEB-INF/myapp/MyAppComponent.jwc"); 438 439 expect(namespace.containsComponentType("MyAppComponent")).andReturn(false); 440 441 train(log, ResolverMessages.resolvingComponent("MyAppComponent", namespace)); 442 443 expect(namespace.getSpecificationLocation()).andReturn(namespaceLocation); 444 445 train(log, ResolverMessages.checkingResource(namespaceLocation 446 .getRelativeResource("MyAppComponent.jwc"))); 447 448 expect(namespace.isApplicationNamespace()).andReturn(true); 449 450 train(log, ResolverMessages.checkingResource(specLocation)); 451 452 ISpecificationSource source = newSource(specLocation, spec); 453 454 train(log, ResolverMessages.installingComponent("MyAppComponent", namespace, spec)); 455 456 namespace.installComponentSpecification("MyAppComponent", spec); 457 458 trainIsDeprecated(spec, false); 459 460 replay(); 461 462 ComponentSpecificationResolverImpl resolver = new ComponentSpecificationResolverImpl(); 463 resolver.setLog(log); 464 resolver.setSpecificationSource(source); 465 resolver.setContextRoot(contextRoot); 466 resolver.setApplicationId("myapp"); 467 resolver.initializeService(); 468 469 resolver.resolve(cycle, namespace, "MyAppComponent", l); 470 471 assertSame(spec, resolver.getSpecification()); 472 assertSame(namespace, resolver.getNamespace()); 473 474 verify(); 475 } 476 477 public void test_Found_In_Web_Inf_Folder() 478 { 479 IRequestCycle cycle = newCycle(); 480 Location l = newLocation(); 481 482 IComponentSpecification spec = newSpec(); 483 Log log = newLog(); 484 485 Resource contextRoot = newResource("context/"); 486 487 INamespace namespace = newMock(INamespace.class); 488 489 Resource namespaceLocation = newResource("LibraryStandin.library"); 490 Resource specLocation = contextRoot.getRelativeResource("WEB-INF/MyWebInfComponent.jwc"); 491 492 expect(namespace.containsComponentType("MyWebInfComponent")).andReturn(false); 493 494 train(log, ResolverMessages.resolvingComponent("MyWebInfComponent", namespace)); 495 496 expect(namespace.getSpecificationLocation()).andReturn(namespaceLocation); 497 498 train(log, ResolverMessages.checkingResource(namespaceLocation 499 .getRelativeResource("MyWebInfComponent.jwc"))); 500 501 expect(namespace.isApplicationNamespace()).andReturn(true); 502 503 train(log, ResolverMessages.checkingResource(contextRoot 504 .getRelativeResource("WEB-INF/myapp/MyWebInfComponent.jwc"))); 505 train(log, ResolverMessages.checkingResource(specLocation)); 506 507 ISpecificationSource source = newSource(specLocation, spec); 508 509 train(log, ResolverMessages.installingComponent("MyWebInfComponent", namespace, spec)); 510 511 namespace.installComponentSpecification("MyWebInfComponent", spec); 512 513 trainIsDeprecated(spec, false); 514 515 replay(); 516 517 ComponentSpecificationResolverImpl resolver = new ComponentSpecificationResolverImpl(); 518 resolver.setLog(log); 519 resolver.setSpecificationSource(source); 520 resolver.setContextRoot(contextRoot); 521 resolver.setApplicationId("myapp"); 522 resolver.initializeService(); 523 524 resolver.resolve(cycle, namespace, "MyWebInfComponent", l); 525 526 assertSame(spec, resolver.getSpecification()); 527 assertSame(namespace, resolver.getNamespace()); 528 529 verify(); 530 } 531 532 public void test_Found_In_Context_Root() 533 { 534 IRequestCycle cycle = newCycle(); 535 Location l = newLocation(); 536 537 IComponentSpecification spec = newSpec(); 538 Log log = newLog(); 539 540 Resource contextRoot = newResource("context/"); 541 542 INamespace namespace = newMock(INamespace.class); 543 544 Resource namespaceLocation = newResource("LibraryStandin.library"); 545 Resource specLocation = contextRoot.getRelativeResource("ContextRootComponent.jwc"); 546 547 548 549 expect(namespace.containsComponentType("ContextRootComponent")).andReturn(false); 550 551 train(log, ResolverMessages.resolvingComponent("ContextRootComponent", namespace)); 552 553 expect(namespace.getSpecificationLocation()).andReturn(namespaceLocation); 554 555 train(log, ResolverMessages.checkingResource(namespaceLocation 556 .getRelativeResource("ContextRootComponent.jwc"))); 557 558 expect(namespace.isApplicationNamespace()).andReturn(true); 559 560 train(log, ResolverMessages.checkingResource(contextRoot 561 .getRelativeResource("WEB-INF/myapp/ContextRootComponent.jwc"))); 562 train(log, ResolverMessages.checkingResource(contextRoot 563 .getRelativeResource("WEB-INF/ContextRootComponent.jwc"))); 564 565 train(log, ResolverMessages.checkingResource(specLocation)); 566 567 ISpecificationSource source = newSource(specLocation, spec); 568 569 train(log, ResolverMessages.installingComponent( 570 "ContextRootComponent", 571 namespace, 572 spec)); 573 574 namespace.installComponentSpecification("ContextRootComponent", spec); 575 576 trainIsDeprecated(spec, false); 577 578 replay(); 579 580 ComponentSpecificationResolverImpl resolver = new ComponentSpecificationResolverImpl(); 581 resolver.setLog(log); 582 resolver.setSpecificationSource(source); 583 resolver.setContextRoot(contextRoot); 584 resolver.setApplicationId("myapp"); 585 resolver.initializeService(); 586 587 resolver.resolve(cycle, namespace, "ContextRootComponent", l); 588 589 assertSame(spec, resolver.getSpecification()); 590 assertSame(namespace, resolver.getNamespace()); 591 592 verify(); 593 } 594 595 public void test_Found_Component_Class() 596 { 597 INamespace namespace = newMock(INamespace.class); 598 599 trainGetPackages(namespace, "org.foo"); 600 ClassFinder finder = newClassFinder("org.foo", "folder.MyComponent", BaseComponent.class); 601 602 Resource componentResource = newResource(); 603 Resource namespaceResource = newResource("folder/MyComponent.jwc", componentResource); 604 605 trainGetResource(namespace, namespaceResource); 606 607 URL componentUrl = this.getClass().getResource("MyComponent.jwc"); 608 expect(componentResource.getResourceURL()).andReturn(componentUrl); 609 610 replay(); 611 612 ComponentSpecificationResolverImpl resolver = new ComponentSpecificationResolverImpl(); 613 resolver.setClassFinder(finder); 614 615 IComponentSpecification spec = resolver.searchForComponentClass(namespace, "folder/MyComponent"); 616 617 assertEquals(BaseComponent.class.getName(), spec.getComponentClassName()); 618 assertSame(componentResource, spec.getSpecificationLocation()); 619 assertSame(componentResource, spec.getLocation().getResource()); 620 621 verify(); 622 } 623 624 private void trainGetResource(INamespace namespace, Resource resource) 625 { 626 expect(namespace.getSpecificationLocation()).andReturn(resource); 627 } 628 629 private Resource newResource(String relativePath, Resource relativeResource) 630 { 631 Resource resource = newMock(Resource.class); 632 checkOrder(resource, false); 633 634 expect(resource.getRelativeResource(relativePath)).andReturn(relativeResource); 635 636 return resource; 637 } 638 }