Search in sources :

Example 1 with Origin

use of org.eclipse.jetty.webapp.Origin in project jetty.project by eclipse.

the class PlusDescriptorProcessor method visitResourceRef.

/**
     * Common Annotations Spec section 2.3:
     * <p>
     *  resource-ref is for:
     * <ul>
     * <li>javax.sql.DataSource</li>
     * <li>javax.jms.ConnectionFactory</li>
     * <li>javax.jms.QueueConnectionFactory</li>
     * <li>javax.jms.TopicConnectionFactory</li>
     * <li>javax.mail.Session</li>
     * <li>java.net.URL</li>
     * <li>javax.resource.cci.ConnectionFactory</li>
     * <li>org.omg.CORBA_2_3.ORB</li>
     * <li>any other connection factory defined by a resource adapter</li>
     * </ul>
     *
     * If web.xml contains a resource-ref with injection targets, all resource-ref entries
     * of the same name are ignored in web fragments. If web.xml does not contain any
     * injection-targets, then they are merged from all the fragments.
     * If web.xml does not contain a resource-ref element of same name, but 2 fragments
     * declare the same name it is an error.
     * resource-ref entries are ONLY for connection factories
     * the resource-ref says how the app will reference the jndi lookup relative
     * to java:comp/env, but it is up to the deployer to map this reference to
     * a real resource in the environment. At the moment, we insist that the
     * jetty.xml file name of the resource has to be exactly the same as the
     * name in web.xml deployment descriptor, but it shouldn't have to be
     * 
     * <p>
     * Maintenance update 3.0a to spec:
     * <p>
     *   Update Section 8.2.3.h.ii with the following -  If a resource reference
     *   element is specified in two fragments, while absent from the main web.xml,
     *   and all the attributes and child elements of the resource reference element
     *   are identical, the resource reference will be merged  into the main web.xml.
     *   It is considered an error if a resource reference element has the same name
     *   specified in two fragments, while absent from the main web.xml and the attributes
     *   and child elements are not identical in the two fragments. For example, if two
     *   web fragments declare a <code>&lt;resource-ref&gt;</code> with the same <code>&lt;resource-ref-name&gt;</code> element
     *   but the type in one is specified as javax.sql.DataSource while the type in the
     *   other is that of a java mail resource, then an error must be reported and the
     *   application MUST fail to deploy.
     *   
     * @param context the context  
     * @param descriptor the descriptor
     * @param node the xml node
     * @throws Exception if unable to bind nodes, or load classes
     */
