-
Notifications
You must be signed in to change notification settings - Fork 215
/
PlaceholderSubstitution.java
130 lines (109 loc) · 5.61 KB
/
PlaceholderSubstitution.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
* Copyright (c) 2022 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.ditto.policies.enforcement.placeholders;
import static java.util.Objects.requireNonNull;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.function.Function;
import javax.annotation.concurrent.Immutable;
import org.eclipse.ditto.base.model.headers.DittoHeaders;
import org.eclipse.ditto.base.model.headers.DittoHeadersSettable;
import org.eclipse.ditto.policies.enforcement.PreEnforcer;
import org.eclipse.ditto.policies.enforcement.placeholders.strategies.SubstitutionStrategy;
import org.eclipse.ditto.policies.enforcement.placeholders.strategies.SubstitutionStrategyRegistry;
import akka.actor.ActorSystem;
/**
* A function which applies substitution of placeholders on a command (subtype of {@link DittoHeadersSettable}) based on
* its {@link DittoHeaders}.
*
*/
@Immutable
public final class PlaceholderSubstitution implements PreEnforcer {
private final HeaderBasedPlaceholderSubstitutionAlgorithm substitutionAlgorithm;
private final SubstitutionStrategyRegistry substitutionStrategyRegistry;
private PlaceholderSubstitution(final HeaderBasedPlaceholderSubstitutionAlgorithm substitutionAlgorithm,
final SubstitutionStrategyRegistry substitutionStrategyRegistry) {
this.substitutionAlgorithm = substitutionAlgorithm;
this.substitutionStrategyRegistry = substitutionStrategyRegistry;
}
public PlaceholderSubstitution(final ActorSystem actorSystem) {
this.substitutionAlgorithm =
HeaderBasedPlaceholderSubstitutionAlgorithm.newInstance(createDefaultReplacementDefinitions());
this.substitutionStrategyRegistry = SubstitutionStrategyRegistry.newInstance();
}
/**
* Creates a new instance with default replacement definitions.
*
* @return the created instance.
* @see #newExtendedInstance(java.util.Map)
*/
public static PlaceholderSubstitution newInstance() {
final Map<String, Function<DittoHeaders, String>> defaultReplacementDefinitions =
createDefaultReplacementDefinitions();
return createInstance(defaultReplacementDefinitions);
}
/**
* Creates a new instance with default replacement definitions, extended with
* {@code additionalReplacementDefinitions}.
*
* @param additionalReplacementDefinitions the additional replacement definitions.
* @return the created instance.
* @see #newInstance()
*/
public static PlaceholderSubstitution newExtendedInstance(
final Map<String, Function<DittoHeaders, String>> additionalReplacementDefinitions) {
requireNonNull(additionalReplacementDefinitions);
final Map<String, Function<DittoHeaders, String>> defaultReplacementDefinitions =
createDefaultReplacementDefinitions();
final Map<String, Function<DittoHeaders, String>> allReplacementDefinitions =
new LinkedHashMap<>();
allReplacementDefinitions.putAll(defaultReplacementDefinitions);
allReplacementDefinitions.putAll(additionalReplacementDefinitions);
return createInstance(allReplacementDefinitions);
}
@Override
@SuppressWarnings({"unchecked", "rawtypes", "java:S3740"})
public CompletionStage<DittoHeadersSettable<?>> apply(final DittoHeadersSettable<?> dittoHeadersSettable) {
requireNonNull(dittoHeadersSettable);
final Optional<SubstitutionStrategy> firstMatchingStrategyOpt =
substitutionStrategyRegistry.getMatchingStrategy(dittoHeadersSettable);
if (firstMatchingStrategyOpt.isPresent()) {
final SubstitutionStrategy<DittoHeadersSettable<?>> firstMatchingStrategy = firstMatchingStrategyOpt.get();
return CompletableFuture.supplyAsync(() ->
firstMatchingStrategy.apply(dittoHeadersSettable, substitutionAlgorithm)
).thenApply(Function.identity());
} else {
return CompletableFuture.completedFuture(dittoHeadersSettable);
}
}
private static Map<String, Function<DittoHeaders, String>> createDefaultReplacementDefinitions() {
final Map<String, Function<DittoHeaders, String>> defaultReplacementDefinitions = new LinkedHashMap<>();
defaultReplacementDefinitions.put(SubjectIdReplacementDefinition.REPLACER_NAME,
SubjectIdReplacementDefinition.getInstance());
defaultReplacementDefinitions.put(SubjectIdReplacementDefinition.LEGACY_REPLACER_NAME,
SubjectIdReplacementDefinition.getInstance());
return Collections.unmodifiableMap(defaultReplacementDefinitions);
}
private static PlaceholderSubstitution createInstance(
final Map<String, Function<DittoHeaders, String>> replacementDefinitions) {
final HeaderBasedPlaceholderSubstitutionAlgorithm algorithm =
HeaderBasedPlaceholderSubstitutionAlgorithm.newInstance(replacementDefinitions);
final SubstitutionStrategyRegistry substitutionStrategyRegistry =
SubstitutionStrategyRegistry.newInstance();
return new PlaceholderSubstitution(algorithm, substitutionStrategyRegistry);
}
}