1 22 package org.jboss.injection; 23 24 import org.jboss.ejb3.Container; 25 import org.jboss.logging.Logger; 26 import org.jboss.metamodel.descriptor.EnvEntry; 27 import org.jboss.metamodel.descriptor.EnvironmentRefGroup; 28 import org.jboss.metamodel.descriptor.MessageDestinationRef; 29 import org.jboss.metamodel.descriptor.ResourceEnvRef; 30 import org.jboss.metamodel.descriptor.ResourceRef; 31 import org.jboss.reflect.plugins.ValueConvertor; 32 33 import javax.annotation.Resource; 34 import javax.annotation.Resources; 35 import javax.ejb.EJBContext ; 36 import javax.ejb.TimerService ; 37 import javax.transaction.UserTransaction ; 38 import javax.xml.ws.WebServiceContext; 39 40 import java.lang.reflect.AccessibleObject ; 41 import java.lang.reflect.Field ; 42 import java.lang.reflect.Method ; 43 import java.util.Collection ; 44 import java.util.Map ; 45 import java.net.URL ; 46 import java.net.MalformedURLException ; 47 48 52 public class ResourceHandler implements InjectionHandler 53 { 54 private static final Logger log = Logger.getLogger(ResourceHandler.class); 55 56 private static void loadEnvEntry(InjectionContainer container, Collection <EnvEntry> envEntries) 57 { 58 for (EnvEntry envEntry : envEntries) 59 { 60 String encName = "env/" + envEntry.getEnvEntryName(); 61 InjectionUtil.injectionTarget(encName, envEntry, container, container.getEncInjections()); 62 if (container.getEncInjectors().containsKey(encName)) continue; 63 log.trace("adding env-entry injector " + encName); 64 container.getEncInjectors().put(encName, new EnvEntryEncInjector(encName, envEntry.getEnvEntryType(), envEntry.getEnvEntryValue())); 65 } 66 } 67 68 private static void loadXmlResourceRefs(InjectionContainer container, Collection <ResourceRef> refs) 69 { 70 for (ResourceRef envRef : refs) 71 { 72 String encName = "env/" + envRef.getResRefName(); 73 if (container.getEncInjectors().containsKey(encName)) continue; 74 if (envRef.getMappedName() == null || envRef.getMappedName().equals("")) 75 { 76 if (envRef.getResUrl() != null) 77 { 78 try 79 { 80 container.getEncInjectors().put(encName, new ValueEncInjector(encName, new URL (envRef.getResUrl().trim()), "<resource-ref>")); 81 } 82 catch (MalformedURLException e) 83 { 84 throw new RuntimeException (e); 85 } 86 } 87 else 88 { 89 throw new RuntimeException ("mapped-name is required for " + envRef.getResRefName() + " of deployment " + container.getIdentifier()); 90 } 91 } 92 else 93 { 94 container.getEncInjectors().put(encName, new LinkRefEncInjector(encName, envRef.getMappedName(), "<resource-ref>")); 95 } 96 InjectionUtil.injectionTarget(encName, envRef, container, container.getEncInjections()); 97 } 98 } 99 100 private static void loadXmlResourceEnvRefs(InjectionContainer container, Collection <ResourceEnvRef> refs) 101 { 102 for (ResourceEnvRef envRef : refs) 103 { 104 String encName = "env/" + envRef.getResRefName(); 105 if (container.getEncInjectors().containsKey(encName)) continue; 106 if (envRef.getMappedName() == null || envRef.getMappedName().equals("")) 107 { 108 throw new RuntimeException ("mapped-name is required for " + envRef.getResRefName() + " of deployment " + container.getIdentifier()); 109 } 110 container.getEncInjectors().put(encName, new LinkRefEncInjector(encName, envRef.getMappedName(), "<resource-ref>")); 111 InjectionUtil.injectionTarget(encName, envRef, container, container.getEncInjections()); 112 } 113 } 114 115 private static void loadXmlMessageDestinationRefs(InjectionContainer container, Collection <MessageDestinationRef> refs) 116 { 117 for (MessageDestinationRef envRef : refs) 118 { 119 String encName = "env/" + envRef.getMessageDestinationRefName(); 120 if (container.getEncInjectors().containsKey(encName)) continue; 121 if (envRef.getMappedName() == null || envRef.getMappedName().equals("")) 122 { 123 String link = envRef.getMessageDestinationLink(); 125 if( link != null ) 126 { 127 } 129 throw new RuntimeException ("mapped-name is required for " + envRef.getMessageDestinationRefName() + " of deployment " + container.getIdentifier()); 130 } 131 container.getEncInjectors().put(encName, new LinkRefEncInjector(encName, envRef.getMappedName(), "<message-destination-ref>")); 132 InjectionUtil.injectionTarget(encName, envRef, container, container.getEncInjections()); 133 } 134 } 135 136 public void loadXml(EnvironmentRefGroup xml, InjectionContainer container) 137 { 138 if (xml == null) return; 139 if (xml.getMessageDestinationRefs() != null) loadXmlMessageDestinationRefs(container, xml.getMessageDestinationRefs()); 140 if (xml.getResourceEnvRefs() != null) loadXmlResourceEnvRefs(container, xml.getResourceEnvRefs()); 141 if (xml.getResourceRefs() != null) loadXmlResourceRefs(container, xml.getResourceRefs()); 142 if (xml.getEnvEntries() != null) loadEnvEntry(container, xml.getEnvEntries()); 143 } 144 145 public void handleClassAnnotations(Class clazz, InjectionContainer container) 146 { 147 Resources resources = container.getAnnotation(Resources.class, clazz); 148 if (resources != null) 149 { 150 for (Resource ref : resources.value()) 151 { 152 handleClassAnnotation(ref, container, clazz); 153 } 154 } 155 Resource res = container.getAnnotation(Resource.class, clazz); 156 if (res != null) handleClassAnnotation(res, container, clazz); 157 } 158 159 private void handleClassAnnotation(Resource ref, InjectionContainer container, Class clazz) 160 { 161 String encName = ref.name(); 162 if (encName == null || encName.equals("")) 163 { 164 throw new RuntimeException ("JBoss requires name() for class level @Resource"); 165 } 166 encName = "env/" + ref.name(); 167 if (container.getEncInjectors().containsKey(encName)) return; 168 169 String mappedName = ref.mappedName(); 170 if (mappedName == null || mappedName.equals("")) 171 { 172 throw new RuntimeException ("You did not specify a @Resource.mappedName() for name: " 173 +ref.name()+", class: " + clazz.getName() + " and there is no binding for that enc name in XML"); 174 } 175 176 if (ref.type() == URL .class) 177 { 178 try 180 { 181 URL url = new URL (ref.mappedName().trim()); 182 container.getEncInjectors().put(encName, new ValueEncInjector(encName, url, "@Resource")); 183 } 184 catch (MalformedURLException e) 185 { 186 throw new RuntimeException (e); 187 } 188 } 189 else 190 { 191 container.getEncInjectors().put(encName, new LinkRefEncInjector(encName, ref.mappedName(), "@Resource")); 192 } 193 } 194 195 public void handleMethodAnnotations(Method method, InjectionContainer container, Map <AccessibleObject , Injector> injectors) 196 { 197 Resource ref = method.getAnnotation(Resource.class); 198 if (ref == null) return; 199 200 String encName = ref.name(); 201 if (encName == null || encName.equals("")) 202 { 203 encName = InjectionUtil.getEncName(method); 204 } 205 else 206 { 207 encName = "env/" + encName; 208 } 209 210 method.setAccessible(true); 211 212 if (!method.getName().startsWith("set")) 213 throw new RuntimeException ("@Resource can only be used with a set method: " + method); 214 if (method.getParameterTypes().length != 1) 215 throw new RuntimeException ("@Resource can only be used with a set method of one parameter: " + method); 216 217 Class type = method.getParameterTypes()[0]; 218 if (!ref.type().equals(Object .class)) 219 { 220 type = ref.type(); 221 } 222 if (type.equals(UserTransaction .class)) 223 { 224 injectors.put(method, new UserTransactionMethodInjector(method, container)); 225 } 226 else if (type.equals(TimerService .class)) 227 { 228 injectors.put(method, new TimerServiceMethodInjector(method, (Container) container)); } 230 else if (EJBContext .class.isAssignableFrom(type)) 231 { 232 injectors.put(method, new EJBContextMethodInjector(method)); 233 } 234 else if (type.equals(WebServiceContext.class)) 235 { 236 } 238 else if (type.equals(String .class) 239 || type.equals(Character .class) 240 || type.equals(Byte .class) 241 || type.equals(Short .class) 242 || type.equals(Integer .class) 243 || type.equals(Long .class) 244 || type.equals(Boolean .class) 245 || type.equals(Double .class) 246 || type.equals(Float .class) 247 || type.isPrimitive() 248 ) 249 { 250 251 if (container.getEncInjectors().containsKey(encName)) 253 { 254 injectors.put(method, new JndiMethodInjector(method, encName, container.getEnc())); 255 } 256 else if (ref.mappedName() != null && ref.mappedName().length() > 0) 257 { 258 String s = ref.mappedName().trim(); 260 try 261 { 262 Object value = ValueConvertor.convertValue(type, s); 263 container.getEncInjectors().put(encName, new ValueEncInjector(encName, value, "@Resource")); 264 injectors.put(method, new JndiMethodInjector(method, encName, container.getEnc())); 265 } 266 catch(Throwable t) 267 { 268 throw new RuntimeException ("Failed to convert: "+ref.mappedName()+" to type:"+type, t); 269 } 270 } 271 } 272 else 273 { 274 if (!container.getEncInjectors().containsKey(encName)) 275 { 276 String mappedName = ref.mappedName(); 277 if (mappedName == null || mappedName.equals("")) 278 { 279 throw new RuntimeException ("You did not specify a @Resource.mappedName() on " + method + " and there is no binding for that enc name in XML"); 280 } 281 container.getEncInjectors().put(encName, new LinkRefEncInjector(encName, ref.mappedName(), "@Resource")); 282 } 283 injectors.put(method, new JndiMethodInjector(method, encName, container.getEnc())); 284 } 285 } 286 public void handleFieldAnnotations(Field field, InjectionContainer container, Map <AccessibleObject , Injector> injectors) 287 { 288 Resource ref = field.getAnnotation(Resource.class); 289 if (ref == null) return; 290 291 log.trace("field " + field + " has @Resource"); 292 293 String encName = ref.name(); 294 if (encName == null || encName.equals("")) 295 { 296 encName = InjectionUtil.getEncName(field); 297 } 298 else 299 { 300 encName = "env/" + encName; 301 } 302 303 field.setAccessible(true); 304 305 Class type = field.getType(); 306 if (!ref.type().equals(Object .class)) 307 { 308 type = ref.type(); 309 } 310 if (type.equals(UserTransaction .class)) 311 { 312 injectors.put(field, new UserTransactionFieldInjector(field, container)); 313 } 314 else if (type.equals(TimerService .class)) 315 { 316 injectors.put(field, new TimerServiceFieldInjector(field, (Container) container)); } 318 else if (EJBContext .class.isAssignableFrom(type)) 319 { 320 injectors.put(field, new EJBContextFieldInjector(field)); 321 } 322 else if (type.equals(WebServiceContext.class)) 323 { 324 } 326 else if (type.equals(String .class) 327 || type.equals(Character .class) 328 || type.equals(Byte .class) 329 || type.equals(Short .class) 330 || type.equals(Integer .class) 331 || type.equals(Long .class) 332 || type.equals(Boolean .class) 333 || type.equals(Double .class) 334 || type.equals(Float .class) 335 || type.isPrimitive() 336 ) 337 { 338 if (container.getEncInjectors().containsKey(encName)) 340 { 341 injectors.put(field, new JndiFieldInjector(field, encName, container.getEnc())); 342 } 343 else if (ref.mappedName() != null && ref.mappedName().length() > 0) 344 { 345 String s = ref.mappedName().trim(); 347 try 348 { 349 Object value = ValueConvertor.convertValue(type, s); 350 container.getEncInjectors().put(encName, new ValueEncInjector(encName, value, "@Resource")); 351 injectors.put(field, new JndiFieldInjector(field, encName, container.getEnc())); 352 } 353 catch(Throwable t) 354 { 355 throw new RuntimeException ("Failed to convert: "+ref.mappedName()+" to type:"+type, t); 356 } 357 } 358 else 359 { 360 log.warn("Not injecting " + field.getName() + ", no matching enc injector " + encName + " found"); 361 } 362 } 363 else 364 { 365 if (!container.getEncInjectors().containsKey(encName)) 366 { 367 String mappedName = ref.mappedName(); 368 if (mappedName == null || mappedName.equals("")) 369 { 370 throw new RuntimeException ("You did not specify a @Resource.mappedName() on " + field + " and there is no binding for enc name " + encName + " in XML"); 371 } 372 container.getEncInjectors().put(encName, new LinkRefEncInjector(encName, ref.mappedName(), "@Resource")); 373 } 374 injectors.put(field, new JndiFieldInjector(field, encName, container.getEnc())); 375 } 376 } 377 378 379 } 380 | Popular Tags |