Search in sources :

Example 1 with Injection

use of org.eclipse.jetty.plus.annotation.Injection in project jetty.project by eclipse.

the class TestResourceAnnotations method testResourceAnnotations.

@Test
public void testResourceAnnotations() throws Exception {
    new org.eclipse.jetty.plus.jndi.EnvEntry(server, "resA", objA, false);
    new org.eclipse.jetty.plus.jndi.EnvEntry(server, "resB", objB, false);
    AnnotationIntrospector parser = new AnnotationIntrospector();
    ResourceAnnotationHandler handler = new ResourceAnnotationHandler(wac);
    parser.registerHandler(handler);
    parser.introspect(ResourceA.class);
    parser.introspect(ResourceB.class);
    //processing classA should give us these jndi name bindings:
    // java:comp/env/myf
    // java:comp/env/org.eclipse.jetty.annotations.resources.ResourceA/g
    // java:comp/env/mye
    // java:comp/env/org.eclipse.jetty.annotations.resources.ResourceA/h
    // java:comp/env/resA
    // java:comp/env/org.eclipse.jetty.annotations.resources.ResourceB/f
    // java:comp/env/org.eclipse.jetty.annotations.resources.ResourceA/n
    //
    assertEquals(objB, env.lookup("myf"));
    assertEquals(objA, env.lookup("mye"));
    assertEquals(objA, env.lookup("resA"));
    assertEquals(objA, env.lookup("org.eclipse.jetty.annotations.resources.ResourceA/g"));
    assertEquals(objA, env.lookup("org.eclipse.jetty.annotations.resources.ResourceA/h"));
    assertEquals(objB, env.lookup("org.eclipse.jetty.annotations.resources.ResourceB/f"));
    assertEquals(objB, env.lookup("org.eclipse.jetty.annotations.resources.ResourceA/n"));
    //we should have Injections
    assertNotNull(injections);
    List<Injection> resBInjections = injections.getInjections(ResourceB.class.getCanonicalName());
    assertNotNull(resBInjections);
    //only 1 field injection because the other has no Resource mapping
    assertEquals(1, resBInjections.size());
    Injection fi = resBInjections.get(0);
    assertEquals("f", fi.getTarget().getName());
    //3 method injections on class ResourceA, 4 field injections
    List<Injection> resAInjections = injections.getInjections(ResourceA.class.getCanonicalName());
    assertNotNull(resAInjections);
    assertEquals(7, resAInjections.size());
    int fieldCount = 0;
    int methodCount = 0;
    for (Injection x : resAInjections) {
        if (x.isField())
            fieldCount++;
        else
            methodCount++;
    }
    assertEquals(4, fieldCount);
    assertEquals(3, methodCount);
    //test injection
    ResourceB binst = new ResourceB();
    injections.inject(binst);
    //check injected values
    Field f = ResourceB.class.getDeclaredField("f");
    f.setAccessible(true);
    assertEquals(objB, f.get(binst));
    //@Resource(mappedName="resA") //test the default naming scheme but using a mapped name from the environment
    f = ResourceA.class.getDeclaredField("g");
    f.setAccessible(true);
    assertEquals(objA, f.get(binst));
    //@Resource(name="resA") //test using the given name as the name from the environment
    f = ResourceA.class.getDeclaredField("j");
    f.setAccessible(true);
    assertEquals(objA, f.get(binst));
    //@Resource(mappedName="resB") //test using the default name on an inherited field
    f = ResourceA.class.getDeclaredField("n");
    f.setAccessible(true);
    assertEquals(objB, f.get(binst));
}
Also used : Field(java.lang.reflect.Field) AnnotationIntrospector(org.eclipse.jetty.annotations.AnnotationIntrospector) ResourceAnnotationHandler(org.eclipse.jetty.annotations.ResourceAnnotationHandler) Injection(org.eclipse.jetty.plus.annotation.Injection) Test(org.junit.Test)

Example 2 with Injection

