1 package com.atlassian.refapp.sal.usersettings;
2
3 import com.atlassian.fugue.Option;
4 import com.atlassian.plugin.spring.scanner.annotation.export.ExportAsService;
5 import com.atlassian.refapp.sal.FileBackedSettingsFileFactory;
6 import com.atlassian.refapp.sal.FileBackedSettingsService;
7 import com.atlassian.sal.api.ApplicationProperties;
8 import com.atlassian.sal.api.user.UserKey;
9 import com.atlassian.sal.api.user.UserManager;
10 import com.atlassian.sal.api.usersettings.UserSettings;
11 import com.atlassian.sal.api.usersettings.UserSettingsBuilder;
12 import com.atlassian.sal.api.usersettings.UserSettingsService;
13 import com.atlassian.sal.core.usersettings.DefaultUserSettings;
14 import com.google.common.annotations.VisibleForTesting;
15 import com.google.common.base.Function;
16 import com.google.common.collect.ImmutableSet;
17 import org.apache.log4j.Logger;
18
19 import java.util.Set;
20 import javax.inject.Inject;
21 import javax.inject.Named;
22
23 import static com.google.common.base.Preconditions.checkNotNull;
24
25 @ExportAsService
26 @Named("userSettingsService")
27 public class RefimplUserSettingsService extends FileBackedSettingsService implements UserSettingsService {
28 private static final Logger log = Logger.getLogger(RefimplUserSettingsService.class);
29
30 private final UserManager userManager;
31
32 @Inject
33 public RefimplUserSettingsService(UserManager userManager, ApplicationProperties applicationProperties) {
34 super(FileBackedSettingsFileFactory.getFileAndProperties("sal.com.atlassian.refapp.sal.usersettings.store", "com.atlassian.refapp.sal.usersettings.xml", Boolean.valueOf(System.getProperty("sal.com.atlassian.refapp.sal.usersettings.usememorystore", "false")), applicationProperties));
35 this.userManager = userManager;
36 }
37
38 @VisibleForTesting
39 RefimplUserSettingsService(UserManager userManager) {
40 this.userManager = userManager;
41 }
42
43 @Override
44 public UserSettings getUserSettings(String username) {
45 if (userManager.resolve(username) == null) {
46 throw new IllegalArgumentException("No user exists with username " + username);
47 }
48
49 SettingsMap settingsMap = new SettingsMap(username);
50 UserSettingsBuilder settings = UserSettingsBuilderRefAppImpl.builder();
51 for (String key : settingsMap.keySet()) {
52 final String value = settingsMap.get(key);
53 if (value.startsWith("B")) {
54 settings.put(key, Boolean.parseBoolean(value.substring(1)));
55 } else if (value.startsWith("L")) {
56 settings.put(key, Long.parseLong(value.substring(1)));
57 } else if (value.startsWith("S")) {
58 settings.put(key, value.substring(1));
59 } else {
60 log.warn("Found user setting with unknown prefix. User: " + username + ", key: " + key + ", value: " + value);
61 }
62 }
63
64 return settings.build();
65 }
66
67 @Override
68 public UserSettings getUserSettings(UserKey userKey) {
69 checkNotNull(userKey, "userKey cannot be null");
70
71 return getUserSettings(userKey.getStringValue());
72 }
73
74 @Override
75 public synchronized void updateUserSettings(String username, Function<UserSettingsBuilder, UserSettings> updateFunction) {
76 final UserSettings userSettings = updateFunction.apply(UserSettingsBuilderRefAppImpl.builder(getUserSettings(username)));
77
78
79 for (String key : userSettings.getKeys()) {
80 if (key.length() > UserSettingsService.MAX_KEY_LENGTH) {
81 throw new IllegalArgumentException("Key: \"" + key + "\" too long");
82 }
83 final Option<String> option = userSettings.getString(key);
84 for (String value : option) {
85 if (value.length() > UserSettingsService.MAX_STRING_VALUE_LENGTH) {
86 throw new IllegalArgumentException("Value: \"" + value + "\" too long");
87 }
88 }
89 }
90
91
92 SettingsMap settingsMap = new SettingsMap(username);
93 settingsMap.clear();
94
95 for (String key : userSettings.getKeys()) {
96
97
98 for (Boolean value : userSettings.getBoolean(key)) {
99 settingsMap.put(key, "B" + value);
100 }
101 for (Long value : userSettings.getLong(key)) {
102 settingsMap.put(key, "L" + value);
103 }
104 for (String value : userSettings.getString(key)) {
105 settingsMap.put(key, "S" + value);
106 }
107 }
108 }
109
110 @Override
111 public void updateUserSettings(UserKey userKey, Function<UserSettingsBuilder, UserSettings> updateFunction) {
112 checkNotNull(userKey, "userKey cannot be null");
113 updateUserSettings(userKey.getStringValue(), updateFunction);
114 }
115
116
117 private static class UserSettingsBuilderRefAppImpl implements UserSettingsBuilder {
118 static UserSettingsBuilderRefAppImpl builder() {
119 return new UserSettingsBuilderRefAppImpl(DefaultUserSettings.builder());
120 }
121
122 static UserSettingsBuilderRefAppImpl builder(UserSettings settings) {
123 return new UserSettingsBuilderRefAppImpl(DefaultUserSettings.builder(settings));
124 }
125
126 private final UserSettingsBuilder original;
127
128 private UserSettingsBuilderRefAppImpl(UserSettingsBuilder original) {
129 this.original = original;
130 }
131
132 @Override
133 public UserSettingsBuilder put(String key, String value) {
134 return original.put(key, value);
135 }
136
137 @Override
138 public UserSettingsBuilder put(String key, boolean value) {
139 return original.put(key, value);
140 }
141
142 @Override
143 public UserSettingsBuilder put(String key, long value) {
144 return original.put(key, value);
145 }
146
147 @Override
148 public UserSettingsBuilder remove(String key) {
149 return original.remove(key);
150 }
151
152 @Override
153 public Option<Object> get(String key) {
154 return original.get(key);
155 }
156
157 @Override
158 public Set<String> getKeys() {
159
160 return ImmutableSet.copyOf(original.getKeys());
161 }
162
163 @Override
164 public UserSettings build() {
165
166
167 return DefaultUserSettings.builder(original.build()).build();
168 }
169 }
170 }