use of org.eclipse.jetty.webapp.Descriptor 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><resource-ref></code> with the same <code><resource-ref-name></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);
}
}
}
use of org.eclipse.jetty.webapp.Descriptor 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);
}
}
}
use of org.eclipse.jetty.webapp.Descriptor 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());
}
}
}
use of org.eclipse.jetty.webapp.Descriptor 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);
}
}
}
use of org.eclipse.jetty.webapp.Descriptor in project jetty.project by eclipse.
the class PlusDescriptorProcessorTest method testWebXmlResourceDeclarations.
@Test
public void testWebXmlResourceDeclarations() throws Exception {
//if declared in web.xml, fragment declarations ignored
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(context.getClassLoader());
try {
PlusDescriptorProcessor pdp = new PlusDescriptorProcessor();
pdp.process(context, webDescriptor);
Descriptor d = context.getMetaData().getOriginDescriptor("resource-ref.jdbc/mydatasource");
assertNotNull(d);
assertTrue(d == webDescriptor);
pdp.process(context, fragDescriptor1);
pdp.process(context, fragDescriptor2);
} finally {
Thread.currentThread().setContextClassLoader(oldLoader);
}
}
Aggregations