use of org.eclipse.jetty.plus.annotation.Injection in project jetty.project by eclipse.

the class ResourceAnnotationHandler method handleMethod.

/**
     * Process a Resource annotation on a Method.
     * <p>
     * This will generate a JNDI entry, and an Injection to be
     * processed when an instance of the class is created.
     * 
     * @param clazz the class to process 
     * @param method the method to process
     */
public void handleMethod(Class<?> clazz, Method method) {
    Resource resource = (Resource) method.getAnnotation(Resource.class);
    if (resource != null) {
        //JavaEE Spec 5.2.3: Method cannot be static
        if (Modifier.isStatic(method.getModifiers())) {
            LOG.warn("Skipping Resource annotation on " + clazz.getName() + "." + method.getName() + ": cannot be static");
            return;
        }
        // only 1 parameter
        if (!method.getName().startsWith("set")) {
            LOG.warn("Skipping Resource annotation on " + clazz.getName() + "." + method.getName() + ": invalid java bean, does not start with 'set'");
            return;
        }
        if (method.getParameterCount() != 1) {
            LOG.warn("Skipping Resource annotation on " + clazz.getName() + "." + method.getName() + ": invalid java bean, not single argument to method");
            return;
        }
        if (Void.TYPE != method.getReturnType()) {
            LOG.warn("Skipping Resource annotation on " + clazz.getName() + "." + method.getName() + ": invalid java bean, not void");
            return;
        }
        //default name is the javabean property name
        String name = method.getName().substring(3);
        name = name.substring(0, 1).toLowerCase(Locale.ENGLISH) + name.substring(1);
        name = clazz.getCanonicalName() + "/" + name;
        name = (resource.name() != null && !resource.name().trim().equals("") ? resource.name() : name);
        String mappedName = (resource.mappedName() != null && !resource.mappedName().trim().equals("") ? resource.mappedName() : null);
        Class<?> paramType = method.getParameterTypes()[0];
        Class<?> resourceType = resource.type();
        //Servlet Spec 3.0 p. 76
        //If a descriptor has specified at least 1 injection target for this
        //resource, then it overrides this annotation
        MetaData metaData = _context.getMetaData();
        if (metaData.getOriginDescriptor("resource-ref." + name + ".injection") != null) {
            //it overrides this annotation
            return;
        }
        //check if an injection has already been setup for this target by web.xml
        InjectionCollection injections = (InjectionCollection) _context.getAttribute(InjectionCollection.INJECTION_COLLECTION);
        if (injections == null) {
            injections = new InjectionCollection();
            _context.setAttribute(InjectionCollection.INJECTION_COLLECTION, injections);
        }
        Injection injection = injections.getInjection(name, clazz, method, paramType);
        if (injection == null) {
            try {
                //try binding name to environment
                //try the webapp's environment first
                boolean bound = org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_context, name, mappedName);
                //try the server's environment
                if (!bound)
                    bound = org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_context.getServer(), name, mappedName);
                //try the jvm's environment
                if (!bound)
                    bound = org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(null, name, mappedName);
                //NamingEntry, just a value bound in java:comp/env
                if (!bound) {
                    try {
                        InitialContext ic = new InitialContext();
                        String nameInEnvironment = (mappedName != null ? mappedName : name);
                        ic.lookup("java:comp/env/" + nameInEnvironment);
                        bound = true;
                    } catch (NameNotFoundException e) {
                        bound = false;
                    }
                }
                if (bound) {
                    LOG.debug("Bound " + (mappedName == null ? name : mappedName) + " as " + name);
                    //   Make the Injection for it
                    injection = new Injection();
                    injection.setTarget(clazz, method, paramType, resourceType);
                    injection.setJndiName(name);
                    injection.setMappingName(mappedName);
                    injections.add(injection);
                    //TODO - an @Resource is equivalent to a resource-ref, resource-env-ref, message-destination
                    metaData.setOrigin("resource-ref." + name + ".injection", resource, clazz);
                } else if (!isEnvEntryType(paramType)) {
                    // JavaEE Spec. sec 5.4.1.3
                    throw new IllegalStateException("No resource at " + (mappedName == null ? name : mappedName));
                }
            } catch (NamingException e) {
                // JavaEE Spec. sec 5.4.1.3
                if (!isEnvEntryType(paramType))
                    throw new IllegalStateException(e);
            }
        }
    }
}
Also used : InjectionCollection(org.eclipse.jetty.plus.annotation.InjectionCollection) NameNotFoundException(javax.naming.NameNotFoundException) MetaData(org.eclipse.jetty.webapp.MetaData) Resource(javax.annotation.Resource) NamingException(javax.naming.NamingException) Injection(org.eclipse.jetty.plus.annotation.Injection) InitialContext(javax.naming.InitialContext)

