Refactor eeX plus.security and plus.annotation classes to core (#11030)
* Refactor eeX plus.security and plus.annotation classes to core
This commit is contained in:
parent
006f8f75c5
commit
d926380651
|
@ -14,7 +14,7 @@
|
|||
[[og-annotations]]
|
||||
=== Annotations
|
||||
|
||||
Enable the `annotations` module if your webapp - or any of its third party libraries - uses any of the following:
|
||||
Enable the `{ee-all}-annotations` module if your webapp - or any of its third party libraries - uses any of the following:
|
||||
|
||||
* Annotations:
|
||||
** @Resource
|
||||
|
@ -30,38 +30,38 @@ Enable the `annotations` module if your webapp - or any of its third party libra
|
|||
** @WebInitParam
|
||||
** @ServletSecurity, @HttpConstraint, @HttpMethodConstraint
|
||||
** @HandlesTypes
|
||||
* javax.servlet.ServletContainerInitializers
|
||||
* javax.servlet.ServletContainerInitializers or jakarta.servlet.ServletContainerInitializers
|
||||
* JSP
|
||||
|
||||
|
||||
[[og-annotations-scanning]]
|
||||
==== Annotation Scanning
|
||||
|
||||
According to more recent versions of the Servlet Specification, the web.xml file can contain the attribute `metadata-complete`.
|
||||
According to more recent versions of the Jakarta Servlet Specification, the `web.xml` file can contain the attribute `metadata-complete`.
|
||||
If this is set to `true`, then _no_ annotation scanning takes place, and your descriptor must contain the equivalent xml statements of any annotations.
|
||||
|
||||
If it is `metadata-complete=false`, or your web.xml predates the inclusion of this attribute, annotation scanning is required to take place.
|
||||
If it is `metadata-complete=false`, or your `web.xml` predates the inclusion of this attribute, annotation scanning is required to take place.
|
||||
|
||||
To prevent annotation scanning you can use the `WebAppContext.setConfigurationDiscovered(false)` method.
|
||||
Here's an example context xml file that calls this method:
|
||||
Here's an example context XML file that calls this method:
|
||||
|
||||
[source,xml]
|
||||
[source,xml,subs="verbatim,attributes"]
|
||||
----
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
|
||||
|
||||
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext"> <!--1-->
|
||||
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext"> <!--1-->
|
||||
<Set name="configurationDiscovered">false</Set> <!--2-->
|
||||
</Configure>
|
||||
----
|
||||
<1> Configures a link:{javadoc-url}/org/eclipse/jetty/webapp/WebAppContext.html[`WebAppContext`], which is the Jetty component that represents a standard Servlet web application.
|
||||
<1> Configures a link:{javadoc-url}/org/eclipse/jetty/{ee-current}/webapp/WebAppContext.html[`WebAppContext`], which is the Jetty component that represents a standard Servlet web application.
|
||||
<2> Specifies that scanning should not take place.
|
||||
|
||||
However, despite `metadata-complete=true`, scanning of classes may _still_ occur because of http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContainerInitializer.html[javax.servlet.ServletContainerInitializer]s.
|
||||
Classes implementing this interface are found by Jetty using the http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html[javax.util.ServiceLoader] mechanism, and if one is present _and_ it includes the @HandlesTypes annotation, then Jetty must scan the class hierarchy of the web application.
|
||||
However, despite `metadata-complete=true`, scanning of classes may _still_ occur because of `ServletContainerInitializer`.
|
||||
Classes implementing this interface are found by Jetty using the http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html[javax.util.ServiceLoader] mechanism, and if one is present _and_ it includes the `@HandlesTypes` annotation, then Jetty must scan the class hierarchy of the web application.
|
||||
This may be very time-consuming if you have many jars.
|
||||
|
||||
We will now look at ways to limit the jars that are scanned.
|
||||
Jetty can reduce the time taken by limiting the jars that are scanned.
|
||||
|
||||
===== The container classpath
|
||||
|
||||
|
@ -71,21 +71,21 @@ Sometimes, you may have third party libraries on the container's classpath that
|
|||
In this case, use the `org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern` context attribute to define which container jars and class directories to scan.
|
||||
The value of this attribute is a regular expression.
|
||||
|
||||
Here's an example from a context xml file that includes any jar whose name starts with "foo-" or "bar-", or a directory named "classes":
|
||||
Here's an example from a context XML file that includes any jar whose name starts with `foo-` or `bar-`, or a directory named `classes`:
|
||||
|
||||
[source,xml]
|
||||
[source,xml,subs="verbatim,attributes"]
|
||||
----
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
|
||||
|
||||
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext"> <!--1-->
|
||||
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext"> <!--1-->
|
||||
<Call name="setAttribute"> <!--2-->
|
||||
<Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg> <!--3-->
|
||||
<Arg>.*/foo-[^/]*\.jar$|.*/bar-[^/]*\.jar$|.*/classes/.*</Arg> <!--4-->
|
||||
</Call>
|
||||
</Configure>
|
||||
----
|
||||
<1> Configures a link:{javadoc-url}/org/eclipse/jetty/webapp/WebAppContext.html[`WebAppContext`], which is the Jetty component that represents a standard Servlet web application.
|
||||
<1> Configures a link:{javadoc-url}/org/eclipse/jetty/{ee-current}/webapp/WebAppContext.html[`WebAppContext`], which is the Jetty component that represents a standard Servlet web application.
|
||||
<2> Specifies a context attribute.
|
||||
<3> Specifies the name of the context attribute.
|
||||
<4> Specifies the value of the context attribute.
|
||||
|
@ -94,42 +94,42 @@ Note that the order of the patterns defines the ordering of the scanning of the
|
|||
|
||||
===== The webapp classpath
|
||||
|
||||
By default Jetty will scan __all__ classes from `WEB-INF/classes` and _all_ jars from `WEB-INF/lib` according to the order, if any, established by absolute or relative ordering clauses in web.xml.
|
||||
By default, Jetty will scan __all__ classes from `WEB-INF/classes` and _all_ jars from `WEB-INF/lib` according to the order, if any, established by absolute or relative ordering clauses in `web.xml`.
|
||||
|
||||
If your webapp contains many jar files that you know do not contain any annotations, you can significantly speed up deployment by omitting them from scanning.
|
||||
However, be careful if your webapp uses a `ServletContainerInitializer` with an `@HandlesTypes` annotation that you don't exclude jars that contain classes matching the annotation.
|
||||
However, be careful if your webapp uses a `ServletContainerInitializer` with a `@HandlesTypes` annotation that you don't exclude jars that contain classes matching the annotation.
|
||||
|
||||
Use the `org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern` context attribute to define a regular expression for jars and class directories to select for scanning.
|
||||
|
||||
Here's an example of a context xml file that sets a pattern that matches any jar on the webapp's classpath that starts with `spring-`:
|
||||
Here's an example of a context XML file that sets a pattern that matches any jar on the webapp's classpath that starts with `"spring-"`:
|
||||
|
||||
[source,xml]
|
||||
[source,xml,subs="verbatim,attributes"]
|
||||
----
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
|
||||
|
||||
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext"> <!--1-->
|
||||
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext"> <!--1-->
|
||||
<Call name="setAttribute"> <!--2-->
|
||||
<Arg>org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern</Arg> <!--3-->
|
||||
<Arg>.*/spring-[^/]*\.jar$</Arg> <!--4-->
|
||||
</Call>
|
||||
</Configure>
|
||||
----
|
||||
<1> Configures a link:{javadoc-url}/org/eclipse/jetty/webapp/WebAppContext.html[`WebAppContext`], which is the Jetty component that represents a standard Servlet web application.
|
||||
<1> Configures a link:{javadoc-url}/org/eclipse/jetty/{ee-current}/webapp/WebAppContext.html[`WebAppContext`], which is the Jetty component that represents a standard Servlet web application.
|
||||
<2> Specifies a context attribute.
|
||||
<3> Specifies the name of the context attribute.
|
||||
<4> Specifies the value of the context attribute.
|
||||
|
||||
===== Multi-threading
|
||||
|
||||
By default Jetty performs annotation scanning in a multi-threaded manner in order to complete it in the minimum amount of time.
|
||||
By default, Jetty performs annotation scanning in a multi-threaded manner in order to complete it in the minimum amount of time.
|
||||
|
||||
If you don't want multi-threaded scanning, you can configure Jetty to revert to single-threaded scanning.
|
||||
There are several options to configure this:
|
||||
|
||||
1. Set the context attribute `org.eclipse.jetty.annotations.multiThreaded` to `false`
|
||||
2. Set the `Server` attribute `org.eclipse.jetty.annotations.multiThreaded` to `false`
|
||||
3. Set the System property `org.eclipse.jetty.annotations.multiThreaded` to `false`
|
||||
3. Set the `System` property `org.eclipse.jetty.annotations.multiThreaded` to `false`
|
||||
|
||||
Method 1 will only affect the current webapp.
|
||||
Method 2 will affect all webapps deployed to the same Server instance.
|
||||
|
@ -140,7 +140,7 @@ You can set this to a higher or lower number of seconds by doing one of the foll
|
|||
|
||||
1. Set the context attribute `org.eclipse.jetty.annotations.maxWait`
|
||||
2. Set the `Server` attribute `org.eclipse.jetty.annotations.maxWait`
|
||||
3. Set the System property `org.eclipse.jetty.annotations.maxWait`
|
||||
3. Set the `System` property `org.eclipse.jetty.annotations.maxWait`
|
||||
|
||||
Method 1 will only affect the current webapp.
|
||||
Method 2 will affect all webapps deployed to the same Server instance.
|
||||
|
@ -149,39 +149,39 @@ Method 3 will affect all webapps deployed in the same JVM.
|
|||
[[og-annotations-scis]]
|
||||
==== ServletContainerInitializers
|
||||
|
||||
The http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContainerInitializer.html[javax.servlet.ServletContainerInitializer] class can exist in: the container's classpath, the webapp's `WEB-INF/classes` directory, the webapp's `WEB-INF/lib` jars, or any external extraClasspath that you have configured on the webapp.
|
||||
The `ServletContainerInitializer` class can exist in: the container's classpath, the webapp's `WEB-INF/classes` directory, the webapp's `WEB-INF/lib` jars, or any external extraClasspath that you have configured on the webapp.
|
||||
|
||||
The Servlet Specification does not define any order in which a `ServletContainerInitializer` must be called when the webapp starts.
|
||||
By default Jetty will call them in the following order:
|
||||
The Jakarta Servlet Specification does not define any order in which a `ServletContainerInitializer` must be called when the webapp starts.
|
||||
By default, Jetty will call them in the following order:
|
||||
|
||||
1. ServletContainerInitializers from the container's classpath
|
||||
2. ServletContainerInitializers from WEB-INF/classes
|
||||
3. ServletContainerInitializers from WEB-INF/lib jars __in the order established in web.xml__, or in the order that the SCI is returned by the http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html[javax.util.ServiceLoader] if there is _no_ ordering.
|
||||
2. ServletContainerInitializers from `WEB-INF/classes`
|
||||
3. ServletContainerInitializers from `WEB-INF/lib` jars __in the order established in web.xml__, or in the order that the SCI is returned by the http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html[javax.util.ServiceLoader] if there is _no_ ordering.
|
||||
|
||||
===== Exclusions
|
||||
|
||||
By default, as according to the Servlet Specification, all `ServletContainerInitializer` that are discovered are invoked.
|
||||
By default, as according to the Jakarta Servlet Specification, all `ServletContainerInitializer` instances that are discovered are invoked.
|
||||
|
||||
Sometimes, depending on your requirements, you may need to prevent some being called at all.
|
||||
|
||||
In this case, you can define the `org.eclipse.jetty.containerInitializerExclusionPattern` context attribute.
|
||||
|
||||
This is a regular expression that defines http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html[patterns] of classnames that you want to exclude.
|
||||
Here's an example of setting the context attribute in a context xml file:
|
||||
Here's an example of setting the context attribute in a context XML file:
|
||||
|
||||
[source,xml]
|
||||
[source,xml,subs="verbatim,attributes"]
|
||||
----
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
|
||||
|
||||
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext"> <!--1-->
|
||||
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext"> <!--1-->
|
||||
<Call name="setAttribute"> <!--2-->
|
||||
<Arg>org.eclipse.jetty.containerInitializerExclusionPattern</Arg> <!--3-->
|
||||
<Arg>com.acme.*|com.corp.SlowContainerInitializer</Arg> <!--4-->
|
||||
</Call>
|
||||
</Configure>
|
||||
----
|
||||
<1> Configures a link:{javadoc-url}/org/eclipse/jetty/webapp/WebAppContext.html[`WebAppContext`], which is the Jetty component that represents a standard Servlet web application.
|
||||
<1> Configures a link:{javadoc-url}/org/eclipse/jetty/{ee-current}/webapp/WebAppContext.html[`WebAppContext`], which is the Jetty component that represents a standard Servlet web application.
|
||||
<2> Specifies a context attribute.
|
||||
<3> Specifies the name of the context attribute.
|
||||
<4> Specifies the value of the context attribute.
|
||||
|
@ -193,26 +193,26 @@ It is possible to use exclusion and ordering together to control `ServletContain
|
|||
===== Ordering
|
||||
|
||||
If you need `ServletContainerInitializer` classes called in a specific order, you can use the context attribute `org.eclipse.jetty.containerInitializerOrder`.
|
||||
Set it to a list of comma separated class names of `ServletContainerInitializers` in the order that you want them applied.
|
||||
Set it to a list of comma separated `ServletContainerInitializer` class names in the order that you want them applied.
|
||||
|
||||
You may optionally use the wildcard character `+*+` *once* in the list.
|
||||
It will match all `ServletContainerInitializer` classes not explicitly named in the list.
|
||||
|
||||
Here is an example context xml file that ensures the `com.example.PrioritySCI` will be called first, followed by the `com.acme.FooSCI`, then all other SCIs:
|
||||
Here is an example context XML file that ensures the `com.example.PrioritySCI` will be called first, followed by the `com.acme.FooSCI`, then all other SCIs:
|
||||
|
||||
[source,xml]
|
||||
[source,xml,subs="verbatim,attributes"]
|
||||
----
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://eclipse.dev/jetty/configure_10_0.dtd">
|
||||
|
||||
<Configure class="org.eclipse.jetty.ee9.webapp.WebAppContext"> <!--1-->
|
||||
<Configure class="org.eclipse.jetty.{ee-current}.webapp.WebAppContext"> <!--1-->
|
||||
<Call name="setAttribute"> <!--2-->
|
||||
<Arg>org.eclipse.jetty.containerInitializerOrder</Arg> <!--3-->
|
||||
<Arg>org.eclipse.jetty.websocket.javax.server.JavaxWebSocketServletContainerInitializer, com.acme.FooSCI, *</Arg> <!--4-->
|
||||
</Call>
|
||||
</Configure>
|
||||
----
|
||||
<1> Configures a link:{javadoc-url}/org/eclipse/jetty/webapp/WebAppContext.html[`WebAppContext`], which is the Jetty component that represents a standard Servlet web application.
|
||||
<1> Configures a link:{javadoc-url}/org/eclipse/jetty/{ee-current}/webapp/WebAppContext.html[`WebAppContext`], which is the Jetty component that represents a standard Servlet web application.
|
||||
<2> Specifies a context attribute.
|
||||
<3> Specifies the name of the context attribute.
|
||||
<4> Specifies the value of the context attribute.
|
||||
|
|
|
@ -17,6 +17,10 @@
|
|||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-util</artifactId>
|
||||
|
|
|
@ -13,11 +13,15 @@
|
|||
|
||||
module org.eclipse.jetty.plus
|
||||
{
|
||||
requires org.eclipse.jetty.security;
|
||||
requires org.eclipse.jetty.util;
|
||||
requires org.slf4j;
|
||||
|
||||
requires transitive java.naming;
|
||||
requires transitive java.sql;
|
||||
// Only required if using DataSourceLoginService.
|
||||
requires static java.sql;
|
||||
|
||||
exports org.eclipse.jetty.plus.annotation;
|
||||
exports org.eclipse.jetty.plus.jndi;
|
||||
exports org.eclipse.jetty.plus.security;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.ee9.plus.annotation;
|
||||
package org.eclipse.jetty.plus.annotation;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Member;
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.ee9.plus.annotation;
|
||||
package org.eclipse.jetty.plus.annotation;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.ee9.plus.annotation;
|
||||
package org.eclipse.jetty.plus.annotation;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.ee9.plus.annotation;
|
||||
package org.eclipse.jetty.plus.annotation;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.ee9.plus.annotation;
|
||||
package org.eclipse.jetty.plus.annotation;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.ee9.plus.annotation;
|
||||
package org.eclipse.jetty.plus.annotation;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
|
@ -14,4 +14,4 @@
|
|||
/**
|
||||
* Jetty Plus : Limited JEE Annotation Support
|
||||
*/
|
||||
package org.eclipse.jetty.ee9.plus.annotation;
|
||||
package org.eclipse.jetty.plus.annotation;
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.ee9.plus.security;
|
||||
package org.eclipse.jetty.plus.security;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
|
@ -307,12 +307,6 @@ public class DataSourceLoginService extends AbstractLoginService
|
|||
if (_datasource != null)
|
||||
return;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
InitialContext ic = new InitialContext();
|
||||
assert ic != null;
|
||||
|
||||
// TODO Should we try webapp scope too?
|
||||
|
||||
// try finding the datasource in the Server scope
|
||||
if (_server != null)
|
||||
{
|
|
@ -14,4 +14,4 @@
|
|||
/**
|
||||
* Jetty Plus : Limited JEE Security Support
|
||||
*/
|
||||
package org.eclipse.jetty.ee9.plus.security;
|
||||
package org.eclipse.jetty.plus.security;
|
|
@ -80,7 +80,7 @@
|
|||
<configuration>
|
||||
<argLine>@{argLine} ${jetty.surefire.argLine}
|
||||
--add-reads org.eclipse.jetty.ee10.annotations=org.eclipse.jetty.logging
|
||||
--add-opens org.eclipse.jetty.ee10.annotations/org.eclipse.jetty.ee10.annotations.resources=org.eclipse.jetty.ee10.plus</argLine>
|
||||
--add-opens org.eclipse.jetty.ee10.annotations/org.eclipse.jetty.ee10.annotations.resources=org.eclipse.jetty.plus</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
|
|
@ -18,11 +18,11 @@ import java.lang.reflect.Modifier;
|
|||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import org.eclipse.jetty.ee10.annotations.AnnotationIntrospector.AbstractIntrospectableAnnotationHandler;
|
||||
import org.eclipse.jetty.ee10.plus.annotation.LifeCycleCallbackCollection;
|
||||
import org.eclipse.jetty.ee10.plus.annotation.PostConstructCallback;
|
||||
import org.eclipse.jetty.ee10.webapp.MetaData;
|
||||
import org.eclipse.jetty.ee10.webapp.Origin;
|
||||
import org.eclipse.jetty.ee10.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
|
||||
import org.eclipse.jetty.plus.annotation.PostConstructCallback;
|
||||
|
||||
public class PostConstructAnnotationHandler extends AbstractIntrospectableAnnotationHandler
|
||||
{
|
||||
|
|
|
@ -18,11 +18,11 @@ import java.lang.reflect.Modifier;
|
|||
|
||||
import jakarta.annotation.PreDestroy;
|
||||
import org.eclipse.jetty.ee10.annotations.AnnotationIntrospector.AbstractIntrospectableAnnotationHandler;
|
||||
import org.eclipse.jetty.ee10.plus.annotation.LifeCycleCallbackCollection;
|
||||
import org.eclipse.jetty.ee10.plus.annotation.PreDestroyCallback;
|
||||
import org.eclipse.jetty.ee10.webapp.MetaData;
|
||||
import org.eclipse.jetty.ee10.webapp.Origin;
|
||||
import org.eclipse.jetty.ee10.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
|
||||
import org.eclipse.jetty.plus.annotation.PreDestroyCallback;
|
||||
|
||||
public class PreDestroyAnnotationHandler extends AbstractIntrospectableAnnotationHandler
|
||||
{
|
||||
|
|
|
@ -25,11 +25,11 @@ import javax.naming.NamingException;
|
|||
|
||||
import jakarta.annotation.Resource;
|
||||
import org.eclipse.jetty.ee10.annotations.AnnotationIntrospector.AbstractIntrospectableAnnotationHandler;
|
||||
import org.eclipse.jetty.ee10.plus.annotation.Injection;
|
||||
import org.eclipse.jetty.ee10.plus.annotation.InjectionCollection;
|
||||
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.ee10.webapp.MetaData;
|
||||
import org.eclipse.jetty.ee10.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.plus.annotation.Injection;
|
||||
import org.eclipse.jetty.plus.annotation.InjectionCollection;
|
||||
import org.eclipse.jetty.plus.jndi.NamingEntryUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
|
|
@ -16,12 +16,12 @@ package org.eclipse.jetty.ee10.annotations;
|
|||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import org.eclipse.jetty.ee10.plus.annotation.LifeCycleCallbackCollection;
|
||||
import org.eclipse.jetty.ee10.servlet.ServletHolder;
|
||||
import org.eclipse.jetty.ee10.servlet.Source;
|
||||
import org.eclipse.jetty.ee10.webapp.MetaData;
|
||||
import org.eclipse.jetty.ee10.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.ee10.webapp.WebDescriptor;
|
||||
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
|
||||
import org.eclipse.jetty.toolchain.test.jupiter.WorkDir;
|
||||
import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension;
|
||||
import org.eclipse.jetty.util.DecoratedObjectFactory;
|
||||
|
|
|
@ -21,9 +21,9 @@ import javax.naming.InitialContext;
|
|||
import org.eclipse.jetty.ee10.annotations.AnnotationIntrospector;
|
||||
import org.eclipse.jetty.ee10.annotations.ResourceAnnotationHandler;
|
||||
import org.eclipse.jetty.ee10.annotations.ResourcesAnnotationHandler;
|
||||
import org.eclipse.jetty.ee10.plus.annotation.Injection;
|
||||
import org.eclipse.jetty.ee10.plus.annotation.InjectionCollection;
|
||||
import org.eclipse.jetty.ee10.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.plus.annotation.Injection;
|
||||
import org.eclipse.jetty.plus.annotation.InjectionCollection;
|
||||
import org.eclipse.jetty.plus.jndi.EnvEntry;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
|
|
|
@ -78,6 +78,13 @@
|
|||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<argLine>@{argLine} ${jetty.surefire.argLine} --add-exports=org.eclipse.jetty.ee10.plus/org.eclipse.jetty.ee10.plus.annotation=org.eclipse.jetty.ee10.servlet --add-opens org.eclipse.jetty.ee10.plus/org.eclipse.jetty.ee10.plus.annotation=org.eclipse.jetty.plus</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
|
|
@ -21,16 +21,10 @@ module org.eclipse.jetty.ee10.plus
|
|||
|
||||
requires transitive org.eclipse.jetty.ee10.webapp;
|
||||
|
||||
// Only required if using DataSourceLoginService.
|
||||
requires static java.sql;
|
||||
// Only required if using Transaction.
|
||||
requires static jakarta.transaction;
|
||||
// Only required if using RunAs.
|
||||
requires static org.eclipse.jetty.ee10.servlet;
|
||||
|
||||
exports org.eclipse.jetty.ee10.plus.annotation;
|
||||
exports org.eclipse.jetty.ee10.plus.jndi;
|
||||
exports org.eclipse.jetty.ee10.plus.security;
|
||||
exports org.eclipse.jetty.ee10.plus.webapp;
|
||||
|
||||
provides org.eclipse.jetty.ee10.webapp.Configuration with
|
||||
|
|
|
@ -1,231 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.ee10.plus.annotation;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import javax.naming.InitialContext;
|
||||
import javax.naming.NamingException;
|
||||
|
||||
import org.eclipse.jetty.util.IntrospectionUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Injection
|
||||
* <p>
|
||||
* Represents the injection of a resource into a target (method or field).
|
||||
* The injection is performed by doing an ENC lookup using the jndi
|
||||
* name provided, and setting the object obtained on the target.
|
||||
*/
|
||||
public class Injection
|
||||
{
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Injection.class);
|
||||
|
||||
private final Class<?> _targetClass;
|
||||
private final String _jndiName;
|
||||
private final String _mappingName;
|
||||
private final Member _target;
|
||||
private final Class<?> _paramClass;
|
||||
private final Class<?> _resourceClass;
|
||||
|
||||
public Injection(Class<?> clazz, Field field, Class<?> resourceType, String jndiName, String mappingName)
|
||||
{
|
||||
_targetClass = Objects.requireNonNull(clazz);
|
||||
_target = Objects.requireNonNull(field);
|
||||
_resourceClass = resourceType;
|
||||
_paramClass = null;
|
||||
_jndiName = jndiName;
|
||||
_mappingName = mappingName;
|
||||
}
|
||||
|
||||
public Injection(Class<?> clazz, Method method, Class<?> arg, Class<?> resourceType, String jndiName, String mappingName)
|
||||
{
|
||||
_targetClass = Objects.requireNonNull(clazz);
|
||||
_target = Objects.requireNonNull(method);
|
||||
_resourceClass = resourceType;
|
||||
_paramClass = arg;
|
||||
_jndiName = jndiName;
|
||||
_mappingName = mappingName;
|
||||
}
|
||||
|
||||
public Injection(Class<?> clazz, String target, Class<?> resourceType, String jndiName, String mappingName)
|
||||
{
|
||||
_targetClass = Objects.requireNonNull(clazz);
|
||||
Objects.requireNonNull(target);
|
||||
_resourceClass = resourceType;
|
||||
_jndiName = jndiName;
|
||||
_mappingName = mappingName;
|
||||
|
||||
Member tmpTarget = null;
|
||||
Class<?> tmpParamClass = null;
|
||||
|
||||
//first look for a javabeans style setter matching the targetName
|
||||
String setter = "set" + target.substring(0, 1).toUpperCase(Locale.ENGLISH) + target.substring(1);
|
||||
try
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Looking for method for setter: {} with arg {}", setter, _resourceClass);
|
||||
tmpTarget = IntrospectionUtil.findMethod(clazz, setter, new Class[]{_resourceClass}, true, false);
|
||||
tmpParamClass = _resourceClass;
|
||||
}
|
||||
catch (NoSuchMethodException nsme)
|
||||
{
|
||||
//try as a field
|
||||
try
|
||||
{
|
||||
tmpTarget = IntrospectionUtil.findField(clazz, target, resourceType, true, false);
|
||||
tmpParamClass = null;
|
||||
}
|
||||
catch (NoSuchFieldException nsfe)
|
||||
{
|
||||
nsme.addSuppressed(nsfe);
|
||||
throw new IllegalArgumentException("No such field or method " + target + " on class " + _targetClass, nsme);
|
||||
}
|
||||
}
|
||||
|
||||
_target = tmpTarget;
|
||||
_paramClass = tmpParamClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the _className
|
||||
*/
|
||||
public Class<?> getTargetClass()
|
||||
{
|
||||
return _targetClass;
|
||||
}
|
||||
|
||||
public Class<?> getParamClass()
|
||||
{
|
||||
return _paramClass;
|
||||
}
|
||||
|
||||
public Class<?> getResourceClass()
|
||||
{
|
||||
return _resourceClass;
|
||||
}
|
||||
|
||||
public boolean isField()
|
||||
{
|
||||
return (Field.class.isInstance(_target));
|
||||
}
|
||||
|
||||
public boolean isMethod()
|
||||
{
|
||||
return (Method.class.isInstance(_target));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the jndiName.
|
||||
* @return the jndiName
|
||||
*/
|
||||
public String getJndiName()
|
||||
{
|
||||
return _jndiName;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
* @return the mappingName
|
||||
*/
|
||||
public String getMappingName()
|
||||
{
|
||||
return _mappingName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the target.
|
||||
* @return the target
|
||||
*/
|
||||
public Member getTarget()
|
||||
{
|
||||
return _target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject a value for a Resource from JNDI into an object
|
||||
*
|
||||
* @param injectable the object to inject
|
||||
*/
|
||||
public void inject(Object injectable)
|
||||
{
|
||||
if (isField())
|
||||
injectField((Field)_target, injectable);
|
||||
else if (isMethod())
|
||||
injectMethod((Method)_target, injectable);
|
||||
else
|
||||
throw new IllegalStateException("Neither field nor method injection");
|
||||
}
|
||||
|
||||
/**
|
||||
* The Resource must already exist in the ENC of this webapp.
|
||||
*
|
||||
* @return the injected valud
|
||||
* @throws NamingException if unable to lookup value
|
||||
*/
|
||||
public Object lookupInjectedValue()
|
||||
throws NamingException
|
||||
{
|
||||
InitialContext context = new InitialContext();
|
||||
return context.lookup("java:comp/env/" + getJndiName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject value from jndi into a field of an instance
|
||||
*
|
||||
* @param field the field to inject into
|
||||
* @param injectable the value to inject
|
||||
*/
|
||||
protected void injectField(Field field, Object injectable)
|
||||
{
|
||||
try
|
||||
{
|
||||
boolean accessibility = field.isAccessible();
|
||||
field.setAccessible(true);
|
||||
field.set(injectable, lookupInjectedValue());
|
||||
field.setAccessible(accessibility);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn("Unable to inject field {} with {}", field, injectable, e);
|
||||
throw new IllegalStateException("Inject failed for field " + field.getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject value from jndi into a setter method of an instance
|
||||
*
|
||||
* @param method the method to inject into
|
||||
* @param injectable the value to inject
|
||||
*/
|
||||
protected void injectMethod(Method method, Object injectable)
|
||||
{
|
||||
try
|
||||
{
|
||||
boolean accessibility = method.isAccessible();
|
||||
method.setAccessible(true);
|
||||
method.invoke(injectable, new Object[]{lookupInjectedValue()});
|
||||
method.setAccessible(accessibility);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn("Unable to inject method {} with {}", method, injectable, e);
|
||||
throw new IllegalStateException("Inject failed for method " + method.getName());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,139 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.ee10.plus.annotation;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* InjectionCollection
|
||||
* Map of classname to all injections requested on that class,
|
||||
* whether by declaration in web.xml or via equivalent annotations.
|
||||
*
|
||||
* This class is not threadsafe for concurrent modifications, but is
|
||||
* threadsafe for readers with concurrent modifications.
|
||||
*/
|
||||
public class InjectionCollection
|
||||
{
|
||||
private static final Logger LOG = LoggerFactory.getLogger(InjectionCollection.class);
|
||||
|
||||
public static final String INJECTION_COLLECTION = "org.eclipse.jetty.injectionCollection";
|
||||
|
||||
private final ConcurrentMap<String, Set<Injection>> _injectionMap = new ConcurrentHashMap<>(); //map of classname to injections
|
||||
|
||||
public void add(Injection injection)
|
||||
{
|
||||
if (injection == null)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Ignoring null Injection");
|
||||
return;
|
||||
}
|
||||
|
||||
String name = injection.getTargetClass().getName();
|
||||
|
||||
Set<Injection> injections = _injectionMap.get(name);
|
||||
if (injections == null)
|
||||
{
|
||||
injections = new CopyOnWriteArraySet<>();
|
||||
Set<Injection> tmp = _injectionMap.putIfAbsent(name, injections);
|
||||
if (tmp != null)
|
||||
injections = tmp;
|
||||
}
|
||||
|
||||
boolean added = injections.add(injection);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Adding injection for class={} on {} added={}", name, injection.getTarget().getName(), added);
|
||||
}
|
||||
|
||||
public Set<Injection> getInjections(String className)
|
||||
{
|
||||
if (className == null)
|
||||
return null;
|
||||
|
||||
return _injectionMap.get(className);
|
||||
}
|
||||
|
||||
public Injection getInjection(String jndiName, Class<?> clazz, Field field)
|
||||
{
|
||||
if (field == null || clazz == null)
|
||||
return null;
|
||||
|
||||
Set<Injection> injections = getInjections(clazz.getName());
|
||||
if (injections == null)
|
||||
return null;
|
||||
Iterator<Injection> itor = injections.iterator();
|
||||
Injection injection = null;
|
||||
while (itor.hasNext() && injection == null)
|
||||
{
|
||||
Injection i = itor.next();
|
||||
if (i.isField() && field.getName().equals(i.getTarget().getName()))
|
||||
injection = i;
|
||||
}
|
||||
|
||||
return injection;
|
||||
}
|
||||
|
||||
public Injection getInjection(String jndiName, Class<?> clazz, Method method, Class<?> paramClass)
|
||||
{
|
||||
if (clazz == null || method == null || paramClass == null)
|
||||
return null;
|
||||
|
||||
Set<Injection> injections = getInjections(clazz.getName());
|
||||
if (injections == null)
|
||||
return null;
|
||||
Iterator<Injection> itor = injections.iterator();
|
||||
Injection injection = null;
|
||||
while (itor.hasNext() && injection == null)
|
||||
{
|
||||
Injection i = itor.next();
|
||||
if (i.isMethod() && i.getTarget().getName().equals(method.getName()) && paramClass.equals(i.getParamClass()))
|
||||
injection = i;
|
||||
}
|
||||
|
||||
return injection;
|
||||
}
|
||||
|
||||
public void inject(Object injectable)
|
||||
{
|
||||
if (injectable == null)
|
||||
return;
|
||||
|
||||
//Get all injections pertinent to the Object by
|
||||
//looking at it's class hierarchy
|
||||
Class<?> clazz = injectable.getClass();
|
||||
|
||||
while (clazz != null)
|
||||
{
|
||||
Set<Injection> injections = _injectionMap.get(clazz.getName());
|
||||
if (injections != null)
|
||||
{
|
||||
for (Injection i : injections)
|
||||
{
|
||||
i.inject(injectable);
|
||||
}
|
||||
}
|
||||
|
||||
clazz = clazz.getSuperclass();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,170 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.ee10.plus.annotation;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.eclipse.jetty.util.IntrospectionUtil;
|
||||
import org.eclipse.jetty.util.Loader;
|
||||
import org.eclipse.jetty.util.TypeUtil;
|
||||
|
||||
/**
|
||||
* LifeCycleCallback
|
||||
*
|
||||
* Holds information about a class and method
|
||||
* that has either been configured in web.xml to have postconstruct or
|
||||
* predestroy callbacks, or has the equivalent annotations.
|
||||
*/
|
||||
public abstract class LifeCycleCallback
|
||||
{
|
||||
public static final Object[] __EMPTY_ARGS = new Object[]{};
|
||||
private Method _target;
|
||||
private Class<?> _targetClass; //Not final so we can do lazy load
|
||||
private final String _className;
|
||||
private final String _methodName;
|
||||
|
||||
public LifeCycleCallback(String className, String methodName)
|
||||
{
|
||||
_className = Objects.requireNonNull(className);
|
||||
_methodName = Objects.requireNonNull(methodName);
|
||||
}
|
||||
|
||||
public LifeCycleCallback(Class<?> clazz, String methodName)
|
||||
{
|
||||
_targetClass = Objects.requireNonNull(clazz);
|
||||
_methodName = Objects.requireNonNull(methodName);
|
||||
try
|
||||
{
|
||||
Method method = IntrospectionUtil.findMethod(clazz, methodName, null, true, true);
|
||||
validate(clazz, method);
|
||||
_target = method;
|
||||
_className = clazz.getName();
|
||||
}
|
||||
catch (NoSuchMethodException e)
|
||||
{
|
||||
throw new IllegalArgumentException("Method " + methodName + " not found on class " + clazz.getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the _targetClass
|
||||
*/
|
||||
public Class<?> getTargetClass()
|
||||
{
|
||||
return _targetClass;
|
||||
}
|
||||
|
||||
public String getTargetClassName()
|
||||
{
|
||||
return _className;
|
||||
}
|
||||
|
||||
public String getMethodName()
|
||||
{
|
||||
return _methodName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the target.
|
||||
* @return the target
|
||||
*/
|
||||
public Method getTarget()
|
||||
{
|
||||
return _target;
|
||||
}
|
||||
|
||||
public void callback(Object instance)
|
||||
throws SecurityException, NoSuchMethodException, ClassNotFoundException, IllegalArgumentException, IllegalAccessException, InvocationTargetException
|
||||
{
|
||||
if (_target == null) //lazy load the target class
|
||||
{
|
||||
if (_targetClass == null)
|
||||
_targetClass = Loader.loadClass(_className);
|
||||
_target = _targetClass.getDeclaredMethod(_methodName, TypeUtil.NO_ARGS);
|
||||
}
|
||||
|
||||
if (_target != null)
|
||||
{
|
||||
boolean accessibility = getTarget().isAccessible();
|
||||
getTarget().setAccessible(true);
|
||||
getTarget().invoke(instance, __EMPTY_ARGS);
|
||||
getTarget().setAccessible(accessibility);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a method of the given name either directly in the given
|
||||
* class, or inherited.
|
||||
*
|
||||
* @param pack the package of the class under inspection
|
||||
* @param clazz the class under inspection
|
||||
* @param methodName the method to find
|
||||
* @param checkInheritance false on first entry, true if a superclass is being introspected
|
||||
* @return the method
|
||||
*/
|
||||
public Method findMethod(Package pack, Class<?> clazz, String methodName, boolean checkInheritance)
|
||||
{
|
||||
if (clazz == null)
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
Method method = clazz.getDeclaredMethod(methodName);
|
||||
if (checkInheritance)
|
||||
{
|
||||
int modifiers = method.getModifiers();
|
||||
if (Modifier.isProtected(modifiers) || Modifier.isPublic(modifiers) || (!Modifier.isPrivate(modifiers) && (pack.equals(clazz.getPackage()))))
|
||||
return method;
|
||||
else
|
||||
return findMethod(clazz.getPackage(), clazz.getSuperclass(), methodName, true);
|
||||
}
|
||||
return method;
|
||||
}
|
||||
catch (NoSuchMethodException e)
|
||||
{
|
||||
return findMethod(clazz.getPackage(), clazz.getSuperclass(), methodName, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return Objects.hash(_className, _methodName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (o == null)
|
||||
return false;
|
||||
|
||||
if (this == o)
|
||||
return true;
|
||||
|
||||
if (!LifeCycleCallback.class.isInstance(o))
|
||||
return false;
|
||||
|
||||
LifeCycleCallback callback = (LifeCycleCallback)o;
|
||||
|
||||
if (getTargetClassName().equals(callback.getTargetClassName()) && getMethodName().equals(callback.getMethodName()))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public abstract void validate(Class<?> clazz, Method m);
|
||||
}
|
|
@ -1,197 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.ee10.plus.annotation;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* LifeCycleCallbackCollection
|
||||
*
|
||||
* This class collects the classes and methods that have been configured
|
||||
* in web.xml with postconstruct/predestroy callbacks, or that contain the
|
||||
* equivalent annotations. It is also responsible for calling the
|
||||
* callbacks.
|
||||
*
|
||||
* This class is not threadsafe for concurrent modifications, but is
|
||||
* threadsafe for reading with concurrent modifications.
|
||||
*/
|
||||
public class LifeCycleCallbackCollection
|
||||
{
|
||||
private static final Logger LOG = LoggerFactory.getLogger(LifeCycleCallbackCollection.class);
|
||||
|
||||
public static final String LIFECYCLE_CALLBACK_COLLECTION = "org.eclipse.jetty.lifecyleCallbackCollection";
|
||||
|
||||
private final ConcurrentMap<String, Set<LifeCycleCallback>> postConstructCallbacksMap = new ConcurrentHashMap<>();
|
||||
private final ConcurrentMap<String, Set<LifeCycleCallback>> preDestroyCallbacksMap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Add a Callback to the list of callbacks.
|
||||
*
|
||||
* @param callback the callback
|
||||
*/
|
||||
public void add(LifeCycleCallback callback)
|
||||
{
|
||||
if (callback == null)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Ignoring empty LifeCycleCallback");
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, Set<LifeCycleCallback>> map = null;
|
||||
if (callback instanceof PreDestroyCallback)
|
||||
map = preDestroyCallbacksMap;
|
||||
else if (callback instanceof PostConstructCallback)
|
||||
map = postConstructCallbacksMap;
|
||||
else
|
||||
throw new IllegalArgumentException("Unsupported lifecycle callback type: " + callback);
|
||||
|
||||
Set<LifeCycleCallback> callbacks = map.get(callback.getTargetClassName());
|
||||
if (callbacks == null)
|
||||
{
|
||||
callbacks = new CopyOnWriteArraySet<LifeCycleCallback>();
|
||||
Set<LifeCycleCallback> tmp = map.putIfAbsent(callback.getTargetClassName(), callbacks);
|
||||
if (tmp != null)
|
||||
callbacks = tmp;
|
||||
}
|
||||
|
||||
boolean added = callbacks.add(callback);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Adding callback for class={} on method={} added={}", callback.getTargetClassName(), callback.getMethodName(), added);
|
||||
}
|
||||
|
||||
public Set<LifeCycleCallback> getPreDestroyCallbacks(Object o)
|
||||
{
|
||||
if (o == null)
|
||||
return null;
|
||||
|
||||
Class<? extends Object> clazz = o.getClass();
|
||||
return preDestroyCallbacksMap.get(clazz.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Amalgamate all pre-destroy callbacks and return a read only set
|
||||
*
|
||||
* @return the collection of {@link PreDestroyCallback}s
|
||||
*/
|
||||
public Collection<LifeCycleCallback> getPreDestroyCallbacks()
|
||||
{
|
||||
Set<LifeCycleCallback> set = new HashSet<LifeCycleCallback>();
|
||||
for (String s : preDestroyCallbacksMap.keySet())
|
||||
{
|
||||
set.addAll(preDestroyCallbacksMap.get(s));
|
||||
}
|
||||
return Collections.unmodifiableCollection(set);
|
||||
}
|
||||
|
||||
public Set<LifeCycleCallback> getPostConstructCallbacks(Object o)
|
||||
{
|
||||
if (o == null)
|
||||
return null;
|
||||
|
||||
Class<? extends Object> clazz = o.getClass();
|
||||
return postConstructCallbacksMap.get(clazz.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Amalgamate all post-construct callbacks and return a read only set
|
||||
*
|
||||
* @return the collection of {@link PostConstructCallback}s
|
||||
*/
|
||||
public Collection<LifeCycleCallback> getPostConstructCallbacks()
|
||||
{
|
||||
Set<LifeCycleCallback> set = new HashSet<LifeCycleCallback>();
|
||||
for (String s : postConstructCallbacksMap.keySet())
|
||||
{
|
||||
set.addAll(postConstructCallbacksMap.get(s));
|
||||
}
|
||||
return Collections.unmodifiableCollection(set);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the method, if one exists, that is annotated with <code>@PostConstruct</code>
|
||||
* or with <code><post-construct></code> in web.xml
|
||||
*
|
||||
* @param o the object on which to attempt the callback
|
||||
* @throws Exception if unable to call {@link PostConstructCallback}
|
||||
*/
|
||||
public void callPostConstructCallback(Object o)
|
||||
throws Exception
|
||||
{
|
||||
if (o == null)
|
||||
return;
|
||||
|
||||
Class<? extends Object> clazz = o.getClass();
|
||||
Set<LifeCycleCallback> callbacks = postConstructCallbacksMap.get(clazz.getName());
|
||||
|
||||
if (callbacks == null)
|
||||
return;
|
||||
|
||||
for (LifeCycleCallback l : callbacks)
|
||||
l.callback(o);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the method, if one exists, that is annotated with <code>@PreDestroy</code>
|
||||
* or with <code><pre-destroy></code> in web.xml
|
||||
*
|
||||
* @param o the object on which to attempt the callback
|
||||
* @throws Exception if unable to call {@link PreDestroyCallback}
|
||||
*/
|
||||
public void callPreDestroyCallback(Object o)
|
||||
throws Exception
|
||||
{
|
||||
if (o == null)
|
||||
return;
|
||||
|
||||
Class<? extends Object> clazz = o.getClass();
|
||||
Set<LifeCycleCallback> callbacks = preDestroyCallbacksMap.get(clazz.getName());
|
||||
|
||||
if (callbacks == null)
|
||||
return;
|
||||
|
||||
for (LifeCycleCallback l : callbacks)
|
||||
l.callback(o);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a read-only view of the post-construct callbacks
|
||||
*
|
||||
* @return the map of {@link PostConstructCallback}s
|
||||
*/
|
||||
public Map<String, Set<LifeCycleCallback>> getPostConstructCallbackMap()
|
||||
{
|
||||
return Collections.unmodifiableMap(postConstructCallbacksMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a read-only view of the pre-destroy callbacks
|
||||
*
|
||||
* @return the map of {@link PreDestroyCallback}s
|
||||
*/
|
||||
public Map<String, Set<LifeCycleCallback>> getPreDestroyCallbackMap()
|
||||
{
|
||||
return Collections.unmodifiableMap(preDestroyCallbacksMap);
|
||||
}
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.ee10.plus.annotation;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
/**
|
||||
* PostConstructCallback
|
||||
*/
|
||||
public class PostConstructCallback extends LifeCycleCallback
|
||||
{
|
||||
|
||||
/**
|
||||
* @param clazz the class object to be injected
|
||||
* @param methodName the name of the method to be injected
|
||||
*/
|
||||
public PostConstructCallback(Class<?> clazz, String methodName)
|
||||
{
|
||||
super(clazz, methodName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param className the name of the class to be injected
|
||||
* @param methodName the name of the method to be injected
|
||||
*/
|
||||
public PostConstructCallback(String className, String methodName)
|
||||
{
|
||||
super(className, methodName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Commons Annotation Specification section 2.5
|
||||
* - no params
|
||||
* - must be void return
|
||||
* - no checked exceptions
|
||||
* - cannot be static
|
||||
*
|
||||
* @see LifeCycleCallback#validate(java.lang.Class, java.lang.reflect.Method)
|
||||
*/
|
||||
@Override
|
||||
public void validate(Class<?> clazz, Method method)
|
||||
{
|
||||
if (method.getExceptionTypes().length > 0)
|
||||
throw new IllegalArgumentException(clazz.getName() + "." + method.getName() + " cannot not throw a checked exception");
|
||||
|
||||
if (!method.getReturnType().equals(Void.TYPE))
|
||||
throw new IllegalArgumentException(clazz.getName() + "." + method.getName() + " cannot not have a return type");
|
||||
|
||||
if (Modifier.isStatic(method.getModifiers()))
|
||||
throw new IllegalArgumentException(clazz.getName() + "." + method.getName() + " cannot be static");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void callback(Object instance)
|
||||
throws SecurityException, IllegalArgumentException, NoSuchMethodException, ClassNotFoundException, IllegalAccessException, InvocationTargetException
|
||||
{
|
||||
super.callback(instance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (super.equals(o) && (o instanceof PostConstructCallback))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.ee10.plus.annotation;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* PreDestroyCallback
|
||||
*/
|
||||
public class PreDestroyCallback extends LifeCycleCallback
|
||||
{
|
||||
private static final Logger LOG = LoggerFactory.getLogger(PreDestroyCallback.class);
|
||||
|
||||
/**
|
||||
* @param clazz the class object to be injected
|
||||
* @param methodName the name of the method to inject
|
||||
*/
|
||||
public PreDestroyCallback(Class<?> clazz, String methodName)
|
||||
{
|
||||
super(clazz, methodName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param className the name of the class to inject
|
||||
* @param methodName the name of the method to inject
|
||||
*/
|
||||
public PreDestroyCallback(String className, String methodName)
|
||||
{
|
||||
super(className, methodName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Commons Annotations Specification section 2.6:
|
||||
* - no params to method
|
||||
* - returns void
|
||||
* - no checked exceptions
|
||||
* - not static
|
||||
*
|
||||
* @see LifeCycleCallback#validate(java.lang.Class, java.lang.reflect.Method)
|
||||
*/
|
||||
@Override
|
||||
public void validate(Class<?> clazz, Method method)
|
||||
{
|
||||
|
||||
if (method.getExceptionTypes().length > 0)
|
||||
throw new IllegalArgumentException(clazz.getName() + "." + method.getName() + " cannot not throw a checked exception");
|
||||
|
||||
if (!method.getReturnType().equals(Void.TYPE))
|
||||
throw new IllegalArgumentException(clazz.getName() + "." + method.getName() + " cannot not have a return type");
|
||||
|
||||
if (Modifier.isStatic(method.getModifiers()))
|
||||
throw new IllegalArgumentException(clazz.getName() + "." + method.getName() + " cannot be static");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void callback(Object instance)
|
||||
{
|
||||
try
|
||||
{
|
||||
super.callback(instance);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn("Ignoring exception thrown on preDestroy call to {}.{}", getTargetClass(), getTarget().getName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (super.equals(o) && (o instanceof PreDestroyCallback))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.ee10.plus.annotation;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.eclipse.jetty.ee10.servlet.ServletHolder;
|
||||
|
||||
/**
|
||||
* RunAs
|
||||
* <p>
|
||||
* Represents a <code><run-as></code> element in web.xml, or a <code>@RunAs</code> annotation.
|
||||
* @deprecated unused as of 9.4.28 due for removal in 10.0.0
|
||||
*/
|
||||
@Deprecated
|
||||
public class RunAs
|
||||
{
|
||||
private String _className;
|
||||
private String _roleName;
|
||||
|
||||
public RunAs(String className, String roleName)
|
||||
{
|
||||
_className = Objects.requireNonNull(className);
|
||||
_roleName = Objects.requireNonNull(roleName);
|
||||
}
|
||||
|
||||
public String getTargetClassName()
|
||||
{
|
||||
return _className;
|
||||
}
|
||||
|
||||
public String getRoleName()
|
||||
{
|
||||
return _roleName;
|
||||
}
|
||||
|
||||
public void setRunAs(ServletHolder holder)
|
||||
{
|
||||
if (holder == null)
|
||||
return;
|
||||
String className = holder.getClassName();
|
||||
|
||||
if (className.equals(_className))
|
||||
{
|
||||
//Only set the RunAs if it has not already been set, presumably by web/web-fragment.xml
|
||||
if (holder.getRegistration().getRunAsRole() == null)
|
||||
holder.getRegistration().setRunAsRole(_roleName);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.ee10.plus.annotation;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import org.eclipse.jetty.ee10.servlet.ServletHolder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* RunAsCollection
|
||||
* @deprecated class unused as of 9.4.28 due for removal in 10.0.0
|
||||
*/
|
||||
@Deprecated
|
||||
public class RunAsCollection
|
||||
{
|
||||
private static final Logger LOG = LoggerFactory.getLogger(RunAsCollection.class);
|
||||
|
||||
public static final String RUNAS_COLLECTION = "org.eclipse.jetty.runAsCollection";
|
||||
private ConcurrentMap<String, RunAs> _runAsMap = new ConcurrentHashMap<String, RunAs>(); //map of classname to run-as
|
||||
|
||||
public void add(RunAs runAs)
|
||||
{
|
||||
if ((runAs == null) || (runAs.getTargetClassName() == null))
|
||||
return;
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Adding run-as for class=" + runAs.getTargetClassName());
|
||||
RunAs prev = _runAsMap.putIfAbsent(runAs.getTargetClassName(), runAs);
|
||||
if (prev != null)
|
||||
LOG.warn("Run-As {} on class {} ignored, already run-as {}", runAs.getRoleName(), runAs.getTargetClassName(), prev.getRoleName());
|
||||
}
|
||||
|
||||
public RunAs getRunAs(Object o)
|
||||
{
|
||||
if (o == null)
|
||||
return null;
|
||||
|
||||
return (RunAs)_runAsMap.get(o.getClass().getName());
|
||||
}
|
||||
|
||||
public void setRunAs(Object o)
|
||||
{
|
||||
if (o == null)
|
||||
return;
|
||||
|
||||
if (!ServletHolder.class.isAssignableFrom(o.getClass()))
|
||||
return;
|
||||
|
||||
RunAs runAs = (RunAs)_runAsMap.get(o.getClass().getName());
|
||||
if (runAs == null)
|
||||
return;
|
||||
|
||||
runAs.setRunAs((ServletHolder)o);
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
/**
|
||||
* Jetty Plus : Limited JEE Annotation Support
|
||||
*/
|
||||
package org.eclipse.jetty.ee10.plus.annotation;
|
|
@ -1,465 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.ee10.plus.security;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.naming.InitialContext;
|
||||
import javax.naming.NameNotFoundException;
|
||||
import javax.naming.NamingException;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.eclipse.jetty.plus.jndi.NamingEntryUtil;
|
||||
import org.eclipse.jetty.security.AbstractLoginService;
|
||||
import org.eclipse.jetty.security.IdentityService;
|
||||
import org.eclipse.jetty.security.RolePrincipal;
|
||||
import org.eclipse.jetty.security.UserPrincipal;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.util.security.Credential;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* DataSourceLoginService
|
||||
* <p>
|
||||
* Obtain user/password/role information from a database via jndi DataSource.
|
||||
*/
|
||||
public class DataSourceLoginService extends AbstractLoginService
|
||||
{
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DataSourceLoginService.class);
|
||||
|
||||
private String _jndiName = "javax.sql.DataSource/default";
|
||||
private DataSource _datasource;
|
||||
private Server _server;
|
||||
private String _userTableName = "users";
|
||||
private String _userTableKey = "id";
|
||||
private String _userTableUserField = "username";
|
||||
private String _userTablePasswordField = "pwd";
|
||||
private String _roleTableName = "roles";
|
||||
private String _roleTableKey = "id";
|
||||
private String _roleTableRoleField = "role";
|
||||
private String _userRoleTableName = "user_roles";
|
||||
private String _userRoleTableUserKey = "user_id";
|
||||
private String _userRoleTableRoleKey = "role_id";
|
||||
private String _userSql;
|
||||
private String _roleSql;
|
||||
private boolean _createTables = false;
|
||||
|
||||
/**
|
||||
* DBUser
|
||||
*/
|
||||
public class DBUserPrincipal extends UserPrincipal
|
||||
{
|
||||
private int _key;
|
||||
|
||||
public DBUserPrincipal(String name, Credential credential, int key)
|
||||
{
|
||||
super(name, credential);
|
||||
_key = key;
|
||||
}
|
||||
|
||||
public int getKey()
|
||||
{
|
||||
return _key;
|
||||
}
|
||||
}
|
||||
|
||||
public DataSourceLoginService()
|
||||
{
|
||||
}
|
||||
|
||||
public DataSourceLoginService(String name)
|
||||
{
|
||||
setName(name);
|
||||
}
|
||||
|
||||
public DataSourceLoginService(String name, IdentityService identityService)
|
||||
{
|
||||
setName(name);
|
||||
setIdentityService(identityService);
|
||||
}
|
||||
|
||||
public void setJndiName(String jndi)
|
||||
{
|
||||
_jndiName = jndi;
|
||||
}
|
||||
|
||||
public String getJndiName()
|
||||
{
|
||||
return _jndiName;
|
||||
}
|
||||
|
||||
public void setServer(Server server)
|
||||
{
|
||||
_server = server;
|
||||
}
|
||||
|
||||
public Server getServer()
|
||||
{
|
||||
return _server;
|
||||
}
|
||||
|
||||
public void setCreateTables(boolean createTables)
|
||||
{
|
||||
_createTables = createTables;
|
||||
}
|
||||
|
||||
public boolean getCreateTables()
|
||||
{
|
||||
return _createTables;
|
||||
}
|
||||
|
||||
public void setUserTableName(String name)
|
||||
{
|
||||
_userTableName = name;
|
||||
}
|
||||
|
||||
public String getUserTableName()
|
||||
{
|
||||
return _userTableName;
|
||||
}
|
||||
|
||||
public String getUserTableKey()
|
||||
{
|
||||
return _userTableKey;
|
||||
}
|
||||
|
||||
public void setUserTableKey(String tableKey)
|
||||
{
|
||||
_userTableKey = tableKey;
|
||||
}
|
||||
|
||||
public String getUserTableUserField()
|
||||
{
|
||||
return _userTableUserField;
|
||||
}
|
||||
|
||||
public void setUserTableUserField(String tableUserField)
|
||||
{
|
||||
_userTableUserField = tableUserField;
|
||||
}
|
||||
|
||||
public String getUserTablePasswordField()
|
||||
{
|
||||
return _userTablePasswordField;
|
||||
}
|
||||
|
||||
public void setUserTablePasswordField(String tablePasswordField)
|
||||
{
|
||||
_userTablePasswordField = tablePasswordField;
|
||||
}
|
||||
|
||||
public String getRoleTableName()
|
||||
{
|
||||
return _roleTableName;
|
||||
}
|
||||
|
||||
public void setRoleTableName(String tableName)
|
||||
{
|
||||
_roleTableName = tableName;
|
||||
}
|
||||
|
||||
public String getRoleTableKey()
|
||||
{
|
||||
return _roleTableKey;
|
||||
}
|
||||
|
||||
public void setRoleTableKey(String tableKey)
|
||||
{
|
||||
_roleTableKey = tableKey;
|
||||
}
|
||||
|
||||
public String getRoleTableRoleField()
|
||||
{
|
||||
return _roleTableRoleField;
|
||||
}
|
||||
|
||||
public void setRoleTableRoleField(String tableRoleField)
|
||||
{
|
||||
_roleTableRoleField = tableRoleField;
|
||||
}
|
||||
|
||||
public String getUserRoleTableName()
|
||||
{
|
||||
return _userRoleTableName;
|
||||
}
|
||||
|
||||
public void setUserRoleTableName(String roleTableName)
|
||||
{
|
||||
_userRoleTableName = roleTableName;
|
||||
}
|
||||
|
||||
public String getUserRoleTableUserKey()
|
||||
{
|
||||
return _userRoleTableUserKey;
|
||||
}
|
||||
|
||||
public void setUserRoleTableUserKey(String roleTableUserKey)
|
||||
{
|
||||
_userRoleTableUserKey = roleTableUserKey;
|
||||
}
|
||||
|
||||
public String getUserRoleTableRoleKey()
|
||||
{
|
||||
return _userRoleTableRoleKey;
|
||||
}
|
||||
|
||||
public void setUserRoleTableRoleKey(String roleTableRoleKey)
|
||||
{
|
||||
_userRoleTableRoleKey = roleTableRoleKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserPrincipal loadUserInfo(String username)
|
||||
{
|
||||
try
|
||||
{
|
||||
try (Connection connection = getConnection();
|
||||
PreparedStatement statement1 = connection.prepareStatement(_userSql))
|
||||
{
|
||||
statement1.setObject(1, username);
|
||||
try (ResultSet rs1 = statement1.executeQuery())
|
||||
{
|
||||
if (rs1.next())
|
||||
{
|
||||
int key = rs1.getInt(_userTableKey);
|
||||
String credentials = rs1.getString(_userTablePasswordField);
|
||||
|
||||
return new DBUserPrincipal(username, Credential.getCredential(credentials), key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NamingException e)
|
||||
{
|
||||
LOG.warn("No datasource for {}", _jndiName, e);
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
LOG.warn("Problem loading user info for {}", username, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RolePrincipal> loadRoleInfo(UserPrincipal user)
|
||||
{
|
||||
DBUserPrincipal dbuser = (DBUserPrincipal)user;
|
||||
|
||||
try
|
||||
{
|
||||
try (Connection connection = getConnection();
|
||||
PreparedStatement statement2 = connection.prepareStatement(_roleSql))
|
||||
{
|
||||
|
||||
List<String> roles = new ArrayList<String>();
|
||||
|
||||
statement2.setInt(1, dbuser.getKey());
|
||||
try (ResultSet rs2 = statement2.executeQuery())
|
||||
{
|
||||
while (rs2.next())
|
||||
roles.add(rs2.getString(_roleTableRoleField));
|
||||
|
||||
return roles.stream().map(RolePrincipal::new).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NamingException e)
|
||||
{
|
||||
LOG.warn("No datasource for {}", _jndiName, e);
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
LOG.warn("Problem loading user info for {}", user.getName(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup the datasource for the jndiName and formulate the
|
||||
* necessary sql query strings based on the configured table
|
||||
* and column names.
|
||||
*
|
||||
* @throws NamingException if unable to init jndi
|
||||
* @throws SQLException if unable to init database
|
||||
*/
|
||||
public void initDb() throws NamingException, SQLException
|
||||
{
|
||||
if (_datasource != null)
|
||||
return;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
InitialContext ic = new InitialContext();
|
||||
assert ic != null;
|
||||
|
||||
// TODO Should we try webapp scope too?
|
||||
|
||||
// try finding the datasource in the Server scope
|
||||
if (_server != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
_datasource = (DataSource)NamingEntryUtil.lookup(_server, _jndiName);
|
||||
}
|
||||
catch (NameNotFoundException e)
|
||||
{
|
||||
//next try the jvm scope
|
||||
}
|
||||
}
|
||||
|
||||
//try finding the datasource in the jvm scope
|
||||
if (_datasource == null)
|
||||
{
|
||||
_datasource = (DataSource)NamingEntryUtil.lookup(null, _jndiName);
|
||||
}
|
||||
|
||||
// set up the select statements based on the table and column names configured
|
||||
_userSql = "select " + _userTableKey + "," + _userTablePasswordField +
|
||||
" from " + _userTableName +
|
||||
" where " + _userTableUserField + " = ?";
|
||||
|
||||
_roleSql = "select r." + _roleTableRoleField +
|
||||
" from " + _roleTableName + " r, " + _userRoleTableName +
|
||||
" u where u." + _userRoleTableUserKey + " = ?" +
|
||||
" and r." + _roleTableKey + " = u." + _userRoleTableRoleKey;
|
||||
|
||||
prepareTables();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private void prepareTables()
|
||||
throws NamingException, SQLException
|
||||
{
|
||||
if (_createTables)
|
||||
{
|
||||
boolean autocommit = true;
|
||||
Connection connection = getConnection();
|
||||
try (Statement stmt = connection.createStatement())
|
||||
{
|
||||
autocommit = connection.getAutoCommit();
|
||||
connection.setAutoCommit(false);
|
||||
DatabaseMetaData metaData = connection.getMetaData();
|
||||
|
||||
//check if tables exist
|
||||
String tableName = (metaData.storesLowerCaseIdentifiers() ? _userTableName.toLowerCase(Locale.ENGLISH) : (metaData.storesUpperCaseIdentifiers() ? _userTableName.toUpperCase(Locale.ENGLISH) : _userTableName));
|
||||
try (ResultSet result = metaData.getTables(null, null, tableName, null))
|
||||
{
|
||||
if (!result.next())
|
||||
{
|
||||
//user table default
|
||||
/*
|
||||
* create table _userTableName (_userTableKey integer,
|
||||
* _userTableUserField varchar(100) not null unique,
|
||||
* _userTablePasswordField varchar(20) not null, primary key(_userTableKey));
|
||||
*/
|
||||
stmt.executeUpdate("create table " + _userTableName + "(" + _userTableKey + " integer," +
|
||||
_userTableUserField + " varchar(100) not null unique," +
|
||||
_userTablePasswordField + " varchar(20) not null, primary key(" + _userTableKey + "))");
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Created table {}", _userTableName);
|
||||
}
|
||||
}
|
||||
|
||||
tableName = (metaData.storesLowerCaseIdentifiers() ? _roleTableName.toLowerCase(Locale.ENGLISH) : (metaData.storesUpperCaseIdentifiers() ? _roleTableName.toUpperCase(Locale.ENGLISH) : _roleTableName));
|
||||
try (ResultSet result = metaData.getTables(null, null, tableName, null))
|
||||
{
|
||||
if (!result.next())
|
||||
{
|
||||
//role table default
|
||||
/*
|
||||
* create table _roleTableName (_roleTableKey integer,
|
||||
* _roleTableRoleField varchar(100) not null unique, primary key(_roleTableKey));
|
||||
*/
|
||||
String str = "create table " + _roleTableName + " (" + _roleTableKey + " integer, " +
|
||||
_roleTableRoleField + " varchar(100) not null unique, primary key(" + _roleTableKey + "))";
|
||||
stmt.executeUpdate(str);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Created table {}", _roleTableName);
|
||||
}
|
||||
}
|
||||
|
||||
tableName = (metaData.storesLowerCaseIdentifiers() ? _userRoleTableName.toLowerCase(Locale.ENGLISH) : (metaData.storesUpperCaseIdentifiers() ? _userRoleTableName.toUpperCase(Locale.ENGLISH) : _userRoleTableName));
|
||||
try (ResultSet result = metaData.getTables(null, null, tableName, null))
|
||||
{
|
||||
if (!result.next())
|
||||
{
|
||||
//user-role table
|
||||
/*
|
||||
* create table _userRoleTableName (_userRoleTableUserKey integer,
|
||||
* _userRoleTableRoleKey integer,
|
||||
* primary key (_userRoleTableUserKey, _userRoleTableRoleKey));
|
||||
*
|
||||
* create index idx_user_role on _userRoleTableName (_userRoleTableUserKey);
|
||||
*/
|
||||
stmt.executeUpdate("create table " + _userRoleTableName + " (" + _userRoleTableUserKey + " integer, " +
|
||||
_userRoleTableRoleKey + " integer, " +
|
||||
"primary key (" + _userRoleTableUserKey + ", " + _userRoleTableRoleKey + "))");
|
||||
stmt.executeUpdate("create index indx_user_role on " + _userRoleTableName + "(" + _userRoleTableUserKey + ")");
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Created table {} and index", _userRoleTableName);
|
||||
}
|
||||
}
|
||||
connection.commit();
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
connection.setAutoCommit(autocommit);
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Prepare tables", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
connection.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Prepare tables", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("createTables false");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private Connection getConnection()
|
||||
throws NamingException, SQLException
|
||||
{
|
||||
initDb();
|
||||
return _datasource.getConnection();
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
/**
|
||||
* Jetty Plus : Limited JEE Security Support
|
||||
*/
|
||||
package org.eclipse.jetty.ee10.plus.security;
|
|
@ -17,8 +17,6 @@ import javax.naming.Context;
|
|||
import javax.naming.InitialContext;
|
||||
import javax.naming.NameNotFoundException;
|
||||
|
||||
import org.eclipse.jetty.ee10.plus.annotation.InjectionCollection;
|
||||
import org.eclipse.jetty.ee10.plus.annotation.LifeCycleCallbackCollection;
|
||||
import org.eclipse.jetty.ee10.plus.jndi.Transaction;
|
||||
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.ee10.webapp.AbstractConfiguration;
|
||||
|
@ -27,6 +25,8 @@ import org.eclipse.jetty.ee10.webapp.JettyWebXmlConfiguration;
|
|||
import org.eclipse.jetty.ee10.webapp.MetaInfConfiguration;
|
||||
import org.eclipse.jetty.ee10.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.ee10.webapp.WebXmlConfiguration;
|
||||
import org.eclipse.jetty.plus.annotation.InjectionCollection;
|
||||
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
|
||||
import org.eclipse.jetty.util.NanoTime;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
|
||||
package org.eclipse.jetty.ee10.plus.webapp;
|
||||
|
||||
import org.eclipse.jetty.ee10.plus.annotation.InjectionCollection;
|
||||
import org.eclipse.jetty.ee10.plus.annotation.LifeCycleCallbackCollection;
|
||||
import org.eclipse.jetty.ee10.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.plus.annotation.InjectionCollection;
|
||||
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
|
||||
import org.eclipse.jetty.util.Decorator;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
|
|
@ -19,17 +19,17 @@ import javax.naming.Context;
|
|||
import javax.naming.InitialContext;
|
||||
import javax.naming.NameNotFoundException;
|
||||
|
||||
import org.eclipse.jetty.ee10.plus.annotation.Injection;
|
||||
import org.eclipse.jetty.ee10.plus.annotation.InjectionCollection;
|
||||
import org.eclipse.jetty.ee10.plus.annotation.LifeCycleCallback;
|
||||
import org.eclipse.jetty.ee10.plus.annotation.LifeCycleCallbackCollection;
|
||||
import org.eclipse.jetty.ee10.plus.annotation.PostConstructCallback;
|
||||
import org.eclipse.jetty.ee10.plus.annotation.PreDestroyCallback;
|
||||
import org.eclipse.jetty.ee10.webapp.Descriptor;
|
||||
import org.eclipse.jetty.ee10.webapp.FragmentDescriptor;
|
||||
import org.eclipse.jetty.ee10.webapp.IterativeDescriptorProcessor;
|
||||
import org.eclipse.jetty.ee10.webapp.Origin;
|
||||
import org.eclipse.jetty.ee10.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.plus.annotation.Injection;
|
||||
import org.eclipse.jetty.plus.annotation.InjectionCollection;
|
||||
import org.eclipse.jetty.plus.annotation.LifeCycleCallback;
|
||||
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
|
||||
import org.eclipse.jetty.plus.annotation.PostConstructCallback;
|
||||
import org.eclipse.jetty.plus.annotation.PreDestroyCallback;
|
||||
import org.eclipse.jetty.plus.jndi.EnvEntry;
|
||||
import org.eclipse.jetty.plus.jndi.Link;
|
||||
import org.eclipse.jetty.plus.jndi.NamingEntry;
|
||||
|
|
|
@ -19,6 +19,10 @@ import java.nio.file.Path;
|
|||
import jakarta.servlet.http.HttpServlet;
|
||||
import org.eclipse.jetty.ee10.servlet.ServletHolder;
|
||||
import org.eclipse.jetty.ee10.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.plus.annotation.LifeCycleCallback;
|
||||
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
|
||||
import org.eclipse.jetty.plus.annotation.PostConstructCallback;
|
||||
import org.eclipse.jetty.plus.annotation.PreDestroyCallback;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.toolchain.test.FS;
|
||||
import org.eclipse.jetty.toolchain.test.jupiter.WorkDir;
|
||||
|
|
|
@ -19,8 +19,6 @@ import javax.naming.Context;
|
|||
import javax.naming.InitialContext;
|
||||
import javax.naming.Name;
|
||||
|
||||
import org.eclipse.jetty.ee10.plus.annotation.Injection;
|
||||
import org.eclipse.jetty.ee10.plus.annotation.InjectionCollection;
|
||||
import org.eclipse.jetty.ee10.webapp.Configuration;
|
||||
import org.eclipse.jetty.ee10.webapp.Descriptor;
|
||||
import org.eclipse.jetty.ee10.webapp.FragmentDescriptor;
|
||||
|
@ -28,6 +26,8 @@ import org.eclipse.jetty.ee10.webapp.Origin;
|
|||
import org.eclipse.jetty.ee10.webapp.WebAppClassLoader;
|
||||
import org.eclipse.jetty.ee10.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.ee10.webapp.WebDescriptor;
|
||||
import org.eclipse.jetty.plus.annotation.Injection;
|
||||
import org.eclipse.jetty.plus.annotation.InjectionCollection;
|
||||
import org.eclipse.jetty.plus.jndi.EnvEntry;
|
||||
import org.eclipse.jetty.plus.jndi.NamingEntryUtil;
|
||||
import org.eclipse.jetty.plus.jndi.Resource;
|
||||
|
|
|
@ -31,8 +31,6 @@ import jakarta.servlet.SessionTrackingMode;
|
|||
import jakarta.servlet.descriptor.JspPropertyGroupDescriptor;
|
||||
import jakarta.servlet.descriptor.TaglibDescriptor;
|
||||
import org.eclipse.jetty.ee10.annotations.AnnotationConfiguration;
|
||||
import org.eclipse.jetty.ee10.plus.annotation.LifeCycleCallback;
|
||||
import org.eclipse.jetty.ee10.plus.annotation.LifeCycleCallbackCollection;
|
||||
import org.eclipse.jetty.ee10.servlet.ErrorPageErrorHandler;
|
||||
import org.eclipse.jetty.ee10.servlet.FilterHolder;
|
||||
import org.eclipse.jetty.ee10.servlet.FilterMapping;
|
||||
|
@ -52,6 +50,8 @@ import org.eclipse.jetty.ee10.webapp.MetaInfConfiguration;
|
|||
import org.eclipse.jetty.ee10.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.ee10.webapp.WebInfConfiguration;
|
||||
import org.eclipse.jetty.http.MimeTypes;
|
||||
import org.eclipse.jetty.plus.annotation.LifeCycleCallback;
|
||||
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
|
||||
import org.eclipse.jetty.security.Authenticator;
|
||||
import org.eclipse.jetty.security.Constraint;
|
||||
import org.eclipse.jetty.security.Constraint.Transport;
|
||||
|
|
|
@ -26,7 +26,7 @@ import org.eclipse.jetty.client.AuthenticationStore;
|
|||
import org.eclipse.jetty.client.BasicAuthentication;
|
||||
import org.eclipse.jetty.client.ContentResponse;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.ee10.plus.security.DataSourceLoginService;
|
||||
import org.eclipse.jetty.plus.security.DataSourceLoginService;
|
||||
import org.eclipse.jetty.toolchain.test.FS;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.eclipse.jetty.util.Loader;
|
||||
|
|
|
@ -111,7 +111,7 @@
|
|||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<argLine>@{argLine} ${jetty.surefire.argLine} --add-reads org.eclipse.jetty.ee8.annotations=org.eclipse.jetty.logging --add-opens org.eclipse.jetty.ee8.annotations/org.eclipse.jetty.ee8.annotations.resources=org.eclipse.jetty.ee8.plus</argLine>
|
||||
<argLine>@{argLine} ${jetty.surefire.argLine} --add-reads org.eclipse.jetty.ee8.annotations=org.eclipse.jetty.logging --add-opens org.eclipse.jetty.ee8.annotations/org.eclipse.jetty.ee8.annotations.resources=org.eclipse.jetty.plus</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
|
|
@ -64,6 +64,13 @@
|
|||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<argLine>@{argLine} ${jetty.surefire.argLine} --add-exports=org.eclipse.jetty.ee8.plus/org.eclipse.jetty.ee8.plus.annotation=org.eclipse.jetty.ee8.nested --add-opens org.eclipse.jetty.ee8.plus/org.eclipse.jetty.ee8.plus.annotation=org.eclipse.jetty.plus</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@
|
|||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<argLine>@{argLine} ${jetty.surefire.argLine} --add-reads org.eclipse.jetty.ee9.annotations=org.eclipse.jetty.logging --add-opens org.eclipse.jetty.ee9.annotations/org.eclipse.jetty.ee9.annotations.resources=org.eclipse.jetty.ee9.plus</argLine>
|
||||
<argLine>@{argLine} ${jetty.surefire.argLine} --add-reads org.eclipse.jetty.ee9.annotations=org.eclipse.jetty.logging --add-opens org.eclipse.jetty.ee9.annotations/org.eclipse.jetty.ee9.annotations.resources=org.eclipse.jetty.plus</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
|
|
@ -18,11 +18,11 @@ import java.lang.reflect.Modifier;
|
|||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import org.eclipse.jetty.ee9.annotations.AnnotationIntrospector.AbstractIntrospectableAnnotationHandler;
|
||||
import org.eclipse.jetty.ee9.plus.annotation.LifeCycleCallbackCollection;
|
||||
import org.eclipse.jetty.ee9.plus.annotation.PostConstructCallback;
|
||||
import org.eclipse.jetty.ee9.webapp.MetaData;
|
||||
import org.eclipse.jetty.ee9.webapp.Origin;
|
||||
import org.eclipse.jetty.ee9.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
|
||||
import org.eclipse.jetty.plus.annotation.PostConstructCallback;
|
||||
|
||||
public class PostConstructAnnotationHandler extends AbstractIntrospectableAnnotationHandler
|
||||
{
|
||||
|
|
|
@ -18,11 +18,11 @@ import java.lang.reflect.Modifier;
|
|||
|
||||
import jakarta.annotation.PreDestroy;
|
||||
import org.eclipse.jetty.ee9.annotations.AnnotationIntrospector.AbstractIntrospectableAnnotationHandler;
|
||||
import org.eclipse.jetty.ee9.plus.annotation.LifeCycleCallbackCollection;
|
||||
import org.eclipse.jetty.ee9.plus.annotation.PreDestroyCallback;
|
||||
import org.eclipse.jetty.ee9.webapp.MetaData;
|
||||
import org.eclipse.jetty.ee9.webapp.Origin;
|
||||
import org.eclipse.jetty.ee9.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
|
||||
import org.eclipse.jetty.plus.annotation.PreDestroyCallback;
|
||||
|
||||
public class PreDestroyAnnotationHandler extends AbstractIntrospectableAnnotationHandler
|
||||
{
|
||||
|
|
|
@ -26,10 +26,10 @@ import javax.naming.NamingException;
|
|||
import jakarta.annotation.Resource;
|
||||
import org.eclipse.jetty.ee9.annotations.AnnotationIntrospector.AbstractIntrospectableAnnotationHandler;
|
||||
import org.eclipse.jetty.ee9.nested.ContextHandler;
|
||||
import org.eclipse.jetty.ee9.plus.annotation.Injection;
|
||||
import org.eclipse.jetty.ee9.plus.annotation.InjectionCollection;
|
||||
import org.eclipse.jetty.ee9.webapp.MetaData;
|
||||
import org.eclipse.jetty.ee9.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.plus.annotation.Injection;
|
||||
import org.eclipse.jetty.plus.annotation.InjectionCollection;
|
||||
import org.eclipse.jetty.plus.jndi.NamingEntryUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
|
|
@ -16,12 +16,12 @@ package org.eclipse.jetty.ee9.annotations;
|
|||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import org.eclipse.jetty.ee9.plus.annotation.LifeCycleCallbackCollection;
|
||||
import org.eclipse.jetty.ee9.servlet.ServletHolder;
|
||||
import org.eclipse.jetty.ee9.servlet.Source;
|
||||
import org.eclipse.jetty.ee9.webapp.MetaData;
|
||||
import org.eclipse.jetty.ee9.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.ee9.webapp.WebDescriptor;
|
||||
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
|
||||
import org.eclipse.jetty.toolchain.test.jupiter.WorkDir;
|
||||
import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension;
|
||||
import org.eclipse.jetty.util.DecoratedObjectFactory;
|
||||
|
|
|
@ -21,9 +21,9 @@ import javax.naming.InitialContext;
|
|||
import org.eclipse.jetty.ee9.annotations.AnnotationIntrospector;
|
||||
import org.eclipse.jetty.ee9.annotations.ResourceAnnotationHandler;
|
||||
import org.eclipse.jetty.ee9.annotations.ResourcesAnnotationHandler;
|
||||
import org.eclipse.jetty.ee9.plus.annotation.Injection;
|
||||
import org.eclipse.jetty.ee9.plus.annotation.InjectionCollection;
|
||||
import org.eclipse.jetty.ee9.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.plus.annotation.Injection;
|
||||
import org.eclipse.jetty.plus.annotation.InjectionCollection;
|
||||
import org.eclipse.jetty.plus.jndi.EnvEntry;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
|
|
|
@ -67,6 +67,12 @@
|
|||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<argLine>@{argLine} ${jetty.surefire.argLine} --add-exports=org.eclipse.jetty.ee9.plus/org.eclipse.jetty.ee9.plus.annotation=org.eclipse.jetty.ee9.nested --add-opens org.eclipse.jetty.ee9.plus/org.eclipse.jetty.ee9.plus.annotation=org.eclipse.jetty.plus</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
|
|
@ -22,16 +22,10 @@ module org.eclipse.jetty.ee9.plus
|
|||
requires transitive org.eclipse.jetty.ee9.webapp;
|
||||
requires transitive org.eclipse.jetty.plus;
|
||||
|
||||
// Only required if using DataSourceLoginService.
|
||||
requires static java.sql;
|
||||
// Only required if using Transaction.
|
||||
requires static jakarta.transaction;
|
||||
// Only required if using RunAs.
|
||||
requires static org.eclipse.jetty.ee9.servlet;
|
||||
|
||||
exports org.eclipse.jetty.ee9.plus.annotation;
|
||||
exports org.eclipse.jetty.ee9.plus.jndi;
|
||||
exports org.eclipse.jetty.ee9.plus.security;
|
||||
exports org.eclipse.jetty.ee9.plus.webapp;
|
||||
|
||||
provides org.eclipse.jetty.ee9.webapp.Configuration with
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.ee9.plus.annotation;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.eclipse.jetty.ee9.servlet.ServletHolder;
|
||||
|
||||
/**
|
||||
* RunAs
|
||||
* <p>
|
||||
* Represents a <code><run-as></code> element in web.xml, or a <code>@RunAs</code> annotation.
|
||||
* @deprecated unused as of 9.4.28 due for removal in 10.0.0
|
||||
*/
|
||||
@Deprecated
|
||||
public class RunAs
|
||||
{
|
||||
private String _className;
|
||||
private String _roleName;
|
||||
|
||||
public RunAs(String className, String roleName)
|
||||
{
|
||||
_className = Objects.requireNonNull(className);
|
||||
_roleName = Objects.requireNonNull(roleName);
|
||||
}
|
||||
|
||||
public String getTargetClassName()
|
||||
{
|
||||
return _className;
|
||||
}
|
||||
|
||||
public String getRoleName()
|
||||
{
|
||||
return _roleName;
|
||||
}
|
||||
|
||||
public void setRunAs(ServletHolder holder)
|
||||
{
|
||||
if (holder == null)
|
||||
return;
|
||||
String className = holder.getClassName();
|
||||
|
||||
if (className.equals(_className))
|
||||
{
|
||||
//Only set the RunAs if it has not already been set, presumably by web/web-fragment.xml
|
||||
if (holder.getRegistration().getRunAsRole() == null)
|
||||
holder.getRegistration().setRunAsRole(_roleName);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.ee9.plus.annotation;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import org.eclipse.jetty.ee9.servlet.ServletHolder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* RunAsCollection
|
||||
* @deprecated class unused as of 9.4.28 due for removal in 10.0.0
|
||||
*/
|
||||
@Deprecated
|
||||
public class RunAsCollection
|
||||
{
|
||||
private static final Logger LOG = LoggerFactory.getLogger(RunAsCollection.class);
|
||||
|
||||
public static final String RUNAS_COLLECTION = "org.eclipse.jetty.runAsCollection";
|
||||
private ConcurrentMap<String, RunAs> _runAsMap = new ConcurrentHashMap<String, RunAs>(); //map of classname to run-as
|
||||
|
||||
public void add(RunAs runAs)
|
||||
{
|
||||
if ((runAs == null) || (runAs.getTargetClassName() == null))
|
||||
return;
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Adding run-as for class=" + runAs.getTargetClassName());
|
||||
RunAs prev = _runAsMap.putIfAbsent(runAs.getTargetClassName(), runAs);
|
||||
if (prev != null)
|
||||
LOG.warn("Run-As {} on class {} ignored, already run-as {}", runAs.getRoleName(), runAs.getTargetClassName(), prev.getRoleName());
|
||||
}
|
||||
|
||||
public RunAs getRunAs(Object o)
|
||||
{
|
||||
if (o == null)
|
||||
return null;
|
||||
|
||||
return (RunAs)_runAsMap.get(o.getClass().getName());
|
||||
}
|
||||
|
||||
public void setRunAs(Object o)
|
||||
{
|
||||
if (o == null)
|
||||
return;
|
||||
|
||||
if (!ServletHolder.class.isAssignableFrom(o.getClass()))
|
||||
return;
|
||||
|
||||
RunAs runAs = (RunAs)_runAsMap.get(o.getClass().getName());
|
||||
if (runAs == null)
|
||||
return;
|
||||
|
||||
runAs.setRunAs((ServletHolder)o);
|
||||
}
|
||||
}
|
|
@ -18,8 +18,6 @@ import javax.naming.InitialContext;
|
|||
import javax.naming.NameNotFoundException;
|
||||
|
||||
import org.eclipse.jetty.ee9.nested.ContextHandler;
|
||||
import org.eclipse.jetty.ee9.plus.annotation.InjectionCollection;
|
||||
import org.eclipse.jetty.ee9.plus.annotation.LifeCycleCallbackCollection;
|
||||
import org.eclipse.jetty.ee9.plus.jndi.Transaction;
|
||||
import org.eclipse.jetty.ee9.webapp.AbstractConfiguration;
|
||||
import org.eclipse.jetty.ee9.webapp.FragmentConfiguration;
|
||||
|
@ -27,6 +25,8 @@ import org.eclipse.jetty.ee9.webapp.JettyWebXmlConfiguration;
|
|||
import org.eclipse.jetty.ee9.webapp.MetaInfConfiguration;
|
||||
import org.eclipse.jetty.ee9.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.ee9.webapp.WebXmlConfiguration;
|
||||
import org.eclipse.jetty.plus.annotation.InjectionCollection;
|
||||
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
|
||||
import org.eclipse.jetty.util.NanoTime;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
|
||||
package org.eclipse.jetty.ee9.plus.webapp;
|
||||
|
||||
import org.eclipse.jetty.ee9.plus.annotation.InjectionCollection;
|
||||
import org.eclipse.jetty.ee9.plus.annotation.LifeCycleCallbackCollection;
|
||||
import org.eclipse.jetty.ee9.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.plus.annotation.InjectionCollection;
|
||||
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
|
||||
import org.eclipse.jetty.util.Decorator;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
|
|
@ -19,17 +19,17 @@ import javax.naming.Context;
|
|||
import javax.naming.InitialContext;
|
||||
import javax.naming.NameNotFoundException;
|
||||
|
||||
import org.eclipse.jetty.ee9.plus.annotation.Injection;
|
||||
import org.eclipse.jetty.ee9.plus.annotation.InjectionCollection;
|
||||
import org.eclipse.jetty.ee9.plus.annotation.LifeCycleCallback;
|
||||
import org.eclipse.jetty.ee9.plus.annotation.LifeCycleCallbackCollection;
|
||||
import org.eclipse.jetty.ee9.plus.annotation.PostConstructCallback;
|
||||
import org.eclipse.jetty.ee9.plus.annotation.PreDestroyCallback;
|
||||
import org.eclipse.jetty.ee9.webapp.Descriptor;
|
||||
import org.eclipse.jetty.ee9.webapp.FragmentDescriptor;
|
||||
import org.eclipse.jetty.ee9.webapp.IterativeDescriptorProcessor;
|
||||
import org.eclipse.jetty.ee9.webapp.Origin;
|
||||
import org.eclipse.jetty.ee9.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.plus.annotation.Injection;
|
||||
import org.eclipse.jetty.plus.annotation.InjectionCollection;
|
||||
import org.eclipse.jetty.plus.annotation.LifeCycleCallback;
|
||||
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
|
||||
import org.eclipse.jetty.plus.annotation.PostConstructCallback;
|
||||
import org.eclipse.jetty.plus.annotation.PreDestroyCallback;
|
||||
import org.eclipse.jetty.plus.jndi.EnvEntry;
|
||||
import org.eclipse.jetty.plus.jndi.Link;
|
||||
import org.eclipse.jetty.plus.jndi.NamingEntry;
|
||||
|
|
|
@ -19,6 +19,10 @@ import java.nio.file.Path;
|
|||
import jakarta.servlet.http.HttpServlet;
|
||||
import org.eclipse.jetty.ee9.servlet.ServletHolder;
|
||||
import org.eclipse.jetty.ee9.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.plus.annotation.LifeCycleCallback;
|
||||
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
|
||||
import org.eclipse.jetty.plus.annotation.PostConstructCallback;
|
||||
import org.eclipse.jetty.plus.annotation.PreDestroyCallback;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.toolchain.test.FS;
|
||||
import org.eclipse.jetty.toolchain.test.jupiter.WorkDir;
|
||||
|
|
|
@ -19,8 +19,6 @@ import javax.naming.Context;
|
|||
import javax.naming.InitialContext;
|
||||
import javax.naming.Name;
|
||||
|
||||
import org.eclipse.jetty.ee9.plus.annotation.Injection;
|
||||
import org.eclipse.jetty.ee9.plus.annotation.InjectionCollection;
|
||||
import org.eclipse.jetty.ee9.webapp.Configuration;
|
||||
import org.eclipse.jetty.ee9.webapp.Descriptor;
|
||||
import org.eclipse.jetty.ee9.webapp.FragmentDescriptor;
|
||||
|
@ -28,6 +26,8 @@ import org.eclipse.jetty.ee9.webapp.Origin;
|
|||
import org.eclipse.jetty.ee9.webapp.WebAppClassLoader;
|
||||
import org.eclipse.jetty.ee9.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.ee9.webapp.WebDescriptor;
|
||||
import org.eclipse.jetty.plus.annotation.Injection;
|
||||
import org.eclipse.jetty.plus.annotation.InjectionCollection;
|
||||
import org.eclipse.jetty.plus.jndi.EnvEntry;
|
||||
import org.eclipse.jetty.plus.jndi.NamingEntryUtil;
|
||||
import org.eclipse.jetty.plus.jndi.Resource;
|
||||
|
|
|
@ -33,8 +33,6 @@ import jakarta.servlet.descriptor.JspPropertyGroupDescriptor;
|
|||
import jakarta.servlet.descriptor.TaglibDescriptor;
|
||||
import org.eclipse.jetty.ee9.annotations.AnnotationConfiguration;
|
||||
import org.eclipse.jetty.ee9.nested.ServletConstraint;
|
||||
import org.eclipse.jetty.ee9.plus.annotation.LifeCycleCallback;
|
||||
import org.eclipse.jetty.ee9.plus.annotation.LifeCycleCallbackCollection;
|
||||
import org.eclipse.jetty.ee9.security.Authenticator;
|
||||
import org.eclipse.jetty.ee9.security.ConstraintAware;
|
||||
import org.eclipse.jetty.ee9.security.ConstraintMapping;
|
||||
|
@ -57,6 +55,8 @@ import org.eclipse.jetty.ee9.webapp.MetaInfConfiguration;
|
|||
import org.eclipse.jetty.ee9.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.ee9.webapp.WebInfConfiguration;
|
||||
import org.eclipse.jetty.http.MimeTypes;
|
||||
import org.eclipse.jetty.plus.annotation.LifeCycleCallback;
|
||||
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
|
||||
import org.eclipse.jetty.util.QuotedStringTokenizer;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.resource.AttributeNormalizer;
|
||||
|
|
|
@ -26,7 +26,7 @@ import org.eclipse.jetty.client.AuthenticationStore;
|
|||
import org.eclipse.jetty.client.BasicAuthentication;
|
||||
import org.eclipse.jetty.client.ContentResponse;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.ee9.plus.security.DataSourceLoginService;
|
||||
import org.eclipse.jetty.plus.security.DataSourceLoginService;
|
||||
import org.eclipse.jetty.toolchain.test.FS;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.eclipse.jetty.util.Loader;
|
||||
|
|
Loading…
Reference in New Issue