1
2
3
4
5
6 package gov.nist.secauto.metaschema.databind;
7
8 import gov.nist.secauto.metaschema.core.model.IBoundObject;
9 import gov.nist.secauto.metaschema.core.model.IModule;
10 import gov.nist.secauto.metaschema.core.model.IModuleLoader;
11 import gov.nist.secauto.metaschema.core.util.CollectionUtil;
12 import gov.nist.secauto.metaschema.databind.IBindingContext.IBindingMatcher;
13 import gov.nist.secauto.metaschema.databind.model.IBoundDefinitionModelComplex;
14 import gov.nist.secauto.metaschema.databind.model.IBoundModule;
15
16 import java.util.ArrayList;
17 import java.util.Collection;
18 import java.util.HashSet;
19 import java.util.List;
20 import java.util.Set;
21 import java.util.concurrent.locks.Lock;
22 import java.util.concurrent.locks.ReentrantLock;
23
24 import edu.umd.cs.findbugs.annotations.NonNull;
25
26 public class PostProcessingModuleLoaderStrategy
27 implements IBindingContext.IModuleLoaderStrategy {
28 @NonNull
29 private final List<IModuleLoader.IModulePostProcessor> modulePostProcessors;
30
31
32 private final IBindingContext.IModuleLoaderStrategy delegate;
33 private final Set<IModule> postProcessedModules = new HashSet<>();
34 private final Lock postProcessedModulesLock = new ReentrantLock();
35
36 public PostProcessingModuleLoaderStrategy(
37 @NonNull List<IModuleLoader.IModulePostProcessor> modulePostProcessors) {
38 this(modulePostProcessors, new SimpleModuleLoaderStrategy());
39 }
40
41 public PostProcessingModuleLoaderStrategy(
42 @NonNull List<IModuleLoader.IModulePostProcessor> modulePostProcessors,
43 @NonNull IBindingContext.IModuleLoaderStrategy delegate) {
44 this.modulePostProcessors = CollectionUtil.unmodifiableList(new ArrayList<>(modulePostProcessors));
45 this.delegate = delegate;
46 }
47
48 @NonNull
49 protected List<IModuleLoader.IModulePostProcessor> getModulePostProcessors() {
50 return modulePostProcessors;
51 }
52
53 @Override
54 public IBoundModule loadModule(Class<? extends IBoundModule> clazz, IBindingContext bindingContext) {
55 return delegate.loadModule(clazz, bindingContext);
56 }
57
58 @Override
59 public void postProcessModule(IModule module, IBindingContext bindingContext) {
60 processModule(module);
61 delegate.postProcessModule(module, bindingContext);
62 }
63
64 @Override
65 public IBoundModule registerModule(IModule module, IBindingContext bindingContext) {
66 IBoundModule boundModule;
67 postProcessedModulesLock.lock();
68 try {
69
70 processModule(module);
71
72 boundModule = delegate.registerModule(module, bindingContext);
73
74
75 postProcessedModules.add(boundModule);
76 } finally {
77 postProcessedModulesLock.unlock();
78 }
79 return boundModule;
80 }
81
82
83
84
85
86
87
88 protected void processModule(@NonNull IModule module) {
89 postProcessedModulesLock.lock();
90 try {
91 if (!postProcessedModules.contains(module)) {
92 for (IModuleLoader.IModulePostProcessor postProcessor : getModulePostProcessors()) {
93 postProcessor.processModule(module);
94 }
95 postProcessedModules.add(module);
96 }
97 } finally {
98 postProcessedModulesLock.unlock();
99 }
100 }
101
102 @Override
103 public Collection<IBindingMatcher> getBindingMatchers() {
104 return delegate.getBindingMatchers();
105 }
106
107 @Override
108 public IBoundDefinitionModelComplex getBoundDefinitionForClass(
109 Class<? extends IBoundObject> clazz,
110 IBindingContext bindingContext) {
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126 return delegate.getBoundDefinitionForClass(clazz, bindingContext);
127 }
128 }