[spring-extensions] branch main updated: JSE-49 - Allow NamespaceHandler base class to sub-delegate
Scott Cantor
cantor.2 at osu.edu
Tue Jun 21 14:52:14 UTC 2022
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch main
in repository spring-extensions.
View the commit online:
http://git.shibboleth.net/view/?p=spring-extensions.git;a=commit;h=8e6733c8df83edb56107c9820cf37ed4795954de
The following commit(s) were added to refs/heads/main by this push:
new 8e6733c JSE-49 - Allow NamespaceHandler base class to sub-delegate
8e6733c is described below
commit 8e6733c8df83edb56107c9820cf37ed4795954de
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Jun 21 10:52:12 2022 -0400
JSE-49 - Allow NamespaceHandler base class to sub-delegate
https://shibboleth.atlassian.net/browse/JSE-49
Bit of reworking to better slot in existing handlers.
---
.../spring/util/BaseSpringNamespaceHandler.java | 80 ++++++++++++++++++----
.../ext/spring/util/SecondaryNamespaceHandler.java | 25 +++++--
.../ext/spring/util/LowerParsersAndBean.java | 17 +++--
3 files changed, 94 insertions(+), 28 deletions(-)
diff --git a/src/main/java/net/shibboleth/ext/spring/util/BaseSpringNamespaceHandler.java b/src/main/java/net/shibboleth/ext/spring/util/BaseSpringNamespaceHandler.java
index 4e095dd..e54c483 100644
--- a/src/main/java/net/shibboleth/ext/spring/util/BaseSpringNamespaceHandler.java
+++ b/src/main/java/net/shibboleth/ext/spring/util/BaseSpringNamespaceHandler.java
@@ -23,15 +23,17 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
-import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import javax.xml.namespace.QName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanInstantiationException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.config.BeanDefinition;
@@ -42,34 +44,68 @@ import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
+import net.shibboleth.utilities.java.support.annotation.ParameterName;
+import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
+import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
+import net.shibboleth.utilities.java.support.primitive.StringSupport;
import net.shibboleth.utilities.java.support.xml.DOMTypeSupport;
import net.shibboleth.utilities.java.support.xml.QNameSupport;
/**
* A base class for {@link NamespaceHandler} implementations.
*
- * This code is heavily based on Spring's <code>NamespaceHandlerSupport</code>. The largest difference is that bean
+ * <p>This code is heavily based on Spring's <code>NamespaceHandlerSupport</code>. The largest difference is that bean
* definition parsers may be registered against either an elements name or schema type. During parser lookup the schema
- * type is preferred.
+ * type is preferred.</p>
+ *
+ * <p>This code also now supports a notion of one or more "secondary" handlers that can be registered to supplement or
+ * override the mappings in the main subclass.</p>
*/
public abstract class BaseSpringNamespaceHandler implements NamespaceHandler {
/**
* The base location to look for the secondary mapping files. Can be present in multiple JAR files.
*/
+ @Nonnull @NotEmpty
public static final String DEFAULT_SECONDARY_HANDLER_BASE_LOCATION = "META-INF/net/shibboleth/spring/handlers/";
/** Class logger. */
- private final Logger log = LoggerFactory.getLogger(BaseSpringNamespaceHandler.class);
+ @Nonnull private final Logger log = LoggerFactory.getLogger(BaseSpringNamespaceHandler.class);
+ /** Qualifier to include in resource path when looking for secondary handlers. */
+ @Nullable @NotEmpty private final String secondaryHandlerQualifier;
+
/**
* Stores the {@link BeanDefinitionParser} implementations keyed by the local name of the {@link Element Elements}
* they handle.
*/
- private Map<QName, BeanDefinitionParser> parsers = Collections.synchronizedMap(new HashMap<>());
+ @Nonnull @NonnullElements private final Map<QName,BeanDefinitionParser> parsers;
+
+ /** Constructor. */
+ public BaseSpringNamespaceHandler() {
+ this(null);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param qualifier qualifier added to secondary handler resource path
+ *
+ * @since 7.0.0
+ */
+ public BaseSpringNamespaceHandler(@Nullable @NotEmpty @ParameterName(name="qualifier") final String qualifier) {
+ parsers = new HashMap<>();
+ secondaryHandlerQualifier = StringSupport.trimOrNull(qualifier);
+ }
+
+ /** {@inheritDoc} */
+ public void init() {
+ doInit();
+ initSecondaryHandlers();
+ }
/**
- * A noop decorator. Returns the input.
+ * A no-op decorator, returns the input.
*
* @param node the node decorating a the given bean definition
* @param definition the bean being decorated
@@ -95,6 +131,16 @@ public abstract class BaseSpringNamespaceHandler implements NamespaceHandler {
return findParserForElement(element).parse(element, parserContext);
}
+ /**
+ * Subclasses should override this method to allow for installation of {@link SecondaryNamespaceHandler}
+ * instances.
+ *
+ * @since 7.0.0
+ */
+ protected void doInit() {
+
+ }
+
/**
* Locates the {@link BeanDefinitionParser} from the register implementations using the local name of the supplied
* {@link Element}.
@@ -142,14 +188,16 @@ public abstract class BaseSpringNamespaceHandler implements NamespaceHandler {
parsers.put(elementNameOrType, parser);
}
- /** Call back to initialize any registered secondary handlers. This is added to the
- * {@link #init()} call if the handler knows that there will be other handlers.
- * @param name a unique name (derived from the namespace URN) to locate the classes to use
+ /**
+ * Initializes any registered secondary handlers.
+ *
+ * <p>Subclasses that allow for this feature should override {@link #doInit()}, while existing/legacy
+ * handlers without this feature may continue to override {@link #init()}.</p>
*/
- protected void initializeOtherHandlers(final String name) {
+ private void initSecondaryHandlers() {
try {
final Enumeration<URL> urls = ClassLoader.getSystemResources(
- DEFAULT_SECONDARY_HANDLER_BASE_LOCATION + name);
+ DEFAULT_SECONDARY_HANDLER_BASE_LOCATION + secondaryHandlerQualifier);
while (urls.hasMoreElements()) {
final URL url = urls.nextElement();
final URLConnection con = url.openConnection();
@@ -164,9 +212,11 @@ public abstract class BaseSpringNamespaceHandler implements NamespaceHandler {
namespaceHandler.init(parsers);
}
}
- } catch (final IOException | ClassNotFoundException e) {
- log.error("Secondary initialization failed for namespace {}", name, e);
- throw new BeanCreationException("Secondary initialization failed for namespace '"+ name +"", e);
+ } catch (final IOException|ClassNotFoundException|ClassCastException|BeanInstantiationException e) {
+ log.error("Secondary initialization failed for namespace {}", secondaryHandlerQualifier, e);
+ throw new BeanCreationException("Secondary initialization failed for namespace '"
+ + secondaryHandlerQualifier + "'", e);
}
}
-}
+
+}
\ No newline at end of file
diff --git a/src/main/java/net/shibboleth/ext/spring/util/SecondaryNamespaceHandler.java b/src/main/java/net/shibboleth/ext/spring/util/SecondaryNamespaceHandler.java
index 9903208..8b689ed 100644
--- a/src/main/java/net/shibboleth/ext/spring/util/SecondaryNamespaceHandler.java
+++ b/src/main/java/net/shibboleth/ext/spring/util/SecondaryNamespaceHandler.java
@@ -19,27 +19,37 @@ package net.shibboleth.ext.spring.util;
import java.util.Map;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import javax.xml.namespace.QName;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.w3c.dom.Element;
-/** A secondary namespace handler to allow us to stack multiple parsers. */
+import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
+import net.shibboleth.utilities.java.support.logic.Constraint;
+
+/**
+ * A secondary namespace handler to allow us to stack multiple parsers.
+ *
+ * @since 7.0.0
+ */
public abstract class SecondaryNamespaceHandler {
/**
* Stores the {@link BeanDefinitionParser} implementations keyed by the local name of the {@link Element Elements}
* they handle.
*/
- private Map<QName, BeanDefinitionParser> parsers;
+ @Nullable @NonnullElements private Map<QName, BeanDefinitionParser> parsers;
- /** Initialize the handler, called when a {@link BaseSpringNamespaceHandler}
+ /**
+ * Initialize the handler, called when a {@link BaseSpringNamespaceHandler}
* calls {@link BaseSpringNamespaceHandler#initializeOtherHandlers(String)}.
*
* @param theParsers
*/
- protected void init(final Map<QName, BeanDefinitionParser> theParsers) {
- parsers = theParsers;
+ protected void init(@Nonnull @NonnullElements final Map<QName, BeanDefinitionParser> theParsers) {
+ parsers = Constraint.isNotNull(theParsers, "Parser map cannot be null");
doInit();
}
@@ -55,8 +65,9 @@ public abstract class SecondaryNamespaceHandler {
}
/**
- * Subclasses implement this call and in it register the {@link BeanDefinitionParser}s
+ * Subclasses implement this method and in it register the {@link BeanDefinitionParser}s
* via calls to {@link #registerBeanDefinitionParser(QName, BeanDefinitionParser) }.
*/
public abstract void doInit();
-}
+
+}
\ No newline at end of file
diff --git a/src/test/java/net/shibboleth/ext/spring/util/LowerParsersAndBean.java b/src/test/java/net/shibboleth/ext/spring/util/LowerParsersAndBean.java
index 3a351f6..f5d5c2e 100644
--- a/src/test/java/net/shibboleth/ext/spring/util/LowerParsersAndBean.java
+++ b/src/test/java/net/shibboleth/ext/spring/util/LowerParsersAndBean.java
@@ -18,6 +18,7 @@
package net.shibboleth.ext.spring.util;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import javax.xml.namespace.QName;
import org.springframework.beans.factory.config.BeanDefinition;
@@ -26,14 +27,19 @@ import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;
+import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
import net.shibboleth.utilities.java.support.xml.AttributeSupport;
import net.shibboleth.utilities.java.support.xml.ElementSupport;
public class LowerParsersAndBean extends BaseSpringNamespaceHandler {
- protected static final String NAMESPACE = "urn:mace:shibboleth:2.0:nested";
+ @Nonnull @NotEmpty protected static final String NAMESPACE = "urn:mace:shibboleth:2.0:nested";
- private String message;
+ @Nullable private String message;
+
+ public LowerParsersAndBean() {
+ super(NAMESPACE.replaceAll("\\:", "-"));
+ }
public void setMessage(String theMessage) {
message = theMessage;
@@ -44,11 +50,10 @@ public class LowerParsersAndBean extends BaseSpringNamespaceHandler {
}
/** {@inheritDoc} */
- public void init() {
+ @Override
+ public void doInit() {
registerBeanDefinitionParser(new QName(NAMESPACE, "LowerElement"), new LowerElementParser());
registerBeanDefinitionParser(new QName(NAMESPACE, "OuterElement"), new OuterElementParser());
- final String adjustedName=NAMESPACE.replaceAll("\\:", "-");
- initializeOtherHandlers(adjustedName);
}
static class LowerElementParser extends AbstractCustomBeanDefinitionParser {
@@ -76,4 +81,4 @@ public class LowerParsersAndBean extends BaseSpringNamespaceHandler {
}
-}
+}
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list