Example 3 with Injection

use of org.eclipse.jetty.plus.annotation.Injection in project jetty.project by eclipse.

the class ResourceAnnotationHandler method handleField.

public void handleField(Class<?> clazz, Field field) {
    Resource resource = (Resource) field.getAnnotation(Resource.class);
    if (resource != null) {
        //JavaEE Spec 5.2.3: Field cannot be static
        if (Modifier.isStatic(field.getModifiers())) {
            LOG.warn("Skipping Resource annotation on " + clazz.getName() + "." + field.getName() + ": cannot be static");
            return;
        }
        //JavaEE Spec 5.2.3: Field cannot be final
        if (Modifier.isFinal(field.getModifiers())) {
            LOG.warn("Skipping Resource annotation on " + clazz.getName() + "." + field.getName() + ": cannot be final");
            return;
        }
        //work out default name
        String name = clazz.getCanonicalName() + "/" + field.getName();
        //allow @Resource name= to override the field name
        name = (resource.name() != null && !resource.name().trim().equals("") ? resource.name() : name);
        String mappedName = (resource.mappedName() != null && !resource.mappedName().trim().equals("") ? resource.mappedName() : null);
        //get the type of the Field
        Class<?> type = field.getType();
        //Servlet Spec 3.0 p. 76
        //If a descriptor has specified at least 1 injection target for this
        //resource, then it overrides this annotation
        MetaData metaData = _context.getMetaData();
        if (metaData.getOriginDescriptor("resource-ref." + name + ".injection") != null) {
            //it overrides this annotation
            return;
        }
        //No injections for this resource in any descriptors, so we can add it
        //Does the injection already exist?
        InjectionCollection injections = (InjectionCollection) _context.getAttribute(InjectionCollection.INJECTION_COLLECTION);
        if (injections == null) {
            injections = new InjectionCollection();
            _context.setAttribute(InjectionCollection.INJECTION_COLLECTION, injections);
        }
        Injection injection = injections.getInjection(name, clazz, field);
        if (injection == null) {
            //No injection has been specified, add it
            try {
                boolean bound = org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_context, name, mappedName);
                if (!bound)
                    bound = org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_context.getServer(), name, mappedName);
                if (!bound)
                    bound = org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(null, name, mappedName);
                if (!bound) {
                    //see if there is an env-entry value been bound
                    try {
                        InitialContext ic = new InitialContext();
                        String nameInEnvironment = (mappedName != null ? mappedName : name);
                        ic.lookup("java:comp/env/" + nameInEnvironment);
                        bound = true;
                    } catch (NameNotFoundException e) {
                        bound = false;
                    }
                }
                //Check there is a JNDI entry for this annotation
                if (bound) {
                    LOG.debug("Bound " + (mappedName == null ? name : mappedName) + " as " + name);
                    //   Make the Injection for it if the binding succeeded
                    injection = new Injection();
                    injection.setTarget(clazz, field, type);
                    injection.setJndiName(name);
                    injection.setMappingName(mappedName);
                    injections.add(injection);
                    //TODO - an @Resource is equivalent to a resource-ref, resource-env-ref, message-destination
                    metaData.setOrigin("resource-ref." + name + ".injection", resource, clazz);
                } else if (!isEnvEntryType(type)) {
                    throw new IllegalStateException("No resource at " + (mappedName == null ? name : mappedName));
                }
            } catch (NamingException e) {
                // JavaEE Spec. sec 5.4.1.3
                if (!isEnvEntryType(type))
                    throw new IllegalStateException(e);
            }
        }
    }
}
Also used : InjectionCollection(org.eclipse.jetty.plus.annotation.InjectionCollection) NameNotFoundException(javax.naming.NameNotFoundException) MetaData(org.eclipse.jetty.webapp.MetaData) Resource(javax.annotation.Resource) NamingException(javax.naming.NamingException) Injection(org.eclipse.jetty.plus.annotation.Injection) InitialContext(javax.naming.InitialContext)

