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