public void visitResourceRef(WebAppContext context, Descriptor descriptor, XmlParser.Node node) throws Exception {
    String jndiName = node.getString("res-ref-name", false, true);
    String type = node.getString("res-type", false, true);
    String auth = node.getString("res-auth", false, true);
    String shared = node.getString("res-sharing-scope", false, true);
    Origin o = context.getMetaData().getOrigin("resource-ref." + jndiName);
    switch(o) {
        case NotSet:
            {
                //No descriptor or annotation previously declared a resource-ref of this name.
                context.getMetaData().setOrigin("resource-ref." + jndiName, descriptor);
                //check for <injection> elements
                Class<?> typeClass = TypeUtil.fromName(type);
                if (typeClass == null)
                    typeClass = context.loadClass(type);
                addInjections(context, descriptor, node, jndiName, typeClass);
                bindResourceRef(context, jndiName, typeClass);
                break;
            }
        case WebXml:
        case WebDefaults:
        case WebOverride:
            {
                //A web xml previously declared the resource-ref.
                if (!(descriptor instanceof FragmentDescriptor)) {
                    //We're processing web-defaults, web.xml or web-override. Any of them can
                    //set or change the resource-ref.
                    context.getMetaData().setOrigin("resource-ref." + jndiName, descriptor);
                    //check for <injection> elements
                    Class<?> typeClass = TypeUtil.fromName(type);
                    if (typeClass == null)
                        typeClass = context.loadClass(type);
                    addInjections(context, descriptor, node, jndiName, typeClass);
                    //bind the entry into jndi
                    bindResourceRef(context, jndiName, typeClass);
                } else {
                    //A web xml declared the resource-ref and we're processing a
                    //web-fragment. Check to see if any injections were declared for it by web.xml.
                    //If any injection was declared in web.xml then don't merge any injections.
                    //If it was declared in a web-fragment, then we can keep merging fragments.
                    Descriptor d = context.getMetaData().getOriginDescriptor("resource-ref." + jndiName + ".injection");
                    if (d == null || d instanceof FragmentDescriptor) {
                        Class<?> typeClass = TypeUtil.fromName(type);
                        if (typeClass == null)
                            typeClass = context.loadClass(type);
                        addInjections(context, descriptor, node, jndiName, TypeUtil.fromName(type));
                    }
                }
                break;
            }
        case WebFragment:
            {
                Descriptor otherFragment = context.getMetaData().getOriginDescriptor("resource-ref." + jndiName);
                XmlParser.Node otherFragmentRoot = otherFragment.getRoot();
                Iterator<Object> iter = otherFragmentRoot.iterator();
                XmlParser.Node otherNode = null;
                while (iter.hasNext() && otherNode == null) {
                    Object obj = iter.next();
                    if (!(obj instanceof XmlParser.Node))
                        continue;
                    XmlParser.Node n = (XmlParser.Node) obj;
                    if ("resource-ref".equals(n.getTag()) && jndiName.equals(n.getString("res-ref-name", false, true)))
                        otherNode = n;
                }
                //If declared in another web-fragment
                if (otherNode != null) {
                    //declarations of the resource-ref must be the same in both fragment descriptors
                    String otherType = otherNode.getString("res-type", false, true);
                    String otherAuth = otherNode.getString("res-auth", false, true);
                    String otherShared = otherNode.getString("res-sharing-scope", false, true);
                    //otherType, otherAuth and otherShared must be the same as type, auth, shared
                    type = (type == null ? "" : type);
                    otherType = (otherType == null ? "" : otherType);
                    auth = (auth == null ? "" : auth);
                    otherAuth = (otherAuth == null ? "" : otherAuth);
                    shared = (shared == null ? "" : shared);
                    otherShared = (otherShared == null ? "" : otherShared);
                    //ServletSpec p.75. No declaration of resource-ref in web xml, but different in multiple web-fragments. Error.
                    if (!type.equals(otherType) || !auth.equals(otherAuth) || !shared.equals(otherShared))
                        throw new IllegalStateException("Conflicting resource-ref " + jndiName + " in " + descriptor.getResource());
                    //same in multiple web-fragments, merge the injections
                    addInjections(context, descriptor, node, jndiName, TypeUtil.fromName(type));
                } else
                    throw new IllegalStateException("resource-ref." + jndiName + " not found in declaring descriptor " + otherFragment);
            }
    }
}
Also used : Origin(org.eclipse.jetty.webapp.Origin) XmlParser(org.eclipse.jetty.xml.XmlParser) Iterator(java.util.Iterator) FragmentDescriptor(org.eclipse.jetty.webapp.FragmentDescriptor) Descriptor(org.eclipse.jetty.webapp.Descriptor) FragmentDescriptor(org.eclipse.jetty.webapp.FragmentDescriptor)

Example 2 with Origin

use of org.eclipse.jetty.webapp.Origin in project jetty.project by eclipse.

the class PlusDescriptorProcessor method visitMessageDestinationRef.

/**
     * Common Annotations Spec section 2.3:
     * <p>
     * message-destination-ref is for:
     * <ul>
     * <li>javax.jms.Queue</li>
     * <li>javax.jms.Topic</li>
     * </ul>
     *     
     * @param context the context 
     * @param descriptor the descriptor 
     * @param node the xml node
     * @throws Exception if unable to load classes or bind jndi entries
     */
