1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.aether.internal.impl.named;
20
21 import javax.inject.Inject;
22 import javax.inject.Named;
23 import javax.inject.Singleton;
24
25 import java.util.ArrayList;
26 import java.util.Collections;
27 import java.util.HashSet;
28 import java.util.Map;
29 import java.util.Set;
30 import java.util.concurrent.ConcurrentHashMap;
31 import java.util.concurrent.ConcurrentMap;
32 import java.util.concurrent.TimeUnit;
33
34 import org.eclipse.aether.ConfigurationProperties;
35 import org.eclipse.aether.MultiRuntimeException;
36 import org.eclipse.aether.RepositorySystemSession;
37 import org.eclipse.aether.impl.NamedLockFactorySelector;
38 import org.eclipse.aether.impl.RepositorySystemLifecycle;
39 import org.eclipse.aether.internal.impl.synccontext.named.NamedLockFactoryAdapter;
40 import org.eclipse.aether.internal.impl.synccontext.named.NamedLockFactoryAdapterFactoryImpl;
41 import org.eclipse.aether.named.NamedLockFactory;
42 import org.eclipse.aether.named.providers.FileLockNamedLockFactory;
43 import org.eclipse.aether.util.ConfigUtils;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46
47 import static java.util.Objects.requireNonNull;
48
49 @Singleton
50 @Named
51 public class DefaultNamedLockFactorySelector implements NamedLockFactorySelector {
52 public static final String CONFIG_PROPS_PREFIX = ConfigurationProperties.PREFIX_SYSTEM + "named.";
53
54
55
56
57
58
59
60
61
62 public static final String CONFIG_PROP_FACTORY_NAME = CONFIG_PROPS_PREFIX + "factory";
63
64 public static final String DEFAULT_FACTORY_NAME = FileLockNamedLockFactory.NAME;
65
66
67
68
69
70
71
72
73 public static final String CONFIG_PROP_LOCK_WAIT_TIME = CONFIG_PROPS_PREFIX + "time";
74
75 public static final long DEFAULT_LOCK_WAIT_TIME = 900L;
76
77
78
79
80
81
82
83
84 public static final String CONFIG_PROP_LOCK_WAIT_TIME_UNIT = CONFIG_PROPS_PREFIX + "timeUnit";
85
86 public static final String DEFAULT_LOCK_WAIT_TIME_UNIT = "SECONDS";
87
88 protected final Logger logger = LoggerFactory.getLogger(getClass());
89
90 protected final Map<String, NamedLockFactory> factories;
91
92 protected final ConcurrentMap<String, NamedLockFactory> usedFactories;
93
94 @Inject
95 public DefaultNamedLockFactorySelector(
96 Map<String, NamedLockFactory> factories, RepositorySystemLifecycle lifecycle) {
97 this.factories = requireNonNull(factories);
98 this.usedFactories = new ConcurrentHashMap<>();
99 lifecycle.addOnSystemEndedHandler(this::shutdown);
100
101 logger.debug("Created lock factory selector; available lock factories {}", factories.keySet());
102 }
103
104 @Override
105 public Set<String> getAvailableLockFactories() {
106 return Collections.unmodifiableSet(new HashSet<>(factories.keySet()));
107 }
108
109 @Override
110 public NamedLockFactory getNamedLockFactory(Map<String, ?> configuration) {
111 String factoryName = ConfigUtils.getString(
112 configuration,
113 DEFAULT_FACTORY_NAME,
114 CONFIG_PROP_FACTORY_NAME,
115 NamedLockFactoryAdapterFactoryImpl.CONFIG_PROP_FACTORY_KEY);
116 NamedLockFactory factory = factories.get(factoryName);
117 if (factory == null) {
118 throw new IllegalArgumentException(
119 "Unknown NamedLockFactory name: '" + factoryName + "', known ones: " + factories.keySet());
120 }
121 usedFactories.putIfAbsent(factoryName, factory);
122 return factory;
123 }
124
125 @Override
126 public long getLockWaitTime(Map<String, ?> configuration) {
127 long result = ConfigUtils.getLong(
128 configuration,
129 DEFAULT_LOCK_WAIT_TIME,
130 CONFIG_PROP_LOCK_WAIT_TIME,
131 NamedLockFactoryAdapter.CONFIG_PROP_TIME);
132 if (result <= 0) {
133 throw new IllegalArgumentException(
134 "The " + CONFIG_PROP_LOCK_WAIT_TIME + " configuration must be greater than zero");
135 }
136 return result;
137 }
138
139 @Override
140 public TimeUnit getLockWaitTimeUnit(Map<String, ?> configuration) {
141 return TimeUnit.valueOf(ConfigUtils.getString(
142 configuration,
143 DEFAULT_LOCK_WAIT_TIME_UNIT,
144 CONFIG_PROP_LOCK_WAIT_TIME_UNIT,
145 NamedLockFactoryAdapter.CONFIG_PROP_TIME_UNIT));
146 }
147
148 private void shutdown() {
149 logger.debug("Shutting down used lock factories {}", usedFactories.keySet());
150 ArrayList<Exception> exceptions = new ArrayList<>();
151 for (Map.Entry<String, NamedLockFactory> entry : usedFactories.entrySet()) {
152 try {
153 logger.debug("Shutting down '{}' factory", entry.getKey());
154 entry.getValue().shutdown();
155 } catch (Exception e) {
156 exceptions.add(e);
157 }
158 }
159 MultiRuntimeException.mayThrow("Problem shutting down used lock factories", exceptions);
160 }
161 }