Example 4 with Injection

use of org.eclipse.jetty.plus.annotation.Injection in project jetty.project by eclipse.

the class PlusDescriptorProcessor method addInjections.

/**
     * Iterate over the <code>&lt;injection-target&gt;</code> entries for a node
     * 
     * @param context the context 
     * @param descriptor the descriptor 
     * @param node the xml node
     * @param jndiName the jndi name
     * @param valueClass the value class
     */
public void addInjections(WebAppContext context, Descriptor descriptor, XmlParser.Node node, String jndiName, Class<?> valueClass) {
    Iterator<XmlParser.Node> itor = node.iterator("injection-target");
    while (itor.hasNext()) {
        XmlParser.Node injectionNode = itor.next();
        String targetClassName = injectionNode.getString("injection-target-class", false, true);
        String targetName = injectionNode.getString("injection-target-name", false, true);
        if ((targetClassName == null) || targetClassName.equals("")) {
            LOG.warn("No classname found in injection-target");
            continue;
        }
        if ((targetName == null) || targetName.equals("")) {
            LOG.warn("No field or method name in injection-target");
            continue;
        }
        InjectionCollection injections = (InjectionCollection) context.getAttribute(InjectionCollection.INJECTION_COLLECTION);
        if (injections == null) {
            injections = new InjectionCollection();
            context.setAttribute(InjectionCollection.INJECTION_COLLECTION, injections);
        }
        // for first as a java bean property, then if that fails, as a field
        try {
            Class<?> clazz = context.loadClass(targetClassName);
            Injection injection = new Injection();
            injection.setJndiName(jndiName);
            injection.setTarget(clazz, targetName, valueClass);
            injections.add(injection);
            //Record which was the first descriptor to declare an injection for this name
            if (context.getMetaData().getOriginDescriptor(node.getTag() + "." + jndiName + ".injection") == null)
                context.getMetaData().setOrigin(node.getTag() + "." + jndiName + ".injection", descriptor);
        } catch (ClassNotFoundException e) {
            LOG.warn("Couldn't load injection target class " + targetClassName);
        }
    }
}
Also used : XmlParser(org.eclipse.jetty.xml.XmlParser) InjectionCollection(org.eclipse.jetty.plus.annotation.InjectionCollection) Injection(org.eclipse.jetty.plus.annotation.Injection)

Aggregations

Injection (org.eclipse.jetty.plus.annotation.Injection)4 InjectionCollection (org.eclipse.jetty.plus.annotation.InjectionCollection)3 Resource (javax.annotation.Resource)2 InitialContext (javax.naming.InitialContext)2 NameNotFoundException (javax.naming.NameNotFoundException)2 NamingException (javax.naming.NamingException)2 MetaData (org.eclipse.jetty.webapp.MetaData)2 Field (java.lang.reflect.Field)1 AnnotationIntrospector (org.eclipse.jetty.annotations.AnnotationIntrospector)1 ResourceAnnotationHandler (org.eclipse.jetty.annotations.ResourceAnnotationHandler)1 XmlParser (org.eclipse.jetty.xml.XmlParser)1 Test (org.junit.Test)1