public void visitMessageDestinationRef(WebAppContext context, Descriptor descriptor, XmlParser.Node node) throws Exception {
    String jndiName = node.getString("message-destination-ref-name", false, true);
    String type = node.getString("message-destination-type", false, true);
    String usage = node.getString("message-destination-usage", false, true);
    Origin o = context.getMetaData().getOrigin("message-destination-ref." + jndiName);
    switch(o) {
        case NotSet:
            {
                //A message-destination-ref of this name has not been previously declared
                Class<?> typeClass = TypeUtil.fromName(type);
                if (typeClass == null)
                    typeClass = context.loadClass(type);
                addInjections(context, descriptor, node, jndiName, typeClass);
                bindMessageDestinationRef(context, jndiName, typeClass);
                context.getMetaData().setOrigin("message-destination-ref." + jndiName, descriptor);
                break;
            }
        case WebXml:
        case WebDefaults:
        case WebOverride:
            {
                //Only allow other web-default, web.xml, web-override to change it.
                if (!(descriptor instanceof FragmentDescriptor)) {
                    Class<?> typeClass = TypeUtil.fromName(type);
                    if (typeClass == null)
                        typeClass = context.loadClass(type);
                    addInjections(context, descriptor, node, jndiName, typeClass);
                    bindMessageDestinationRef(context, jndiName, typeClass);
                    context.getMetaData().setOrigin("message-destination-ref." + jndiName, descriptor);
                } else {
                    //A web-fragment has declared a message-destination-ref with the same name as a web xml.
                    //It can only contribute injections, and only if the web xml didn't declare any.
                    Descriptor d = context.getMetaData().getOriginDescriptor("message-destination-ref." + jndiName + ".injection");
                    if (d == null || d instanceof FragmentDescriptor) {
                        Class<?> typeClass = TypeUtil.fromName(type);
                        if (typeClass == null)
                            typeClass = context.loadClass(type);
                        addInjections(context, descriptor, node, jndiName, typeClass);
                    }
                }
                break;
            }
        case WebFragment:
            {
                Descriptor otherFragment = context.getMetaData().getOriginDescriptor("message-destination-ref." + jndiName);
                XmlParser.Node otherFragmentRoot = otherFragment.getRoot();
                Iterator<Object> iter = otherFragmentRoot.iterator();
                XmlParser.Node otherNode = null;
                while (iter.hasNext() && otherNode == null) {
                    Object obj = iter.next();
                    if (!(obj instanceof XmlParser.Node))
                        continue;
                    XmlParser.Node n = (XmlParser.Node) obj;
                    if ("message-destination-ref".equals(n.getTag()) && jndiName.equals(n.getString("message-destination-ref-name", false, true)))
                        otherNode = n;
                }
                if (otherNode != null) {
                    String otherType = node.getString("message-destination-type", false, true);
                    String otherUsage = node.getString("message-destination-usage", false, true);
                    type = (type == null ? "" : type);
                    usage = (usage == null ? "" : usage);
                    if (!type.equals(otherType) || !usage.equalsIgnoreCase(otherUsage))
                        throw new IllegalStateException("Conflicting message-destination-ref " + jndiName + " in " + descriptor.getResource());
                    //same in multiple web-fragments, merge the injections
                    addInjections(context, descriptor, node, jndiName, TypeUtil.fromName(type));
                } else
                    throw new IllegalStateException("message-destination-ref." + jndiName + " not found in declaring descriptor " + otherFragment);
            }
    }
}
Also used : Origin(org.eclipse.jetty.webapp.Origin) XmlParser(org.eclipse.jetty.xml.XmlParser) Iterator(java.util.Iterator) FragmentDescriptor(org.eclipse.jetty.webapp.FragmentDescriptor) Descriptor(org.eclipse.jetty.webapp.Descriptor) FragmentDescriptor(org.eclipse.jetty.webapp.FragmentDescriptor)

Example 3 with Origin

use of org.eclipse.jetty.webapp.Origin in project jetty.project by eclipse.

the class PlusDescriptorProcessor method visitEnvEntry.

/**
     * JavaEE 5.4.1.3
     * 
     * @param context the context 
     * @param descriptor the descriptor 
     * @param node the xml node
     * @throws Exception if unable to process jndi bindings
     */
public void visitEnvEntry(WebAppContext context, Descriptor descriptor, XmlParser.Node node) throws Exception {
    String name = node.getString("env-entry-name", false, true);
    String type = node.getString("env-entry-type", false, true);
    String valueStr = node.getString("env-entry-value", false, true);
    //nor processing injection entries
    if (valueStr == null || valueStr.equals("")) {
        LOG.warn("No value for env-entry-name " + name);
        return;
    }
    Origin o = context.getMetaData().getOrigin("env-entry." + name);
    switch(o) {
        case NotSet:
            {
                //no descriptor has configured an env-entry of this name previously
                context.getMetaData().setOrigin("env-entry." + name, descriptor);
                //the javaee_5.xsd says that the env-entry-type is optional
                //if there is an <injection> element, because you can get
                //type from the element, but what to do if there is more
                //than one <injection> element, do you just pick the type
                //of the first one?
                addInjections(context, descriptor, node, name, TypeUtil.fromName(type));
                Object value = TypeUtil.valueOf(type, valueStr);
                bindEnvEntry(name, value);
                break;
            }
        case WebXml:
        case WebDefaults:
        case WebOverride:
            {
                //the web.xml did not declare any injections.
                if (!(descriptor instanceof FragmentDescriptor)) {
                    //We're processing web-defaults, web.xml or web-override. Any of them can
                    //set or change the env-entry.
                    context.getMetaData().setOrigin("env-entry." + name, descriptor);
                    addInjections(context, descriptor, node, name, TypeUtil.fromName(type));
                    Object value = TypeUtil.valueOf(type, valueStr);
                    bindEnvEntry(name, value);
                } else {
                    //A web.xml declared the env-entry. Check to see if any injections have been
                    //declared for it. If it was declared in web.xml then don't merge any injections.
                    //If it was declared in a web-fragment, then we can keep merging fragments.
                    Descriptor d = context.getMetaData().getOriginDescriptor("env-entry." + name + ".injection");
                    if (d == null || d instanceof FragmentDescriptor)
                        addInjections(context, descriptor, node, name, TypeUtil.fromName(type));
                }
                break;
            }
        case WebFragment:
            {
                //ServletSpec p.75. No declaration in web.xml, but in multiple web-fragments. Error.
                throw new IllegalStateException("Conflicting env-entry " + name + " in " + descriptor.getResource());
            }
    }
}
Also used : Origin(org.eclipse.jetty.webapp.Origin) FragmentDescriptor(org.eclipse.jetty.webapp.FragmentDescriptor) Descriptor(org.eclipse.jetty.webapp.Descriptor) FragmentDescriptor(org.eclipse.jetty.webapp.FragmentDescriptor)

