-
Notifications
You must be signed in to change notification settings - Fork 215
/
AbstractTypedSubstitutionStrategy.java
137 lines (111 loc) · 5.48 KB
/
AbstractTypedSubstitutionStrategy.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
131
132
133
134
135
136
137
/*
* 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.strategies;
import static java.util.Objects.requireNonNull;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.ditto.base.model.headers.DittoHeaders;
import org.eclipse.ditto.base.model.headers.DittoHeadersSettable;
import org.eclipse.ditto.policies.enforcement.placeholders.HeaderBasedPlaceholderSubstitutionAlgorithm;
import org.eclipse.ditto.policies.model.PoliciesModelFactory;
import org.eclipse.ditto.policies.model.Policy;
import org.eclipse.ditto.policies.model.PolicyEntry;
import org.eclipse.ditto.policies.model.Subject;
import org.eclipse.ditto.policies.model.Subjects;
/**
* Abstract base class for instances of {@link SubstitutionStrategy} which matches on a concrete subtype of
* {@link DittoHeadersSettable}.
*
* @param <T> the subtype of {@link DittoHeadersSettable} handled by this strategy.
*/
public abstract class AbstractTypedSubstitutionStrategy<T extends DittoHeadersSettable<?>> implements SubstitutionStrategy<T> {
private final Class<T> type;
protected AbstractTypedSubstitutionStrategy(final Class<T> type) {
this.type = requireNonNull(type);
}
@Override
public boolean matches(final DittoHeadersSettable<?> dittoHeadersSettable) {
return type.isAssignableFrom(dittoHeadersSettable.getClass());
}
protected static Subjects substituteSubjects(final Subjects subjects,
final HeaderBasedPlaceholderSubstitutionAlgorithm substitutionAlgorithm, final DittoHeaders dittoHeaders) {
Subjects newSubjects = subjects;
for (final Subject subject : subjects) {
final String subjectId = subject.getId().toString();
final String substitutedSubjectId = substitutionAlgorithm.substitute(subjectId, dittoHeaders);
if (!subjectId.equals(substitutedSubjectId)) {
final Subject newSubject =
Subject.newInstance(substitutedSubjectId, subject.getType());
newSubjects = newSubjects.removeSubject(subjectId).setSubject(newSubject);
}
}
return newSubjects;
}
protected static PolicyEntry substitutePolicyEntry(final PolicyEntry existingPolicyEntry,
final HeaderBasedPlaceholderSubstitutionAlgorithm substitutionAlgorithm, final DittoHeaders dittoHeaders) {
final Subjects existingSubjects = existingPolicyEntry.getSubjects();
final Subjects substitutedSubjects = substituteSubjects(existingSubjects, substitutionAlgorithm, dittoHeaders);
final PolicyEntry resultEntry;
if (existingSubjects.equals(substitutedSubjects)) {
resultEntry = existingPolicyEntry;
} else {
resultEntry = PolicyEntry.newInstance(existingPolicyEntry.getLabel(), substitutedSubjects,
existingPolicyEntry.getResources());
}
return resultEntry;
}
protected static Policy substitutePolicy(final Policy policy,
final HeaderBasedPlaceholderSubstitutionAlgorithm substitutionAlgorithm,
final DittoHeaders dittoHeaders) {
final Iterable<PolicyEntry> existingEntries = policy.getEntriesSet();
final Iterable<PolicyEntry> substitutedEntries =
substitutePolicyEntries(existingEntries, substitutionAlgorithm, dittoHeaders);
final Policy resultPolicy;
if (existingEntries.equals(substitutedEntries)) {
resultPolicy = policy;
} else {
resultPolicy = PoliciesModelFactory.newPolicyBuilder(policy).setAll(substitutedEntries).build();
}
return resultPolicy;
}
protected static Iterable<PolicyEntry> substitutePolicyEntries(final Iterable<PolicyEntry> policyEntries,
final HeaderBasedPlaceholderSubstitutionAlgorithm substitutionAlgorithm,
final DittoHeaders dittoHeaders) {
final Iterator<PolicyEntry> existingEntriesIterator = policyEntries.iterator();
Iterable<PolicyEntry> currentEntries = policyEntries;
for (int i = 0; existingEntriesIterator.hasNext(); i++) {
final PolicyEntry existingEntry = existingEntriesIterator.next();
final PolicyEntry substitutedEntry =
substitutePolicyEntry(existingEntry, substitutionAlgorithm, dittoHeaders);
if (!existingEntry.equals(substitutedEntry)) {
currentEntries = replace(currentEntries, substitutedEntry, i);
}
}
return currentEntries;
}
private static Iterable<PolicyEntry> replace(final Iterable<PolicyEntry> entries,
final PolicyEntry substitutedEntry, final int index) {
final List<PolicyEntry> newEntries = new ArrayList<>();
final Iterator<PolicyEntry> entriesIterator = entries.iterator();
for (int i = 0; entriesIterator.hasNext(); i++) {
final PolicyEntry existingEntry = entriesIterator.next();
if (i == index) {
newEntries.add(substitutedEntry);
} else {
newEntries.add(existingEntry);
}
}
return newEntries;
}
}