|
17 | 17 | package org.apache.logging.log4j.jndi.test.junit;
|
18 | 18 |
|
19 | 19 | import static java.util.Objects.requireNonNull;
|
20 |
| -import static org.junit.Assert.assertNotNull; |
21 | 20 |
|
22 | 21 | import java.util.Collections;
|
23 | 22 | import java.util.Hashtable;
|
24 | 23 | import java.util.Map;
|
25 |
| -import java.util.Set; |
26 |
| -import java.util.Spliterators; |
27 |
| -import java.util.stream.Collectors; |
28 |
| -import java.util.stream.StreamSupport; |
29 | 24 | import javax.annotation.Nullable;
|
30 | 25 | import javax.naming.Context;
|
31 |
| -import javax.naming.NameClassPair; |
| 26 | +import javax.naming.Name; |
32 | 27 | import javax.naming.NamingException;
|
33 | 28 | import javax.naming.spi.InitialContextFactoryBuilder;
|
34 | 29 | import javax.naming.spi.NamingManager;
|
|
46 | 41 | @SuppressWarnings("BanJNDI")
|
47 | 42 | public class JndiRule implements TestRule {
|
48 | 43 |
|
| 44 | + private static final Hashtable<String, Object> ENV = new Hashtable<>(Map.of(MemoryContext.IGNORE_CLOSE, "true")); |
| 45 | + private static final Context CONTEXT = new MemoryContext(ENV); |
| 46 | + |
49 | 47 | static {
|
50 |
| - final InitialContextFactoryBuilder factoryBuilder = |
51 |
| - factoryBuilderEnv -> factoryEnv -> new MemoryContext(new Hashtable<>()) {}; |
| 48 | + final InitialContextFactoryBuilder factoryBuilder = factoryBuilderEnv -> factoryEnv -> CONTEXT; |
52 | 49 | try {
|
53 | 50 | NamingManager.setInitialContextFactoryBuilder(factoryBuilder);
|
54 | 51 | } catch (final NamingException error) {
|
@@ -91,38 +88,44 @@ public void evaluate() throws Throwable {
|
91 | 88 |
|
92 | 89 | private void resetJndiManager() throws NamingException {
|
93 | 90 | if (JndiManager.isJndiEnabled()) {
|
94 |
| - final Context context = getContext(); |
95 |
| - clearBindings(context); |
96 |
| - addBindings(context); |
| 91 | + clearBindings(); |
| 92 | + addBindings(); |
97 | 93 | }
|
98 | 94 | }
|
99 | 95 |
|
100 |
| - private Context getContext() { |
101 |
| - final JndiManager manager = |
102 |
| - managerName == null ? JndiManager.getDefaultManager() : JndiManager.getDefaultManager(managerName); |
103 |
| - @Nullable final Context context = manager.getContext(); |
104 |
| - assertNotNull(context); |
105 |
| - return context; |
106 |
| - } |
107 |
| - |
108 |
| - private static void clearBindings(final Context context) throws NamingException { |
109 |
| - final Set<NameClassPair> existingBindings = StreamSupport.stream( |
110 |
| - Spliterators.spliteratorUnknownSize(context.list("").asIterator(), 0), false) |
111 |
| - .collect(Collectors.toSet()); |
112 |
| - existingBindings.forEach(binding -> { |
| 96 | + private static void clearBindings() throws NamingException { |
| 97 | + Collections.list(CONTEXT.list("")).forEach(binding -> { |
113 | 98 | try {
|
114 |
| - context.unbind(binding.getName()); |
| 99 | + CONTEXT.unbind(binding.getName()); |
115 | 100 | } catch (NamingException error) {
|
116 | 101 | throw new RuntimeException(error);
|
117 | 102 | }
|
118 | 103 | });
|
119 | 104 | }
|
120 | 105 |
|
121 |
| - private void addBindings(final Context context) throws NamingException { |
| 106 | + private void addBindings() throws NamingException { |
122 | 107 | for (final Map.Entry<String, Object> entry : bindings.entrySet()) {
|
123 |
| - final String name = entry.getKey(); |
| 108 | + final String key = entry.getKey(); |
124 | 109 | final Object object = entry.getValue();
|
125 |
| - context.bind(name, object); |
| 110 | + recursiveBind(key, object); |
| 111 | + } |
| 112 | + } |
| 113 | + |
| 114 | + public static void recursiveBind(final String key, final Object value) throws NamingException { |
| 115 | + final Name name = CONTEXT.getNameParser((Name) null).parse(key); |
| 116 | + Context currentContext = CONTEXT; |
| 117 | + final int lastIndex = name.size() - 1; |
| 118 | + for (int i = 0; i < lastIndex; i++) { |
| 119 | + try { |
| 120 | + currentContext = (Context) currentContext.lookup(name.get(i)); |
| 121 | + } catch (NamingException ignored) { |
| 122 | + currentContext = currentContext.createSubcontext(name.get(i)); |
| 123 | + } |
126 | 124 | }
|
| 125 | + currentContext.bind(name.get(lastIndex), value); |
| 126 | + } |
| 127 | + |
| 128 | + public static void rebind(final String key, final Object value) throws NamingException { |
| 129 | + CONTEXT.rebind(key, value); |
127 | 130 | }
|
128 | 131 | }
|
0 commit comments