1 package com.trendmicro.grid.acl.ds;
2
3 import org.slf4j.Logger;
4 import org.slf4j.LoggerFactory;
5
6 import javax.xml.bind.annotation.*;
7 import java.util.Arrays;
8 import java.util.Collections;
9 import java.util.List;
10 import java.util.Map;
11
12
13
14
15
16
17
18 @XmlType
19 @XmlAccessorType(XmlAccessType.FIELD)
20 public class RepositorySelector<R extends Repository> implements RepositorySelectorMBean {
21
22 private static final Logger log = LoggerFactory.getLogger(RepositorySelector.class);
23
24 private transient Map<String, R> repositories;
25 private transient R selected;
26 private transient long lastModified;
27 transient boolean initialized, autoSelectedKey;
28
29 @XmlAttribute(required = true)
30 private String repositoryClass;
31
32 @XmlElement(required = false)
33 private String selectedKey;
34 @XmlElement(name = "available", required = false)
35 private String[] availableKeys;
36
37 public RepositorySelector() {
38 }
39
40 public RepositorySelector(Map<String, R> repositories, Class<R> repositoryClass) {
41 init(repositories, repositoryClass);
42 }
43
44 public void initFrom(RepositorySelector<R> other) {
45 try {
46 lastModified = other.lastModified;
47 if (!other.autoSelectedKey || !other.repositories.containsKey(selectedKey))
48 selectedKey = other.getSelectedKey();
49 init(other.repositories, other.getRepositoryClass());
50 } finally {
51 String selection = getSelectedKey();
52 try {
53 setSelectedKey(selection);
54 } catch (IllegalArgumentException e) {
55 log.warn("TMACL-00340:Failed to select the implementation '{}' for " +
56 "repository type {}, using default of {} instead.",
57 new Object[]{selection, repositoryClass, getSelectedKey()});
58 }
59 }
60 }
61
62 public void init(Map<String, R> repositories, Class<R> repositoryClass) {
63 init(repositories, repositoryClass.getName());
64 }
65
66 private void init(Map<String, R> repositories, String repositoryClass) {
67 if (repositories == null || repositories.isEmpty()) {
68 log.warn("TMACL-00090:The repository type {} doesn't have any registered implementations.",
69 repositoryClass);
70 }
71
72 this.repositories = repositories;
73 this.repositoryClass = repositoryClass;
74 if (repositories != null)
75 availableKeys = repositories.keySet().toArray(new String[repositories.size()]);
76
77 try {
78 setSelectedKey(getSelectedKey());
79 } catch (IllegalArgumentException e) {
80
81 }
82
83 initialized = true;
84 }
85
86 private void assertIsInitialized() {
87 if (!initialized) {
88 log.error("TMACL-00110:The selector for {} repositories was invoked " +
89 "before it got initialized. The result will be 'null'.", repositoryClass);
90 throw new IllegalStateException("Selector for repository " +
91 repositoryClass + " is used before it was initialized.");
92 }
93 }
94
95 public long getLastModified() {
96 return lastModified;
97 }
98
99 public void setLastModified(long time) {
100 lastModified = time;
101 }
102
103
104
105
106 public String getRepositoryClass() {
107 return repositoryClass;
108 }
109
110 public R getRepository(String key) {
111 assertIsInitialized();
112 return repositories == null ? null : repositories.get(key);
113 }
114
115
116
117
118
119
120 public R getRepository() {
121 assertIsInitialized();
122 return selected;
123 }
124
125 public boolean hasSelection() {
126 return selectedKey != null;
127 }
128
129 public boolean isAutoSelectedKey() {
130 return autoSelectedKey;
131 }
132
133
134
135
136 public String getSelectedKey() {
137 if (!hasSelection() && repositories != null && !repositories.isEmpty()) {
138 String key = repositories.keySet().iterator().next();
139 log.info("TMACL-00120:No selection present for repository type {}, auto-selecting '{}'",
140 repositoryClass, key);
141 setSelectedKey(key);
142 autoSelectedKey = true;
143 }
144 return selectedKey;
145 }
146
147
148
149
150 public void setSelectedKey(String selectedKey) {
151 setSelectedKey(selectedKey, false);
152 }
153
154 void setSelectedKey(String selectedKey, boolean autoSelectedKey) {
155 if (repositories != null && selectedKey != null && !repositories.containsKey(selectedKey)) {
156 throw new IllegalArgumentException("Cannot set the selection to '" + selectedKey +
157 "' an implementation of that name does not exist.");
158 }
159
160 if (!String.valueOf(this.selectedKey).equals(selectedKey)) {
161 lastModified = System.currentTimeMillis();
162 this.autoSelectedKey = autoSelectedKey;
163 }
164
165 this.selectedKey = selectedKey;
166 selected = repositories == null ? null : repositories.get(selectedKey);
167 }
168
169
170
171
172 public List<String> getAvailableKeys() {
173 if (availableKeys == null)
174 return Collections.emptyList();
175 return Arrays.asList(availableKeys);
176 }
177 }