package se.bjurr.prnfb.settings.legacy;
import static com.google.common.base.Optional.fromNullable;
import static com.google.common.base.Strings.isNullOrEmpty;
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.find;
import static com.google.common.collect.Iterables.removeIf;
import static com.google.common.collect.Iterables.tryFind;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Maps.newTreeMap;
import static java.lang.System.currentTimeMillis;
import static java.util.logging.Level.SEVERE;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.DEFAULT_NAME;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.NAME;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.VALUE;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.BUTTON_VISIBILITY.NONE;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.FIELDS.FORM_IDENTIFIER;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.FIELDS.accept_any_certificate;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.FIELDS.admin_allowed;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.FIELDS.button_title;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.FIELDS.button_visibility;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.FIELDS.events;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.FIELDS.filter_regexp;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.FIELDS.filter_string;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.FIELDS.header_name;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.FIELDS.header_value;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.FIELDS.injection_url;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.FIELDS.injection_url_regexp;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.FIELDS.key_store;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.FIELDS.key_store_password;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.FIELDS.key_store_type;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.FIELDS.method;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.FIELDS.name;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.FIELDS.password;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.FIELDS.post_content;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.FIELDS.proxy_password;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.FIELDS.proxy_port;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.FIELDS.proxy_server;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.FIELDS.proxy_user;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.FIELDS.trigger_if_isconflicting;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.FIELDS.trigger_ignore_state;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.FIELDS.url;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.FIELDS.user;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.FIELDS.user_allowed;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.FIELDS.valueOf;
import static se.bjurr.prnfb.settings.legacy.AdminFormValues.FORM_TYPE.TRIGGER_CONFIG_FORM;
import static se.bjurr.prnfb.settings.legacy.PrnfbNotification.isOfType;
import static se.bjurr.prnfb.settings.legacy.PrnfbNotificationBuilder.prnfbNotificationBuilder;
import static se.bjurr.prnfb.settings.legacy.PrnfbPredicates.predicate;
import static se.bjurr.prnfb.settings.legacy.PrnfbSettingsBuilder.prnfbSettingsBuilder;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.logging.Logger;
import se.bjurr.prnfb.listener.PrnfbPullRequestAction;
import se.bjurr.prnfb.settings.legacy.AdminFormValues.BUTTON_VISIBILITY;
import com.atlassian.bitbucket.pull.PullRequestState;
import com.atlassian.sal.api.pluginsettings.PluginSettings;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableMap;
import com.google.gson.Gson;
@Deprecated
public class SettingsStorage {
public static final String STORAGE_KEY = "se.bjurr.prnfb.admin.AdminFormValues_2";
public static final String STORAGE_KEY_PRNFS = "se.bjurr.prnfs.admin.AdminFormValues_2";
private static final Gson gson = new Gson();
private static Logger logger = Logger.getLogger(SettingsStorage.class.getName());
private static Random random = new Random(currentTimeMillis());
public static void checkFieldsRecognized(AdminFormValues adminFormValues)
throws ValidationException {
for (final Map<String, String> m : adminFormValues) {
for (final Entry<String, String> entry : m.entrySet()) {
if (entry.getKey().equals(NAME)) {
if (valueOf(entry.getValue()) == null) {
throw new ValidationException(entry.getValue(), "Field not recognized!");
}
} else if (!entry.getKey().equals(VALUE)) {
throw new ValidationException(entry.getKey(), "Key not recognized!");
}
}
}
}
public static void deleteSettings(PluginSettings pluginSettings, String id) {
final Map<String, AdminFormValues> map = getNotificationsMap(pluginSettings);
map.remove(id);
try {
storeNotificationsMap(pluginSettings, map);
} catch (final ValidationException e) {
logger.log(SEVERE, "", e);
}
}
@VisibleForTesting
public static void fakeRandom(Random random) {
SettingsStorage.random = random;
}
public static String formIdentifierGnerator() {
return random.nextLong() + "";
}
@VisibleForTesting
public static Logger getLogger() {
return logger;
}
public static PrnfbButton getPrnfbButton(AdminFormValues adminFormValues)
throws ValidationException {
final Optional<Map<String, String>> titleOpt =
tryFind(adminFormValues, predicate(button_title.name()));
String title = "Trigger Notification";
if (titleOpt.isPresent()) {
title = titleOpt.get().get(VALUE);
}
final Optional<Map<String, String>> visibilityOpt =
tryFind(adminFormValues, predicate(button_visibility.name()));
BUTTON_VISIBILITY visibility = NONE;
if (visibilityOpt.isPresent()) {
visibility = BUTTON_VISIBILITY.valueOf(visibilityOpt.get().get(VALUE));
}
return new PrnfbButton(
title, visibility, find(adminFormValues, predicate(FORM_IDENTIFIER.name())).get(VALUE));
}
public static PrnfbNotification getPrnfbNotification(AdminFormValues adminFormValues)
throws ValidationException {
final Optional<Map<String, String>> urlOpt = tryFind(adminFormValues, predicate(url.name()));
if (!urlOpt.isPresent()) {
throw new ValidationException("url", "URL not set");
}
final PrnfbNotificationBuilder prnfbNotificationBuilder =
prnfbNotificationBuilder().withUrl(urlOpt.get().get(VALUE));
for (final Map<String, String> event : filter(adminFormValues, predicate(events.name()))) {
prnfbNotificationBuilder.withTrigger(PrnfbPullRequestAction.valueOf(event.get(VALUE)));
}
Iterator<Map<String, String>> headerValues =
filter(adminFormValues, predicate(header_value.name())).iterator();
for (final Map<String, String> headerName :
filter(adminFormValues, predicate(header_name.name()))) {
if (headerName.get(VALUE).trim().isEmpty()) {
continue;
}
String headerValue = headerValues.next().get(VALUE);
if (isNullOrEmpty(headerValue)) {
throw new ValidationException(header_value.name(), "Value cannot be null");
}
prnfbNotificationBuilder.withHeader(headerName.get(VALUE), headerValue);
}
if (tryFind(adminFormValues, predicate(proxy_server.name())).isPresent()) {
prnfbNotificationBuilder.withProxyServer(
find(adminFormValues, predicate(proxy_server.name())).get(VALUE));
}
if (tryFind(adminFormValues, predicate(proxy_port.name())).isPresent()) {
prnfbNotificationBuilder.withProxyPort(
find(adminFormValues, predicate(proxy_port.name())).get(VALUE));
}
if (tryFind(adminFormValues, predicate(proxy_user.name())).isPresent()) {
prnfbNotificationBuilder.withProxyUser(
find(adminFormValues, predicate(proxy_user.name())).get(VALUE));
}
if (tryFind(adminFormValues, predicate(proxy_password.name())).isPresent()) {
prnfbNotificationBuilder.withProxyPassword(
find(adminFormValues, predicate(proxy_password.name())).get(VALUE));
}
if (tryFind(adminFormValues, predicate(user.name())).isPresent()) {
prnfbNotificationBuilder.withUser(find(adminFormValues, predicate(user.name())).get(VALUE));
}
if (tryFind(adminFormValues, predicate(password.name())).isPresent()) {
prnfbNotificationBuilder.withPassword(
find(adminFormValues, predicate(password.name())).get(VALUE));
}
if (tryFind(adminFormValues, predicate(filter_string.name())).isPresent()) {
prnfbNotificationBuilder.withFilterString(
find(adminFormValues, predicate(filter_string.name())).get(VALUE));
}
if (tryFind(adminFormValues, predicate(filter_regexp.name())).isPresent()) {
prnfbNotificationBuilder.withFilterRegexp(
find(adminFormValues, predicate(filter_regexp.name())).get(VALUE));
}
if (tryFind(adminFormValues, predicate(method.name())).isPresent()) {
prnfbNotificationBuilder.withMethod(
find(adminFormValues, predicate(method.name())).get(VALUE));
}
if (tryFind(adminFormValues, predicate(post_content.name())).isPresent()) {
prnfbNotificationBuilder.withPostContent(
find(adminFormValues, predicate(post_content.name())).get(VALUE));
}
if (tryFind(adminFormValues, predicate(name.name())).isPresent()) {
prnfbNotificationBuilder.withName(find(adminFormValues, predicate(name.name())).get(VALUE));
}
if (tryFind(adminFormValues, predicate(injection_url.name())).isPresent()) {
prnfbNotificationBuilder.withInjectionUrl(
find(adminFormValues, predicate(injection_url.name())).get(VALUE));
}
if (tryFind(adminFormValues, predicate(injection_url_regexp.name())).isPresent()) {
prnfbNotificationBuilder.withInjectionUrlRegexp(
find(adminFormValues, predicate(injection_url_regexp.name())).get(VALUE));
}
if (tryFind(adminFormValues, predicate(trigger_if_isconflicting.name())).isPresent()) {
prnfbNotificationBuilder.withTriggerIfCanMerge(
find(adminFormValues, predicate(trigger_if_isconflicting.name())).get(VALUE));
}
for (final Map<String, String> event :
filter(adminFormValues, predicate(trigger_ignore_state.name()))) {
prnfbNotificationBuilder.withTriggerIgnoreState(PullRequestState.valueOf(event.get(VALUE)));
}
return prnfbNotificationBuilder.build();
}
public static PrnfbSettings getPrnfbSettings(PluginSettings pluginSettings)
throws ValidationException {
final PrnfbSettingsBuilder prnfbSettingsBuilder = prnfbSettingsBuilder();
for (final AdminFormValues adminFormValues : getSettingsAsFormValues(pluginSettings)) {
if (isOfType(adminFormValues, TRIGGER_CONFIG_FORM)) {
prnfbSettingsBuilder.withNotification(getPrnfbNotification(adminFormValues));
} else {
prnfbSettingsBuilder.withButton(getPrnfbButton(adminFormValues));
}
prnfbSettingsBuilder.withUsersAllowed(
tryFind(adminFormValues, predicate(user_allowed.name())).isPresent());
prnfbSettingsBuilder.withAdminsAllowed(
tryFind(adminFormValues, predicate(admin_allowed.name())).isPresent());
prnfbSettingsBuilder //
.withShouldAcceptAnyCertificate(
tryFind(adminFormValues, predicate(accept_any_certificate.name())).isPresent());
if (tryFind(adminFormValues, predicate(key_store.name())).isPresent()) {
prnfbSettingsBuilder.setKeyStore(
tryFind(adminFormValues, predicate(key_store.name())).get().get(VALUE));
}
if (tryFind(adminFormValues, predicate(key_store_type.name())).isPresent()) {
prnfbSettingsBuilder.setKeyStoreType(
tryFind(adminFormValues, predicate(key_store_type.name())).get().get(VALUE));
}
if (tryFind(adminFormValues, predicate(key_store_password.name())).isPresent()) {
prnfbSettingsBuilder.setKeyStorePassword(
tryFind(adminFormValues, predicate(key_store_password.name())).get().get(VALUE));
}
}
return prnfbSettingsBuilder.build();
}
public static List<AdminFormValues> getSettingsAsFormValues(PluginSettings settings) {
final List<AdminFormValues> toReturn = newArrayList();
try {
/**
* The storage key was accidently changed when migrating to Bitbucket 4. This is an attempt to
* load 1.x settings if they exist.
*/
Optional<Object> settingsToUse = fromNullable(settings.get(STORAGE_KEY));
if (!settingsToUse.isPresent()) {
settingsToUse = fromNullable(settings.get(STORAGE_KEY_PRNFS));
if (!settingsToUse.isPresent()) {
return toReturn;
}
}
@SuppressWarnings("unchecked")
final List<String> settingsList = newArrayList((List<String>) settingsToUse.get());
for (final String storedJson : settingsList) {
toReturn.add(injectConfigurationName(gson.fromJson(storedJson, AdminFormValues.class)));
}
} catch (final Exception e) {
logger.log(SEVERE, "Unable to deserialize settings", e);
}
return toReturn;
}
public static void injectFormIdentifierIfNotSet(final AdminFormValues config) {
final Optional<Map<String, String>> formIdOpt =
tryFind(config, predicate(FORM_IDENTIFIER.name()));
if (!formIdOpt.isPresent() || formIdOpt.get().get(VALUE).trim().isEmpty()) {
final String generatedIdentifier = formIdentifierGnerator();
removeIf(config, predicate(FORM_IDENTIFIER.name()));
config.add(
new ImmutableMap.Builder<String, String>()
.put(NAME, FORM_IDENTIFIER.name())
.put(VALUE, generatedIdentifier)
.build());
}
}
@VisibleForTesting
public static void setLogger(Logger loggerParam) {
logger = loggerParam;
}
public static void storeSettings(PluginSettings pluginSettings, final AdminFormValues config)
throws ValidationException {
injectFormIdentifierIfNotSet(config);
final Map<String, AdminFormValues> allNotificationsMap = getNotificationsMap(pluginSettings);
allNotificationsMap.put(find(config, predicate(FORM_IDENTIFIER.name())).get(VALUE), config);
storeNotificationsMap(pluginSettings, allNotificationsMap);
}
private static Map<String, AdminFormValues> getNotificationsMap(PluginSettings pluginSettings) {
final Map<String, AdminFormValues> allNotificationsMap = newTreeMap();
for (final AdminFormValues a : getSettingsAsFormValues(pluginSettings)) {
if (tryFind(a, predicate(FORM_IDENTIFIER.name())).isPresent()) {
allNotificationsMap.put(find(a, predicate(FORM_IDENTIFIER.name())).get(VALUE), a);
}
}
return allNotificationsMap;
}
/** Inject a default name for the trigger. To make the plugin backwards compatible. */
private static AdminFormValues injectConfigurationName(AdminFormValues adminFormValues) {
final Optional<Map<String, String>> nameMapOpt =
tryFind(adminFormValues, predicate(name.name()));
if (nameMapOpt.isPresent()) {
return adminFormValues;
}
adminFormValues.add(
ImmutableMap.<String, String>builder() //
.put(NAME, name.name()) //
.put(VALUE, DEFAULT_NAME) //
.build());
return adminFormValues;
}
private static void storeNotificationsMap(
PluginSettings pluginSettings, Map<String, AdminFormValues> allNotificationsMap)
throws ValidationException {
final List<String> toStore = newArrayList();
for (final AdminFormValues adminFormValues : allNotificationsMap.values()) {
final Optional<Map<String, String>> formIdOpt =
tryFind(adminFormValues, predicate(FORM_IDENTIFIER.name()));
if (!formIdOpt.isPresent() || formIdOpt.get().get(VALUE).trim().isEmpty()) {
throw new ValidationException(FORM_IDENTIFIER.name(), "Not set!");
}
toStore.add(new Gson().toJson(adminFormValues));
}
pluginSettings.put(STORAGE_KEY, toStore);
}
}