Example 4 with Origin

use of org.eclipse.jetty.webapp.Origin in project jetty.project by eclipse.

the class PlusDescriptorProcessor method visitResourceEnvRef.

/**
     * Common Annotations Spec section 2.3:
     * <p>
     * resource-env-ref is for:
     * <ul>
     * <li>javax.transaction.UserTransaction</li>
     * <li>javax.resource.cci.InteractionSpec</li>
     * <li>anything else that is not a connection factory</li>
     * </ul>
     * 
     * @param context the context 
     * @param descriptor the descriptor 
     * @param node the xml node
     * @throws Exception if unable to load classes, or bind jndi entries
     */
public void visitResourceEnvRef(WebAppContext context, Descriptor descriptor, XmlParser.Node node) throws Exception {
    String jndiName = node.getString("resource-env-ref-name", false, true);
    String type = node.getString("resource-env-ref-type", false, true);
    Origin o = context.getMetaData().getOrigin("resource-env-ref." + jndiName);
    switch(o) {
        case NotSet:
            {
                //First declaration of resource-env-ref with this jndiName
                //JavaEE Spec sec 5.7.1.3 says the resource-env-ref-type
                //is mandatory, but the schema says it is optional!
                Class<?> typeClass = TypeUtil.fromName(type);
                if (typeClass == null)
                    typeClass = context.loadClass(type);
                addInjections(context, descriptor, node, jndiName, typeClass);
                bindResourceEnvRef(context, jndiName, typeClass);
                break;
            }
        case WebXml:
        case WebDefaults:
        case WebOverride:
            {
                //Only allow other web-default, web.xml, web-override to change it.
                if (!(descriptor instanceof FragmentDescriptor)) {
                    //We're processing web-defaults, web.xml or web-override. Any of them can
                    //set or change the resource-env-ref.
                    context.getMetaData().setOrigin("resource-env-ref." + jndiName, descriptor);
                    Class<?> typeClass = TypeUtil.fromName(type);
                    if (typeClass == null)
                        typeClass = context.loadClass(type);
                    addInjections(context, descriptor, node, jndiName, typeClass);
                    bindResourceEnvRef(context, jndiName, typeClass);
                } else {
                    //We're processing a web-fragment. It can only contribute injections if the
                    //there haven't been any injections declared yet, or they weren't declared in a WebXml file.
                    Descriptor d = context.getMetaData().getOriginDescriptor("resource-env-ref." + jndiName + ".injection");
                    if (d == null || d instanceof FragmentDescriptor) {
                        Class<?> typeClass = TypeUtil.fromName(type);
                        if (typeClass == null)
                            typeClass = context.loadClass(type);
                        addInjections(context, descriptor, node, jndiName, typeClass);
                    }
                }
                break;
            }
        case WebFragment:
            {
                Descriptor otherFragment = context.getMetaData().getOriginDescriptor("resource-env-ref." + jndiName);
                XmlParser.Node otherFragmentRoot = otherFragment.getRoot();
                Iterator<Object> iter = otherFragmentRoot.iterator();
                XmlParser.Node otherNode = null;
                while (iter.hasNext() && otherNode == null) {
                    Object obj = iter.next();
                    if (!(obj instanceof XmlParser.Node))
                        continue;
                    XmlParser.Node n = (XmlParser.Node) obj;
                    if ("resource-env-ref".equals(n.getTag()) && jndiName.equals(n.getString("resource-env-ref-name", false, true)))
                        otherNode = n;
                }
                if (otherNode != null) {
                    //declarations of the resource-ref must be the same in both fragment descriptors
                    String otherType = otherNode.getString("resource-env-ref-type", false, true);
                    //types must be the same
                    type = (type == null ? "" : type);
                    otherType = (otherType == null ? "" : otherType);
                    //ServletSpec p.75. No declaration of resource-ref in web xml, but different in multiple web-fragments. Error.
                    if (!type.equals(otherType))
                        throw new IllegalStateException("Conflicting resource-env-ref " + jndiName + " in " + descriptor.getResource());
                    //same in multiple web-fragments, merge the injections
                    addInjections(context, descriptor, node, jndiName, TypeUtil.fromName(type));
                } else
                    throw new IllegalStateException("resource-env-ref." + jndiName + " not found in declaring descriptor " + otherFragment);
            }
    }
}
Also used : Origin(org.eclipse.jetty.webapp.Origin) XmlParser(org.eclipse.jetty.xml.XmlParser) Iterator(java.util.Iterator) FragmentDescriptor(org.eclipse.jetty.webapp.FragmentDescriptor) Descriptor(org.eclipse.jetty.webapp.Descriptor) FragmentDescriptor(org.eclipse.jetty.webapp.FragmentDescriptor)

