001 // Copyright 2004, 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.services.impl; 016 017 import static org.easymock.EasyMock.checkOrder; 018 import static org.easymock.EasyMock.expect; 019 020 import java.util.ArrayList; 021 import java.util.Collections; 022 import java.util.List; 023 024 import org.apache.hivemind.ApplicationRuntimeException; 025 import org.apache.hivemind.ErrorLog; 026 import org.apache.hivemind.Location; 027 import org.apache.tapestry.BaseComponentTestCase; 028 import org.apache.tapestry.IRequestCycle; 029 import org.apache.tapestry.engine.IEngineService; 030 import org.testng.annotations.Test; 031 032 /** 033 * Tests for {@link org.apache.tapestry.services.impl.ServiceMapImpl}. 034 * 035 * @author Howard Lewis Ship 036 * @since 4.0 037 */ 038 @Test 039 public class TestServiceMap extends BaseComponentTestCase 040 { 041 private IEngineService newService(String name) 042 { 043 IEngineService service = newMock(IEngineService.class); 044 checkOrder(service, false); 045 046 expect(service.getName()).andReturn(name); 047 048 return service; 049 } 050 051 private IEngineService newService() 052 { 053 return newMock(IEngineService.class); 054 } 055 056 private EngineServiceContribution constructService(String name, IEngineService service) 057 { 058 EngineServiceContribution result = new EngineServiceContribution(); 059 result.setName(name); 060 result.setService(service); 061 062 return result; 063 } 064 065 /** 066 * Gets an application-defined and factory-defined service where there are no naming conflicts. 067 * Because ServiceMap now returns proxies, we have to do a little extra indirection to ensure 068 * that we get what's expected. 069 */ 070 public void testGetNoConflict() throws Exception 071 { 072 IRequestCycle cycle1 = newCycle(); 073 IRequestCycle cycle2 = newCycle(); 074 075 IEngineService factory = newService("factory"); 076 IEngineService application = newService("application"); 077 078 EngineServiceContribution factoryc = constructService("factory", factory); 079 EngineServiceContribution applicationc = constructService("application", application); 080 081 factory.service(cycle1); 082 application.service(cycle2); 083 084 replay(); 085 086 ServiceMapImpl m = new ServiceMapImpl(); 087 088 m.setFactoryServices(Collections.singletonList(factoryc)); 089 m.setApplicationServices(Collections.singletonList(applicationc)); 090 091 m.initializeService(); 092 093 assertEquals(true, m.isValid("factory")); 094 095 m.getService("factory").service(cycle1); 096 097 assertEquals(true, m.isValid("application")); 098 099 m.getService("application").service(cycle2); 100 101 verify(); 102 } 103 104 public void testNameMismatch() throws Exception 105 { 106 IRequestCycle cycle = newCycle(); 107 Location l = fabricateLocation(1289); 108 109 IEngineService service = newService("actual-name"); 110 111 EngineServiceContribution contribution = constructService("expected-name", service); 112 contribution.setLocation(l); 113 114 replay(); 115 116 ServiceMapImpl m = new ServiceMapImpl(); 117 118 m.setFactoryServices(Collections.singletonList(contribution)); 119 m.setApplicationServices(Collections.EMPTY_LIST); 120 121 m.initializeService(); 122 123 IEngineService proxy = m.getService("expected-name"); 124 125 try 126 { 127 proxy.service(cycle); 128 unreachable(); 129 } 130 catch (ApplicationRuntimeException ex) 131 { 132 assertEquals( 133 "Engine service EasyMock for interface org.apache.tapestry.engine.IEngineService is mapped to name 'expected-name' but indicates a name of 'actual-name'.", 134 ex.getMessage()); 135 assertSame(l, ex.getLocation()); 136 } 137 138 verify(); 139 } 140 141 public void testGetServiceRepeated() 142 { 143 IEngineService application = newService(); 144 EngineServiceContribution applicationc = constructService("application", application); 145 146 replay(); 147 148 ServiceMapImpl m = new ServiceMapImpl(); 149 150 m.setFactoryServices(Collections.EMPTY_LIST); 151 m.setApplicationServices(Collections.singletonList(applicationc)); 152 153 m.initializeService(); 154 155 IEngineService service = m.getService("application"); 156 assertSame(service, m.getService("application")); 157 158 verify(); 159 } 160 161 public void testApplicationOverridesFactory() throws Exception 162 { 163 IRequestCycle cycle = newCycle(); 164 IEngineService factory = newService(); 165 IEngineService application = newService("override"); 166 167 EngineServiceContribution factoryc = constructService("override", factory); 168 EngineServiceContribution applicationc = constructService("override", application); 169 170 application.service(cycle); 171 172 replay(); 173 174 ServiceMapImpl m = new ServiceMapImpl(); 175 176 m.setFactoryServices(Collections.singletonList(factoryc)); 177 m.setApplicationServices(Collections.singletonList(applicationc)); 178 179 m.initializeService(); 180 181 m.getService("override").service(cycle); 182 183 verify(); 184 } 185 186 public void testUnknownService() 187 { 188 ServiceMapImpl m = new ServiceMapImpl(); 189 190 m.setFactoryServices(Collections.EMPTY_LIST); 191 m.setApplicationServices(Collections.EMPTY_LIST); 192 193 m.initializeService(); 194 195 assertEquals(false, m.isValid("missing")); 196 197 try 198 { 199 m.getService("missing"); 200 unreachable(); 201 } 202 catch (ApplicationRuntimeException ex) 203 { 204 assertEquals(ImplMessages.noSuchService("missing"), ex.getMessage()); 205 } 206 207 try 208 { 209 m.resolveEngineService("resolve-missing"); 210 unreachable(); 211 } 212 catch (ApplicationRuntimeException ex) 213 { 214 assertEquals(ImplMessages.noSuchService("resolve-missing"), ex.getMessage()); 215 216 } 217 } 218 219 public void testDuplicateName() throws Exception 220 { 221 Location l = fabricateLocation(37); 222 IRequestCycle cycle = newCycle(); 223 224 IEngineService first = newService("duplicate"); 225 IEngineService second = newService(); 226 227 EngineServiceContribution firstc = constructService("duplicate", first); 228 firstc.setLocation(l); 229 230 EngineServiceContribution secondc = constructService("duplicate", second); 231 232 List list = new ArrayList(); 233 list.add(firstc); 234 list.add(secondc); 235 236 ErrorLog log = newMock(ErrorLog.class); 237 238 first.service(cycle); 239 240 log.error(ImplMessages.dupeService("duplicate", firstc), l, null); 241 242 replay(); 243 244 ServiceMapImpl m = new ServiceMapImpl(); 245 246 m.setFactoryServices(list); 247 m.setApplicationServices(Collections.EMPTY_LIST); 248 m.setErrorLog(log); 249 250 m.initializeService(); 251 252 m.getService("duplicate").service(cycle); 253 254 verify(); 255 } 256 }