use of org.eclipse.jetty.webapp.FragmentDescriptor in project jetty.project by eclipse.
the class TestAnnotationConfiguration method testGetFragmentFromJar.
@Test
public void testGetFragmentFromJar() throws Exception {
String dir = MavenTestingUtils.getTargetTestingDir("getFragmentFromJar").getAbsolutePath();
File file = new File(dir);
file = new File(file.getCanonicalPath());
URL url = file.toURL();
Resource jar1 = Resource.newResource(url + "file.jar");
AnnotationConfiguration config = new AnnotationConfiguration();
WebAppContext wac = new WebAppContext();
List<FragmentDescriptor> frags = new ArrayList<FragmentDescriptor>();
frags.add(new FragmentDescriptor(Resource.newResource("jar:" + url + "file.jar!/fooa.props")));
frags.add(new FragmentDescriptor(Resource.newResource("jar:" + url + "file2.jar!/foob.props")));
assertNotNull(config.getFragmentFromJar(jar1, frags));
}
use of org.eclipse.jetty.webapp.FragmentDescriptor in project jetty.project by eclipse.
the class AnnotationConfiguration method parseWebInfLib.
/**
* Scan jars in WEB-INF/lib
*
* @param context the context for the scan
* @param parser the annotation parser to use
* @throws Exception if unable to scan and/or parse
*/
public void parseWebInfLib(final WebAppContext context, final AnnotationParser parser) throws Exception {
List<FragmentDescriptor> frags = context.getMetaData().getFragments();
//email from Rajiv Mordani jsrs 315 7 April 2010
//jars that do not have a web-fragment.xml are still considered fragments
//they have to participate in the ordering
ArrayList<URI> webInfUris = new ArrayList<URI>();
List<Resource> jars = null;
if (context.getMetaData().getOrdering() != null)
jars = context.getMetaData().getOrderedWebInfJars();
else
//No ordering just use the jars in any order
jars = context.getMetaData().getWebInfJars();
_webInfLibStats = new CounterStatistic();
for (Resource r : jars) {
//for each jar, we decide which set of annotations we need to parse for
final Set<Handler> handlers = new HashSet<Handler>();
FragmentDescriptor f = getFragmentFromJar(r, frags);
//or if it has a fragment we scan it if it is not metadata complete
if (f == null || !isMetaDataComplete(f) || _classInheritanceHandler != null || !_containerInitializerAnnotationHandlers.isEmpty()) {
//register the classinheritance handler if there is one
if (_classInheritanceHandler != null)
handlers.add(_classInheritanceHandler);
//register the handlers for the @HandlesTypes values that are themselves annotations if there are any
handlers.addAll(_containerInitializerAnnotationHandlers);
//only register the discoverable annotation handlers if this fragment is not metadata complete, or has no fragment descriptor
if (f == null || !isMetaDataComplete(f))
handlers.addAll(_discoverableAnnotationHandlers);
if (_parserTasks != null) {
ParserTask task = new ParserTask(parser, handlers, r);
_parserTasks.add(task);
_webInfLibStats.increment();
if (LOG.isDebugEnabled())
task.setStatistic(new TimeStatistic());
}
}
}
}
use of org.eclipse.jetty.webapp.FragmentDescriptor 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.FragmentDescriptor 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.FragmentDescriptor 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());
}
}
}
Aggregations