Example 5 with Origin

use of org.eclipse.jetty.webapp.Origin in project jetty.project by eclipse.

the class PostConstructAnnotationHandler method doHandle.

public void doHandle(Class clazz) {
    //Check that the PostConstruct is on a class that we're interested in
    if (supportsPostConstruct(clazz)) {
        Method[] methods = clazz.getDeclaredMethods();
        for (int i = 0; i < methods.length; i++) {
            Method m = (Method) methods[i];
            if (m.isAnnotationPresent(PostConstruct.class)) {
                if (m.getParameterCount() != 0)
                    throw new IllegalStateException(m + " has parameters");
                if (m.getReturnType() != Void.TYPE)
                    throw new IllegalStateException(m + " is not void");
                if (m.getExceptionTypes().length != 0)
                    throw new IllegalStateException(m + " throws checked exceptions");
                if (Modifier.isStatic(m.getModifiers()))
                    throw new IllegalStateException(m + " is static");
                //ServletSpec 3.0 p80 If web.xml declares even one post-construct then all post-constructs
                //in fragments must be ignored. Otherwise, they are additive.
                MetaData metaData = _context.getMetaData();
                Origin origin = metaData.getOrigin("post-construct");
                if (origin != null && (origin == Origin.WebXml || origin == Origin.WebDefaults || origin == Origin.WebOverride))
                    return;
                PostConstructCallback callback = new PostConstructCallback();
                callback.setTarget(clazz.getName(), m.getName());
                LifeCycleCallbackCollection lifecycles = (LifeCycleCallbackCollection) _context.getAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION);
                if (lifecycles == null) {
                    lifecycles = new LifeCycleCallbackCollection();
                    _context.setAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION, lifecycles);
                }
                lifecycles.add(callback);
            }
        }
    }
}
Also used : Origin(org.eclipse.jetty.webapp.Origin) LifeCycleCallbackCollection(org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection) MetaData(org.eclipse.jetty.webapp.MetaData) PostConstructCallback(org.eclipse.jetty.plus.annotation.PostConstructCallback) Method(java.lang.reflect.Method)

Aggregations

Origin (org.eclipse.jetty.webapp.Origin)8 FragmentDescriptor (org.eclipse.jetty.webapp.FragmentDescriptor)6 Descriptor (org.eclipse.jetty.webapp.Descriptor)4 Iterator (java.util.Iterator)3 XmlParser (org.eclipse.jetty.xml.XmlParser)3 Method (java.lang.reflect.Method)2 LifeCycleCallback (org.eclipse.jetty.plus.annotation.LifeCycleCallback)2 LifeCycleCallbackCollection (org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection)2 PostConstructCallback (org.eclipse.jetty.plus.annotation.PostConstructCallback)2 PreDestroyCallback (org.eclipse.jetty.plus.annotation.PreDestroyCallback)2 MetaData (org.eclipse.jetty.webapp.MetaData)2